static void natPulse( tr_shared * s, bool do_check ) { const tr_port private_peer_port = s->session->private_peer_port; const int is_enabled = s->isEnabled && !s->isShuttingDown; tr_port public_peer_port; int oldStatus; int newStatus; if( s->natpmp == NULL ) s->natpmp = tr_natpmpInit( ); if( s->upnp == NULL ) s->upnp = tr_upnpInit( ); oldStatus = tr_sharedTraversalStatus( s ); s->natpmpStatus = tr_natpmpPulse( s->natpmp, private_peer_port, is_enabled, &public_peer_port ); if( s->natpmpStatus == TR_PORT_MAPPED ) s->session->public_peer_port = public_peer_port; s->upnpStatus = tr_upnpPulse( s->upnp, private_peer_port, is_enabled, do_check ); newStatus = tr_sharedTraversalStatus( s ); if( newStatus != oldStatus ) tr_ninf( getKey( ), _( "State changed from \"%1$s\" to \"%2$s\"" ), getNatStateStr( oldStatus ), getNatStateStr( newStatus ) ); }
static void natPulse( tr_shared * s, tr_bool doPortCheck ) { const tr_port port = s->session->peerPort; const int isEnabled = s->isEnabled && !s->isShuttingDown; int oldStatus; int newStatus; if( s->natpmp == NULL ) s->natpmp = tr_natpmpInit( ); if( s->upnp == NULL ) s->upnp = tr_upnpInit( ); oldStatus = tr_sharedTraversalStatus( s ); s->natpmpStatus = tr_natpmpPulse( s->natpmp, port, isEnabled ); s->upnpStatus = tr_upnpPulse( s->upnp, port, isEnabled, doPortCheck ); newStatus = tr_sharedTraversalStatus( s ); if( newStatus != oldStatus ) tr_ninf( getKey( ), _( "State changed from \"%1$s\" to \"%2$s\"" ), getNatStateStr( oldStatus ), getNatStateStr( newStatus ) ); }
static void * upnpNatpmpThread( ) { int oldStatus, newStatus; int i, err; time_t now; struct timespec deltatime; pthread_mutex_lock(&g_mutex); g_stop = 0; pthread_mutex_unlock(&g_mutex); while( g_running ){ //clear in g_unmaps now = time(NULL); for(i = 0; i < MAX_MAPS; i++){ if ( ! g_running ) break; if ( ! g_unmaps[i].enabled && g_unmaps[i].extPort > 0 ){ if ( g_unmaps[i].overTime < now ){ oldStatus = getStatus( &g_unmaps[i] ); pthread_mutex_lock(&g_mutex); switch (oldStatus){ case ML_PORT_MAPPED: g_unmaps[i].overTime = now + 60 * 20; break; case ML_PORT_ERROR: g_unmaps[i].overTime = now + 60; break; default: /* in progress. pulse frequently. */ g_unmaps[i].overTime = now + 333; break; } g_unmaps[i].natpmpStatus = natpmpPulse( &g_unmaps[i] ); g_unmaps[i].doPortCheck = 0; g_unmaps[i].upnpStatus = upnpPulse( &g_unmaps[i]); dbg_printf( "upnpNatpmpThread g_unmaps[%d]\n", i); #ifdef DEBUG_PRINTF_UPNP dumpMap(&g_unmaps[i], 1); #endif newStatus = getStatus( &g_unmaps[i] ); if( newStatus != oldStatus ) dbg_printf( "port forwarding state changed from \"%s\" to \"%s\"\n", getNatStateStr( oldStatus ), getNatStateStr( newStatus ) ); if( newStatus == ML_PORT_UNMAPPED ){ memset(&g_unmaps[i], 0, sizeof(ml_upnpmp_t)); } pthread_mutex_unlock(&g_mutex); } } } //create,check in g_maps now = time(NULL); for(i = 0; i < MAX_MAPS; i++){ if ( ! g_running ) break; if ( g_maps[i].enabled && g_maps[i].extPort ){ if ( g_maps[i].overTime < now ){ oldStatus = getStatus( &g_maps[i] ); pthread_mutex_lock(&g_mutex); switch (oldStatus){ case ML_PORT_MAPPED: g_maps[i].overTime = now + 60 * 20; break; case ML_PORT_ERROR: g_maps[i].overTime = now + 60; break; default: /* in progress. pulse frequently. */ g_maps[i].overTime = now + 333; break; } g_maps[i].natpmpStatus = natpmpPulse( &g_maps[i] ); g_maps[i].doPortCheck = 1; g_maps[i].upnpStatus = upnpPulse( &g_maps[i] ); pthread_mutex_unlock(&g_mutex); dbg_printf( "upnpNatpmpThread g_maps[%d]\n", i); #ifdef DEBUG_PRINTF_UPNP dumpMap(&g_maps[i], 1); #endif newStatus = getStatus( &g_maps[i] ); if( newStatus != oldStatus ) dbg_printf( "port forwarding state changed from \"%s\" to \"%s\"\n", getNatStateStr( oldStatus ), getNatStateStr( newStatus ) ); } } } if ( g_running ){ deltatime.tv_sec = time(NULL) + 30; deltatime.tv_nsec = 0; #if defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS - 200112L) >= 0L err = pthread_mutex_timedlock(&g_delay_mutex, &deltatime); dbg_printf("%d seconds timedlock err=%d, running...\n", deltatime.tv_sec, err); #else do { err = pthread_mutex_trylock(&g_delay_mutex); if(err == EBUSY){ struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 100000000; int status = -1; while (status == -1) status = nanosleep(&ts, &ts); } else break; //dbg_printf("trylock err=%d, running...\n", err); } while (err != 0 && (time(NULL) < deltatime.tv_sec)); #endif }else{ break; } } pthread_mutex_lock(&g_mutex); g_stop = 1; pthread_mutex_unlock(&g_mutex); dbg_printf("upnp thread stopped!\n"); return NULL; }