diff --git a/libtransmission/peer-io.c b/libtransmission/peer-io.c index 7ca67984e..b7f15de3b 100644 --- a/libtransmission/peer-io.c +++ b/libtransmission/peer-io.c @@ -25,6 +25,7 @@ #include #include +#include "utp.h" #include "transmission.h" #include "session.h" @@ -367,7 +368,8 @@ tr_peerIoNew( tr_session * session, const uint8_t * torrentHash, tr_bool isIncoming, tr_bool isSeed, - int socket ) + int socket, + struct UTPSocket * utp_socket) { tr_peerIo * io; @@ -376,6 +378,7 @@ tr_peerIoNew( tr_session * session, assert( tr_isBool( isIncoming ) ); assert( tr_isBool( isSeed ) ); assert( tr_amInEventThread( session ) ); + assert( (socket < 0) == (utp_socket != NULL) ); if( socket >= 0 ) { tr_netSetTOS( socket, session->peerSocketTOS ); @@ -391,16 +394,22 @@ tr_peerIoNew( tr_session * session, io->isSeed = isSeed; io->port = port; io->socket = socket; + io->utp_socket = utp_socket; io->isIncoming = isIncoming != 0; io->timeCreated = tr_time( ); io->inbuf = evbuffer_new( ); io->outbuf = evbuffer_new( ); - io->event_read = event_new( session->event_base, io->socket, EV_READ, event_read_cb, io ); - io->event_write = event_new( session->event_base, io->socket, EV_WRITE, event_write_cb, io ); tr_bandwidthConstruct( &io->bandwidth, session, parent ); tr_bandwidthSetPeer( &io->bandwidth, io ); dbgmsg( io, "bandwidth is %p; its parent is %p", &io->bandwidth, parent ); + if( io->socket >= 0 ) { + io->event_read = event_new( session->event_base, + io->socket, EV_READ, event_read_cb, io ); + io->event_write = event_new( session->event_base, + io->socket, EV_WRITE, event_write_cb, io ); + } + return io; } @@ -409,13 +418,14 @@ tr_peerIoNewIncoming( tr_session * session, tr_bandwidth * parent, const tr_address * addr, tr_port port, - int fd ) + int fd, + struct UTPSocket * utp_socket ) { assert( session ); assert( tr_isAddress( addr ) ); - assert( fd >= 0 ); - return tr_peerIoNew( session, parent, addr, port, NULL, TRUE, FALSE, fd ); + return tr_peerIoNew( session, parent, addr, port, NULL, TRUE, FALSE, + fd, utp_socket ); } tr_peerIo* @@ -436,7 +446,8 @@ tr_peerIoNewOutgoing( tr_session * session, dbgmsg( NULL, "tr_netOpenPeerSocket returned fd %d", fd ); return fd < 0 ? NULL - : tr_peerIoNew( session, parent, addr, port, torrentHash, FALSE, isSeed, fd ); + : tr_peerIoNew( session, parent, addr, port, + torrentHash, FALSE, isSeed, fd, NULL ); } /*** @@ -449,12 +460,14 @@ event_enable( tr_peerIo * io, short event ) assert( tr_amInEventThread( io->session ) ); assert( io->session != NULL ); assert( io->session->events != NULL ); - assert( event_initialized( io->event_read ) ); - assert( event_initialized( io->event_write ) ); if( io->socket < 0 ) return; + assert( io->session->events != NULL ); + assert( event_initialized( io->event_read ) ); + assert( event_initialized( io->event_write ) ); + if( ( event & EV_READ ) && ! ( io->pendingEvents & EV_READ ) ) { dbgmsg( io, "enabling libevent ready-to-read polling" ); @@ -475,6 +488,10 @@ event_disable( struct tr_peerIo * io, short event ) { assert( tr_amInEventThread( io->session ) ); assert( io->session != NULL ); + + if( io->socket < 0 ) + return; + assert( io->session->events != NULL ); assert( event_initialized( io->event_read ) ); assert( event_initialized( io->event_write ) ); @@ -532,7 +549,10 @@ io_dtor( void * vio ) tr_bandwidthDestruct( &io->bandwidth ); evbuffer_free( io->outbuf ); evbuffer_free( io->inbuf ); - tr_netClose( io->session, io->socket ); + if( io->socket >= 0 ) + tr_netClose( io->session, io->socket ); + if( io->utp_socket != NULL ) + UTP_Close( io->utp_socket ); tr_cryptoFree( io->crypto ); tr_list_free( &io->outbuf_datatypes, tr_free ); @@ -639,8 +659,14 @@ tr_peerIoReconnect( tr_peerIo * io ) pendingEvents = io->pendingEvents; event_disable( io, EV_READ | EV_WRITE ); - if( io->socket >= 0 ) + if( io->socket >= 0 ) { tr_netClose( session, io->socket ); + io->socket = -1; + } + if( io->utp_socket != NULL ) { + UTP_Close(io->utp_socket); + io->utp_socket = NULL; + } event_free( io->event_read ); event_free( io->event_write ); diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index e17558220..1ab140b61 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -83,6 +83,7 @@ typedef struct tr_peerIo tr_port port; int socket; + struct UTPSocket *utp_socket; int refCount; @@ -125,7 +126,8 @@ tr_peerIo* tr_peerIoNewIncoming( tr_session * session, struct tr_bandwidth * parent, const struct tr_address * addr, tr_port port, - int socket ); + int socket, + struct UTPSocket * utp_socket ); void tr_peerIoRefImpl ( const char * file, int line, diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 283589449..8394dd205 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -17,6 +17,7 @@ #include /* qsort */ #include +#include "utp.h" #include "transmission.h" #include "announcer.h" @@ -2007,7 +2008,8 @@ void tr_peerMgrAddIncoming( tr_peerMgr * manager, tr_address * addr, tr_port port, - int socket ) + int socket, + struct UTPSocket * utp_socket ) { tr_session * session; @@ -2019,18 +2021,24 @@ tr_peerMgrAddIncoming( tr_peerMgr * manager, if( tr_sessionIsAddressBlocked( session, addr ) ) { tr_dbg( "Banned IP address \"%s\" tried to connect to us", tr_ntop_non_ts( addr ) ); - tr_netClose( session, socket ); + if(socket >= 0) + tr_netClose( session, socket ); + else + UTP_Close( utp_socket ); } else if( getExistingHandshake( &manager->incomingHandshakes, addr ) ) { - tr_netClose( session, socket ); + if(socket >= 0) + tr_netClose( session, socket ); + else + UTP_Close( utp_socket ); } else /* we don't have a connection to them yet... */ { tr_peerIo * io; tr_handshake * handshake; - io = tr_peerIoNewIncoming( session, session->bandwidth, addr, port, socket ); + io = tr_peerIoNewIncoming( session, session->bandwidth, addr, port, socket, utp_socket ); handshake = tr_handshakeNew( io, session->encryptionMode, @@ -2612,6 +2620,7 @@ tr_peerMgrPeerStats( const tr_torrent * tor, int * setmeCount ) stat->pendingReqsToClient = peer->pendingReqsToClient; pch = stat->flagStr; + if( peer->io->utp_socket != NULL) *pch++ = 'T'; if( t->optimistic == peer ) *pch++ = 'O'; if( stat->isDownloadingFrom ) *pch++ = 'D'; else if( stat->clientIsInterested ) *pch++ = 'd'; diff --git a/libtransmission/peer-mgr.h b/libtransmission/peer-mgr.h index 571be9745..117595c68 100644 --- a/libtransmission/peer-mgr.h +++ b/libtransmission/peer-mgr.h @@ -34,6 +34,7 @@ * @{ */ +struct UTPSocket; struct tr_peer_stat; struct tr_torrent; typedef struct tr_peerMgr tr_peerMgr; @@ -163,7 +164,8 @@ void tr_peerMgrRebuildRequests( tr_torrent * torrent ); void tr_peerMgrAddIncoming( tr_peerMgr * manager, tr_address * addr, tr_port port, - int socket ); + int socket, + struct UTPSocket *utp_socket ); tr_pex * tr_peerMgrCompactToPex( const void * compact, size_t compactLen, diff --git a/libtransmission/session.c b/libtransmission/session.c index d00f8812a..a82787c9d 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -194,7 +194,8 @@ accept_incoming_peer( int fd, short what UNUSED, void * vsession ) if( clientSocket > 0 ) { tr_deepLog( __FILE__, __LINE__, NULL, "new incoming connection %d (%s)", clientSocket, tr_peerIoAddrStr( &clientAddr, clientPort ) ); - tr_peerMgrAddIncoming( session->peerMgr, &clientAddr, clientPort, clientSocket ); + tr_peerMgrAddIncoming( session->peerMgr, &clientAddr, clientPort, + clientSocket, NULL ); } }