Changeset 7397 for trunk/libtransmission/port-forwarding.c
- Timestamp:
- Dec 15, 2008, 12:17:08 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/port-forwarding.c
r7392 r7397 39 39 tr_port_forwarding upnpStatus; 40 40 41 int bindPort;42 int bindSocket;43 intpublicPort;41 tr_bool shouldChange; 42 tr_socketList * bindSockets; 43 tr_port publicPort; 44 44 45 45 tr_timer * pulseTimer; … … 85 85 natPulse( tr_shared * s ) 86 86 { 87 const int port = s->publicPort;88 const int isEnabled = s->isEnabled && !s->isShuttingDown;89 int oldStatus;90 int newStatus;87 const tr_port port = s->publicPort; 88 const int isEnabled = s->isEnabled && !s->isShuttingDown; 89 int oldStatus; 90 int newStatus; 91 91 92 92 oldStatus = tr_sharedTraversalStatus( s ); … … 101 101 } 102 102 103 static void 104 incomingPeersPulse( tr_shared * s ) 105 { 106 tr_bool allPaused; 107 tr_torrent * tor; 108 109 if( s->bindSocket >= 0 && ( s->bindPort != s->publicPort ) ) 110 { 111 tr_ninf( getKey( ), _( "Closing port %d" ), s->bindPort ); 112 tr_netClose( s->bindSocket ); 113 s->bindSocket = -1; 114 } 115 116 if( ( s->publicPort > 0 ) && ( s->bindPort != s->publicPort ) ) 117 { 118 int socket; 119 errno = 0; 120 socket = tr_netBindTCP( &tr_inaddr_any, s->publicPort ); 121 if( socket >= 0 ) 122 { 123 tr_ninf( getKey( ), 124 _( 125 "Opened port %d to listen for incoming peer connections" ), 126 s->publicPort ); 127 s->bindPort = s->publicPort; 128 s->bindSocket = socket; 129 listen( s->bindSocket, 5 ); 130 } 131 else 132 { 133 tr_nerr( getKey( ), 134 _( 135 "Couldn't open port %d to listen for incoming peer connections (errno %d - %s)" ), 136 s->publicPort, errno, tr_strerror( errno ) ); 137 s->bindPort = -1; 138 s->bindSocket = -1; 139 } 140 } 141 142 /* see if any torrents aren't paused */ 143 allPaused = 1; 144 tor = NULL; 145 while(( tor = tr_torrentNext( s->session, tor ))) { 146 if( TR_STATUS_IS_ACTIVE( tr_torrentGetActivity( tor ))) { 147 allPaused = 0; 148 break; 149 } 150 } 151 152 /* if we have any running torrents, check for new incoming peer connections */ 153 while( !allPaused ) 154 { 155 int socket; 156 tr_port port; 157 tr_address addr; 158 159 if( s->bindSocket < 0 ) 160 break; 161 162 socket = tr_netAccept( s->session, s->bindSocket, &addr, &port ); 163 if( socket < 0 ) 164 break; 165 103 /* 104 * Callbacks for socket list 105 */ 106 static void 107 closeCb( int * const socket, 108 tr_address * const addr, 109 void * const userData ) 110 { 111 tr_shared * s = ( tr_shared * )userData; 112 if( *socket >= 0 ) 113 { 114 tr_ninf( getKey( ), _( "Closing port %d on %s" ), s->publicPort, 115 tr_ntop_non_ts( addr ) ); 116 tr_netClose( *socket ); 117 } 118 } 119 120 static void 121 acceptCb( int * const socket, 122 tr_address * const addr, 123 void * const userData ) 124 { 125 tr_shared * s = ( tr_shared * )userData; 126 tr_address clientAddr; 127 tr_port clientPort; 128 int clientSocket; 129 clientSocket = tr_netAccept( s->session, *socket, &clientAddr, &clientPort ); 130 if( clientSocket > 0 ) 131 { 166 132 tr_deepLog( __FILE__, __LINE__, NULL, 167 133 "New INCOMING connection %d (%s)", 168 socket, tr_peerIoAddrStr( &addr, port ) ); 169 170 tr_peerMgrAddIncoming( s->session->peerMgr, &addr, port, socket ); 171 } 134 clientSocket, tr_peerIoAddrStr( &clientAddr, clientPort ) ); 135 136 tr_peerMgrAddIncoming( s->session->peerMgr, &clientAddr, clientPort, 137 clientSocket ); 138 } 139 } 140 141 static void 142 bindCb( int * const socket, 143 tr_address * const addr, 144 void * const userData ) 145 { 146 tr_shared * s = ( tr_shared * )userData; 147 *socket = tr_netBindTCP( addr, s->publicPort, FALSE ); 148 if( *socket >= 0 ) 149 { 150 tr_ninf( getKey( ), 151 _( "Opened port %d on %s to listen for incoming peer connections" ), 152 s->publicPort, tr_ntop_non_ts( addr ) ); 153 listen( *socket, 10 ); 154 } 155 else 156 { 157 tr_nerr( getKey( ), 158 _( 159 "Couldn't open port %d on %s to listen for incoming peer connections (errno %d - %s)" ), 160 s->publicPort, tr_ntop_non_ts( addr ), errno, tr_strerror( errno ) ); 161 } 162 } 163 164 static void 165 incomingPeersPulse( tr_shared * s ) 166 { 167 int allPaused; 168 tr_torrent * tor; 169 170 if( s->shouldChange ) 171 { 172 tr_socketListForEach( s->bindSockets, &closeCb, s ); 173 s->shouldChange = FALSE; 174 if( s->publicPort > 0 ) 175 tr_socketListForEach( s->bindSockets, &bindCb, s ); 176 } 177 178 /* see if any torrents aren't paused */ 179 allPaused = 1; 180 tor = NULL; 181 while( ( tor = tr_torrentNext( s->session, tor ) ) ) 182 { 183 if( TR_STATUS_IS_ACTIVE( tr_torrentGetActivity( tor ) ) ) 184 { 185 allPaused = 0; 186 break; 187 } 188 } 189 190 /* if we have any running torrents, check for new incoming peer connections */ 191 /* (jhujhiti): 192 * This has been changed from a loop that will end when the listener queue 193 * is exhausted to one that will only check for one connection at a time. 194 * I think it unlikely that we get many more than one connection in the 195 * time between pulses (currently one second). However, just to be safe, 196 * I have increased the length of the listener queue from 5 to 10 197 * (see acceptCb() above). */ 198 if( !allPaused ) 199 tr_socketListForEach( s->bindSockets, &acceptCb, s ); 172 200 } 173 201 … … 188 216 tr_ninf( getKey( ), _( "Stopped" ) ); 189 217 tr_timerFree( &shared->pulseTimer ); 190 tr_ netClose( shared->bindSocket);218 tr_socketListForEach( shared->bindSockets, &closeCb, shared ); 191 219 tr_natpmpClose( shared->natpmp ); 192 220 tr_upnpClose( shared->upnp ); … … 203 231 ***/ 204 232 233 static tr_socketList * 234 setupBindSockets( tr_port port ) 235 { 236 /* Do we care if an address is in use? Probably not, since it will be 237 * caught later. This will only set up the list of sockets to bind. */ 238 int s4, s6; 239 tr_socketList * socks = NULL; 240 s6 = tr_netBindTCP( &tr_in6addr_any, port, TRUE ); 241 if( s6 >= 0 || -s6 != EAFNOSUPPORT ) /* we support ipv6 */ 242 { 243 socks = tr_socketListNew( &tr_in6addr_any ); 244 listen( s6, 1 ); 245 } 246 s4 = tr_netBindTCP( &tr_inaddr_any, port, TRUE ); 247 if( s4 >= 0 ) /* we bound *with* the ipv6 socket bound (need both) 248 * or only have ipv4 */ 249 { 250 if( socks ) 251 tr_socketListAppend( socks, &tr_inaddr_any ); 252 else 253 socks = tr_socketListNew( &tr_inaddr_any ); 254 tr_netClose( s4 ); 255 } 256 if( s6 >= 0 ) 257 tr_netClose( s6 ); 258 return socks; 259 } 260 205 261 tr_shared * 206 262 tr_sharedInit( tr_session * session, … … 212 268 s->session = session; 213 269 s->publicPort = publicPort; 214 s->bindPort = -1; 215 s->bindSocket = -1; 270 s->shouldChange = TRUE; 271 s->bindSockets = setupBindSockets( publicPort ); 272 s->shouldChange = TRUE; 216 273 s->natpmp = tr_natpmpInit( ); 217 274 s->upnp = tr_upnpInit( ); … … 235 292 tr_torrent * tor = NULL; 236 293 237 s->publicPort = port; 294 s->publicPort = port; 295 s->shouldChange = TRUE; 238 296 239 297 while( ( tor = tr_torrentNext( s->session, tor ) ) )
Note: See TracChangeset
for help on using the changeset viewer.