1/* 2 * This file Copyright (C) Mnemosyne LLC 3 * 4 * This file is licensed by the GPL version 2. Works owned by the 5 * Transmission project are granted a special exemption to clause 2(b) 6 * so that the bulk of its code can remain under the MIT license. 7 * This exemption does not extend to derived works not owned by 8 * the Transmission project. 9 * 10 * $Id: peer-io.h 12365 2011-04-17 05:22:50Z jordan $ 11 */ 12 13#ifndef __TRANSMISSION__ 14#error only libtransmission should #include this header. 15#endif 16 17#ifndef TR_PEER_IO_H 18#define TR_PEER_IO_H 19 20/** 21*** 22**/ 23 24#include <assert.h> 25 26#include "transmission.h" 27#include "bandwidth.h" 28#include "crypto.h" 29#include "net.h" /* tr_address */ 30#include "utils.h" /* tr_time() */ 31 32struct evbuffer; 33struct tr_bandwidth; 34struct tr_datatype; 35struct tr_peerIo; 36 37/** 38 * @addtogroup networked_io Networked IO 39 * @{ 40 */ 41 42typedef enum 43{ 44 READ_NOW, 45 READ_LATER, 46 READ_ERR 47} 48ReadState; 49 50typedef enum 51{ 52 /* these match the values in MSE's crypto_select */ 53 PEER_ENCRYPTION_NONE = ( 1 << 0 ), 54 PEER_ENCRYPTION_RC4 = ( 1 << 1 ) 55} 56tr_encryption_type; 57 58 59typedef ReadState ( *tr_can_read_cb )( struct tr_peerIo * io, 60 void * user_data, 61 size_t * setme_piece_byte_count ); 62 63typedef void ( *tr_did_write_cb )( struct tr_peerIo * io, 64 size_t bytesWritten, 65 int wasPieceData, 66 void * userData ); 67 68typedef void ( *tr_net_error_cb )( struct tr_peerIo * io, 69 short what, 70 void * userData ); 71 72typedef struct tr_peerIo 73{ 74 bool isEncrypted; 75 bool isIncoming; 76 bool peerIdIsSet; 77 bool extendedProtocolSupported; 78 bool fastExtensionSupported; 79 bool dhtSupported; 80 bool utpSupported; 81 82 tr_priority_t priority; 83 84 short int pendingEvents; 85 86 int magicNumber; 87 88 tr_encryption_type encryption_type; 89 bool isSeed; 90 91 tr_port port; 92 int socket; 93 struct UTPSocket *utp_socket; 94 95 int refCount; 96 97 uint8_t peerId[SHA_DIGEST_LENGTH]; 98 time_t timeCreated; 99 100 tr_session * session; 101 102 tr_address addr; 103 104 tr_can_read_cb canRead; 105 tr_did_write_cb didWrite; 106 tr_net_error_cb gotError; 107 void * userData; 108 109 struct tr_bandwidth bandwidth; 110 tr_crypto crypto; 111 112 struct evbuffer * inbuf; 113 struct evbuffer * outbuf; 114 struct tr_datatype * outbuf_datatypes; 115 116 struct event * event_read; 117 struct event * event_write; 118} 119tr_peerIo; 120 121/** 122*** 123**/ 124 125tr_peerIo* tr_peerIoNewOutgoing( tr_session * session, 126 struct tr_bandwidth * parent, 127 const struct tr_address * addr, 128 tr_port port, 129 const uint8_t * torrentHash, 130 bool isSeed, 131 bool utp ); 132 133 134tr_peerIo* tr_peerIoNewIncoming( tr_session * session, 135 struct tr_bandwidth * parent, 136 const struct tr_address * addr, 137 tr_port port, 138 int socket, 139 struct UTPSocket * utp_socket ); 140 141void tr_peerIoRefImpl ( const char * file, 142 int line, 143 tr_peerIo * io ); 144 145#define tr_peerIoRef(io) tr_peerIoRefImpl( __FILE__, __LINE__, (io) ); 146 147void tr_peerIoUnrefImpl ( const char * file, 148 int line, 149 tr_peerIo * io ); 150 151#define tr_peerIoUnref(io) tr_peerIoUnrefImpl( __FILE__, __LINE__, (io) ); 152 153#define PEER_IO_MAGIC_NUMBER 206745 154 155static inline bool 156tr_isPeerIo( const tr_peerIo * io ) 157{ 158 return ( io != NULL ) 159 && ( io->magicNumber == PEER_IO_MAGIC_NUMBER ) 160 && ( io->refCount >= 0 ) 161 && ( tr_isBandwidth( &io->bandwidth ) ) 162 && ( tr_address_is_valid( &io->addr ) ); 163} 164 165/** 166*** 167**/ 168 169static inline void tr_peerIoEnableFEXT( tr_peerIo * io, bool flag ) 170{ 171 io->fastExtensionSupported = flag; 172} 173static inline bool tr_peerIoSupportsFEXT( const tr_peerIo * io ) 174{ 175 return io->fastExtensionSupported; 176} 177 178static inline void tr_peerIoEnableLTEP( tr_peerIo * io, bool flag ) 179{ 180 io->extendedProtocolSupported = flag; 181} 182static inline bool tr_peerIoSupportsLTEP( const tr_peerIo * io ) 183{ 184 return io->extendedProtocolSupported; 185} 186 187static inline void tr_peerIoEnableDHT( tr_peerIo * io, bool flag ) 188{ 189 io->dhtSupported = flag; 190} 191static inline bool tr_peerIoSupportsDHT( const tr_peerIo * io ) 192{ 193 return io->dhtSupported; 194} 195 196static inline bool tr_peerIoSupportsUTP( const tr_peerIo * io ) 197{ 198 return io->dhtSupported; 199} 200 201/** 202*** 203**/ 204 205static inline tr_session* tr_peerIoGetSession ( tr_peerIo * io ) 206{ 207 assert( tr_isPeerIo( io ) ); 208 assert( io->session ); 209 210 return io->session; 211} 212 213const char* tr_peerIoAddrStr( const struct tr_address * addr, 214 tr_port port ); 215 216const char* tr_peerIoGetAddrStr( const tr_peerIo * io ); 217 218const struct tr_address * tr_peerIoGetAddress( const tr_peerIo * io, 219 tr_port * port ); 220 221const uint8_t* tr_peerIoGetTorrentHash( tr_peerIo * io ); 222 223int tr_peerIoHasTorrentHash( const tr_peerIo * io ); 224 225void tr_peerIoSetTorrentHash( tr_peerIo * io, 226 const uint8_t * hash ); 227 228int tr_peerIoReconnect( tr_peerIo * io ); 229 230static inline bool tr_peerIoIsIncoming( const tr_peerIo * io ) 231{ 232 return io->isIncoming; 233} 234 235static inline int tr_peerIoGetAge( const tr_peerIo * io ) 236{ 237 return tr_time() - io->timeCreated; 238} 239 240 241/** 242*** 243**/ 244 245void tr_peerIoSetPeersId( tr_peerIo * io, 246 const uint8_t * peer_id ); 247 248static inline const uint8_t* tr_peerIoGetPeersId( const tr_peerIo * io ) 249{ 250 assert( tr_isPeerIo( io ) ); 251 assert( io->peerIdIsSet ); 252 253 return io->peerId; 254} 255 256/** 257*** 258**/ 259 260void tr_peerIoSetIOFuncs ( tr_peerIo * io, 261 tr_can_read_cb readcb, 262 tr_did_write_cb writecb, 263 tr_net_error_cb errcb, 264 void * user_data ); 265 266void tr_peerIoClear ( tr_peerIo * io ); 267 268/** 269*** 270**/ 271 272void tr_peerIoWriteBytes ( tr_peerIo * io, 273 const void * writeme, 274 size_t writemeLen, 275 bool isPieceData ); 276 277void tr_peerIoWriteBuf ( tr_peerIo * io, 278 struct evbuffer * buf, 279 bool isPieceData ); 280 281/** 282*** 283**/ 284 285static inline tr_crypto * tr_peerIoGetCrypto( tr_peerIo * io ) 286{ 287 return &io->crypto; 288} 289 290void tr_peerIoSetEncryption( tr_peerIo * io, tr_encryption_type encryption_type ); 291 292static inline bool 293tr_peerIoIsEncrypted( const tr_peerIo * io ) 294{ 295 return ( io != NULL ) && ( io->encryption_type == PEER_ENCRYPTION_RC4 ); 296} 297 298void evbuffer_add_uint8 ( struct evbuffer * outbuf, uint8_t byte ); 299void evbuffer_add_uint16( struct evbuffer * outbuf, uint16_t hs ); 300void evbuffer_add_uint32( struct evbuffer * outbuf, uint32_t hl ); 301void evbuffer_add_uint64( struct evbuffer * outbuf, uint64_t hll ); 302 303static inline void 304evbuffer_add_hton_16( struct evbuffer * buf, uint16_t val ) 305{ 306 evbuffer_add_uint16( buf, val ); 307} 308static inline void 309evbuffer_add_hton_32( struct evbuffer * buf, uint32_t val ) 310{ 311 evbuffer_add_uint32( buf, val ); 312} 313static inline void 314evbuffer_add_hton_64( struct evbuffer * buf, uint64_t val ) 315{ 316 evbuffer_add_uint64( buf, val ); 317} 318 319void tr_peerIoReadBytesToBuf( tr_peerIo * io, 320 struct evbuffer * inbuf, 321 struct evbuffer * outbuf, 322 size_t byteCount ); 323 324void tr_peerIoReadBytes( tr_peerIo * io, 325 struct evbuffer * inbuf, 326 void * bytes, 327 size_t byteCount ); 328 329static inline void tr_peerIoReadUint8( tr_peerIo * io, 330 struct evbuffer * inbuf, 331 uint8_t * setme ) 332{ 333 tr_peerIoReadBytes( io, inbuf, setme, sizeof( uint8_t ) ); 334} 335 336void tr_peerIoReadUint16( tr_peerIo * io, 337 struct evbuffer * inbuf, 338 uint16_t * setme ); 339 340void tr_peerIoReadUint32( tr_peerIo * io, 341 struct evbuffer * inbuf, 342 uint32_t * setme ); 343 344void tr_peerIoDrain( tr_peerIo * io, 345 struct evbuffer * inbuf, 346 size_t byteCount ); 347 348/** 349*** 350**/ 351 352size_t tr_peerIoGetWriteBufferSpace( const tr_peerIo * io, uint64_t now ); 353 354static inline void tr_peerIoSetParent( tr_peerIo * io, 355 struct tr_bandwidth * parent ) 356{ 357 assert( tr_isPeerIo( io ) ); 358 359 tr_bandwidthSetParent( &io->bandwidth, parent ); 360} 361 362void tr_peerIoBandwidthUsed( tr_peerIo * io, 363 tr_direction direction, 364 size_t byteCount, 365 int isPieceData ); 366 367static inline bool 368tr_peerIoHasBandwidthLeft( const tr_peerIo * io, tr_direction dir ) 369{ 370 return tr_bandwidthClamp( &io->bandwidth, dir, 1024 ) > 0; 371} 372 373static inline unsigned int 374tr_peerIoGetPieceSpeed_Bps( const tr_peerIo * io, uint64_t now, tr_direction dir ) 375{ 376 return tr_bandwidthGetPieceSpeed_Bps( &io->bandwidth, now, dir ); 377} 378 379/** 380*** 381**/ 382 383void tr_peerIoSetEnabled( tr_peerIo * io, 384 tr_direction dir, 385 bool isEnabled ); 386 387int tr_peerIoFlush( tr_peerIo * io, 388 tr_direction dir, 389 size_t byteLimit ); 390 391int tr_peerIoFlushOutgoingProtocolMsgs( tr_peerIo * io ); 392 393/** 394*** 395**/ 396 397static inline struct evbuffer * tr_peerIoGetReadBuffer( tr_peerIo * io ) 398{ 399 return io->inbuf; 400} 401 402/* @} */ 403 404#endif 405