void CMiniUPnP::DoForwarding(SPort* pPort) { int UPnPStatus = upnpPulse(pPort->pUPnP, pPort->Port, pPort->Proto, pPort->Enabled, pPort->Enabled && pPort->Check, pPort->Name.toStdString().c_str()); int NatPMPStatus = natpmpPulse(pPort->pNatPMP, pPort->Port, pPort->Proto, pPort->Enabled); pPort->Status = UPnPStatus > NatPMPStatus ? UPnPStatus : NatPMPStatus; pPort->Check = (pPort->Status == PORT_MAPPED); if(pPort->Status == PORT_ERROR) pPort->Countdown = 60*333/1000; }
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; }