source: trunk/libtransmission/peer-io.h @ 11296

Last change on this file since 11296 was 11296, checked in by charles, 12 years ago

(trunk libT) remove unnecessary calls to time(NULL)

  • Property svn:keywords set to Date Rev Author Id
File size: 11.7 KB
Line 
1/*
2 * This file Copyright (C) 2007-2010 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 11296 2010-10-08 13:36:33Z charles $
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 <event.h>
27
28#include "transmission.h"
29#include "bandwidth.h"
30#include "list.h" /* tr_list */
31#include "net.h" /* tr_address */
32#include "utils.h" /* tr_time() */
33
34struct evbuffer;
35struct tr_bandwidth;
36struct tr_crypto;
37struct tr_peerIo;
38
39/**
40 * @addtogroup networked_io Networked IO
41 * @{
42 */
43
44typedef enum
45{
46    READ_NOW,
47    READ_LATER,
48    READ_ERR
49}
50ReadState;
51
52typedef ReadState ( *tr_can_read_cb  )( struct tr_peerIo * io,
53                                        void             * user_data,
54                                        size_t           * setme_piece_byte_count );
55
56typedef void      ( *tr_did_write_cb )( struct tr_peerIo * io,
57                                        size_t             bytesWritten,
58                                        int                wasPieceData,
59                                        void             * userData );
60
61typedef void      ( *tr_net_error_cb )( struct tr_peerIo * io,
62                                        short              what,
63                                        void             * userData );
64
65typedef struct tr_peerIo
66{
67    tr_bool               isEncrypted;
68    tr_bool               isIncoming;
69    tr_bool               peerIdIsSet;
70    tr_bool               extendedProtocolSupported;
71    tr_bool               fastExtensionSupported;
72    tr_bool               dhtSupported;
73
74    /* we create the socket in a nonblocking way, so this flag is initially
75     * false and then set to true when libevent says that the socket is ready
76     * for reading or writing */
77    tr_bool               hasFinishedConnecting;
78
79    tr_priority_t         priority;
80
81    short int             pendingEvents;
82
83    int                   magicNumber;
84
85    uint32_t              encryptionMode;
86    tr_bool               isSeed;
87
88    tr_port               port;
89    int                   socket;
90
91    int                   refCount;
92
93    uint8_t               peerId[SHA_DIGEST_LENGTH];
94    time_t                timeCreated;
95
96    tr_session          * session;
97
98    tr_address            addr;
99
100    tr_can_read_cb        canRead;
101    tr_did_write_cb       didWrite;
102    tr_net_error_cb       gotError;
103    void *                userData;
104
105    struct tr_bandwidth   bandwidth;
106    struct tr_crypto    * crypto;
107
108    struct evbuffer     * inbuf;
109    struct evbuffer     * outbuf;
110    struct tr_list      * outbuf_datatypes; /* struct tr_datatype */
111
112    struct event          event_read;
113    struct event          event_write;
114}
115tr_peerIo;
116
117/**
118***
119**/
120
121tr_peerIo*  tr_peerIoNewOutgoing( tr_session              * session,
122                                  struct tr_bandwidth     * parent,
123                                  const struct tr_address * addr,
124                                  tr_port                   port,
125                                  const  uint8_t          * torrentHash,
126                                  tr_bool                   isSeed );
127
128tr_peerIo*  tr_peerIoNewIncoming( tr_session              * session,
129                                  struct tr_bandwidth     * parent,
130                                  const struct tr_address * addr,
131                                  tr_port                   port,
132                                  int                       socket );
133
134void tr_peerIoRefImpl           ( const char              * file,
135                                  int                       line,
136                                  tr_peerIo               * io );
137
138#define tr_peerIoRef(io) tr_peerIoRefImpl( __FILE__, __LINE__, (io) );
139
140void tr_peerIoUnrefImpl         ( const char              * file,
141                                  int                       line,
142                                  tr_peerIo               * io );
143
144#define tr_peerIoUnref(io) tr_peerIoUnrefImpl( __FILE__, __LINE__, (io) );
145
146tr_bool     tr_isPeerIo         ( const tr_peerIo         * io );
147
148
149/**
150***
151**/
152
153static inline void tr_peerIoEnableFEXT( tr_peerIo * io, tr_bool flag )
154{
155    io->fastExtensionSupported = flag;
156}
157static inline tr_bool tr_peerIoSupportsFEXT( const tr_peerIo * io )
158{
159    return io->fastExtensionSupported;
160}
161
162static inline void tr_peerIoEnableLTEP( tr_peerIo * io, tr_bool flag )
163{
164    io->extendedProtocolSupported = flag;
165}
166static inline tr_bool tr_peerIoSupportsLTEP( const tr_peerIo * io )
167{
168    return io->extendedProtocolSupported;
169}
170
171static inline void tr_peerIoEnableDHT( tr_peerIo * io, tr_bool flag )
172{
173    io->dhtSupported = flag;
174}
175static inline tr_bool tr_peerIoSupportsDHT( const tr_peerIo * io )
176{
177    return io->dhtSupported;
178}
179
180/**
181***
182**/
183
184static inline tr_session* tr_peerIoGetSession ( tr_peerIo * io )
185{
186    assert( tr_isPeerIo( io ) );
187    assert( io->session );
188
189    return io->session;
190}
191
192const char* tr_peerIoAddrStr( const struct tr_address * addr,
193                              tr_port                   port );
194
195static inline const char* tr_peerIoGetAddrStr( const tr_peerIo * io )
196{
197    return tr_isPeerIo( io ) ? tr_peerIoAddrStr( &io->addr, io->port ) : "error";
198}
199
200const struct tr_address * tr_peerIoGetAddress( const tr_peerIo * io,
201                                               tr_port         * port );
202
203const uint8_t*       tr_peerIoGetTorrentHash( tr_peerIo * io );
204
205int                  tr_peerIoHasTorrentHash( const tr_peerIo * io );
206
207void                 tr_peerIoSetTorrentHash( tr_peerIo *     io,
208                                              const uint8_t * hash );
209
210int                  tr_peerIoReconnect( tr_peerIo * io );
211
212static inline tr_bool tr_peerIoIsIncoming( const tr_peerIo * io )
213{
214    return io->isIncoming;
215}
216
217static inline int    tr_peerIoGetAge( const tr_peerIo * io )
218{
219    return tr_time() - io->timeCreated;
220}
221
222
223/**
224***
225**/
226
227void                 tr_peerIoSetPeersId( tr_peerIo *     io,
228                                          const uint8_t * peer_id );
229
230static inline const uint8_t* tr_peerIoGetPeersId( const tr_peerIo * io )
231{
232    assert( tr_isPeerIo( io ) );
233    assert( io->peerIdIsSet );
234
235    return io->peerId;
236}
237
238/**
239***
240**/
241
242void    tr_peerIoSetIOFuncs      ( tr_peerIo        * io,
243                                   tr_can_read_cb     readcb,
244                                   tr_did_write_cb    writecb,
245                                   tr_net_error_cb    errcb,
246                                   void             * user_data );
247
248void    tr_peerIoClear           ( tr_peerIo        * io );
249
250/**
251***
252**/
253
254void    tr_peerIoWrite          ( tr_peerIo         * io,
255                                  const void        * writeme,
256                                  size_t              writemeLen,
257                                  tr_bool             isPieceData );
258
259void    tr_peerIoWriteBuf       ( tr_peerIo         * io,
260                                  struct evbuffer   * buf,
261                                  tr_bool             isPieceData );
262
263/**
264***
265**/
266
267static inline struct tr_crypto * tr_peerIoGetCrypto( tr_peerIo * io )
268{
269    return io->crypto;
270}
271
272typedef enum
273{
274    /* these match the values in MSE's crypto_select */
275    PEER_ENCRYPTION_NONE  = ( 1 << 0 ),
276    PEER_ENCRYPTION_RC4   = ( 1 << 1 )
277}
278EncryptionMode;
279
280void tr_peerIoSetEncryption( tr_peerIo * io, uint32_t encryptionMode );
281
282static inline tr_bool
283tr_peerIoIsEncrypted( const tr_peerIo * io )
284{
285    return ( io != NULL ) && ( io->encryptionMode == PEER_ENCRYPTION_RC4 );
286}
287
288static inline void tr_peerIoWriteBytes( tr_peerIo        * io UNUSED,
289                                           struct evbuffer  * outbuf,
290                                           const void       * bytes,
291                                           size_t             byteCount )
292{
293    evbuffer_add( outbuf, bytes, byteCount );
294}
295
296static inline void  tr_peerIoWriteUint8( tr_peerIo        * io,
297                                            struct evbuffer  * outbuf,
298                                            uint8_t            writeme )
299{
300    tr_peerIoWriteBytes( io, outbuf, &writeme, sizeof( uint8_t ) );
301}
302
303static inline void tr_peerIoWriteUint16( tr_peerIo        * io,
304                                            struct evbuffer  * outbuf,
305                                            uint16_t           writeme )
306{
307    const uint16_t tmp = htons( writeme );
308    tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof( uint16_t ) );
309}
310
311static inline void tr_peerIoWriteUint32( tr_peerIo        * io,
312                                            struct evbuffer  * outbuf,
313                                            uint32_t           writeme )
314{
315    const uint32_t tmp = htonl( writeme );
316    tr_peerIoWriteBytes( io, outbuf, &tmp, sizeof( uint32_t ) );
317}
318
319void tr_peerIoReadBytes( tr_peerIo        * io,
320                         struct evbuffer  * inbuf,
321                         void             * bytes,
322                         size_t             byteCount );
323
324static inline void tr_peerIoReadUint8( tr_peerIo        * io,
325                                          struct evbuffer  * inbuf,
326                                          uint8_t          * setme )
327{
328    tr_peerIoReadBytes( io, inbuf, setme, sizeof( uint8_t ) );
329}
330
331static inline void tr_peerIoReadUint16( tr_peerIo        * io,
332                                           struct evbuffer  * inbuf,
333                                           uint16_t         * setme )
334{
335    uint16_t tmp;
336    tr_peerIoReadBytes( io, inbuf, &tmp, sizeof( uint16_t ) );
337    *setme = ntohs( tmp );
338}
339
340static inline void tr_peerIoReadUint32( tr_peerIo        * io,
341                                           struct evbuffer  * inbuf,
342                                           uint32_t         * setme )
343{
344    uint32_t tmp;
345    tr_peerIoReadBytes( io, inbuf, &tmp, sizeof( uint32_t ) );
346    *setme = ntohl( tmp );
347}
348
349void      tr_peerIoDrain( tr_peerIo        * io,
350                          struct evbuffer  * inbuf,
351                          size_t             byteCount );
352
353/**
354***
355**/
356
357size_t    tr_peerIoGetWriteBufferSpace( const tr_peerIo * io, uint64_t now );
358
359static inline void tr_peerIoSetParent( tr_peerIo            * io,
360                                          struct tr_bandwidth  * parent )
361{
362    assert( tr_isPeerIo( io ) );
363
364    tr_bandwidthSetParent( &io->bandwidth, parent );
365}
366
367void      tr_peerIoBandwidthUsed( tr_peerIo           * io,
368                                  tr_direction          direction,
369                                  size_t                byteCount,
370                                  int                   isPieceData );
371
372static inline tr_bool
373tr_peerIoHasBandwidthLeft( const tr_peerIo * io, tr_direction dir )
374{
375    assert( tr_isPeerIo( io ) );
376
377    return !io->hasFinishedConnecting
378        || ( tr_bandwidthClamp( &io->bandwidth, dir, 1024 ) > 0 );
379}
380
381static inline unsigned int
382tr_peerIoGetPieceSpeed_Bps( const tr_peerIo * io, uint64_t now, tr_direction dir )
383{
384    assert( tr_isPeerIo( io ) );
385    assert( tr_isDirection( dir ) );
386
387    return tr_bandwidthGetPieceSpeed_Bps( &io->bandwidth, now, dir );
388}
389
390/**
391***
392**/
393
394void      tr_peerIoSetEnabled( tr_peerIo    * io,
395                               tr_direction   dir,
396                               tr_bool        isEnabled );
397
398int       tr_peerIoFlush( tr_peerIo     * io,
399                          tr_direction    dir,
400                          size_t          byteLimit );
401
402int       tr_peerIoFlushOutgoingProtocolMsgs( tr_peerIo * io );
403
404/**
405***
406**/
407
408static inline struct evbuffer * tr_peerIoGetReadBuffer( tr_peerIo * io )
409{
410    return io->inbuf;
411}
412
413/* @} */
414
415#endif
Note: See TracBrowser for help on using the repository browser.