NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { MYDRIVERENTRY(DRIVER_DEVICE_NAME, FILE_DEVICE_ADDINT, AddInterrupt()); return ntStatus; }
// DDNS client thread void DCThread(THREAD *thread, void *param) { DDNS_CLIENT *c; INTERRUPT_MANAGER *interrput; UINT last_ip_hash = 0; void *route_change_poller = NULL; bool last_time_ip_changed = false; UINT last_azure_ddns_trigger_int = 0; UINT last_vgs_ddns_trigger_int = 0; UINT n; INTERNET_SETTING last_t; // Validate arguments if (thread == NULL || param == NULL) { return; } c = (DDNS_CLIENT *)param; interrput = NewInterruptManager(); route_change_poller = NewRouteChange(); IsRouteChanged(route_change_poller); Zero(&last_t, sizeof(last_t)); n = 0; while (c->Halt == false) { UINT ip_hash = GetHostIPAddressHash32(); UINT interval; UINT64 now = Tick64(); bool ip_changed = false; bool azure_client_triggered = false; bool internet_setting_changed = false; bool vgs_server_triggered = false; if (c->Cedar->Server != NULL && c->Cedar->Server->AzureClient != NULL) { if (c->Cedar->Server->AzureClient->DDnsTriggerInt != last_azure_ddns_trigger_int) { azure_client_triggered = true; last_azure_ddns_trigger_int = c->Cedar->Server->AzureClient->DDnsTriggerInt; last_time_ip_changed = false; Debug("DDNS Thread Triggered by AzureClient.\n"); } } if (Cmp(&last_t, &c->InternetSetting, sizeof(INTERNET_SETTING)) != 0) { Copy(&last_t, &c->InternetSetting, sizeof(INTERNET_SETTING)); internet_setting_changed = true; last_time_ip_changed = false; } if (ip_hash != last_ip_hash) { last_time_ip_changed = false; Debug("DDNS Thread Triggered by IP Hash Changed.\n"); } if ((ip_hash != last_ip_hash) || (IsRouteChanged(route_change_poller)) || azure_client_triggered || internet_setting_changed || vgs_server_triggered) { if (last_time_ip_changed == false) { // Call all getting functions from the beginning if the routing // table or the IP address of this host has changed c->NextRegisterTick_IPv4 = 0; c->NextRegisterTick_IPv6 = 0; c->NextGetMyIpTick_IPv4 = 0; c->NextGetMyIpTick_IPv6 = 0; last_ip_hash = ip_hash; last_time_ip_changed = true; ip_changed = true; Debug("DDNS Internet Condition Changed.\n"); } } else { last_time_ip_changed = false; } if ((n++) >= 1) { // Self IPv4 address acquisition if (c->NextGetMyIpTick_IPv4 == 0 || now >= c->NextGetMyIpTick_IPv4) { UINT next_interval; char ip[MAX_SIZE]; Zero(ip, sizeof(ip)); c->Err_IPv4_GetMyIp = DCGetMyIp(c, false, ip, sizeof(ip), NULL); if (c->Err_IPv4_GetMyIp == ERR_NO_ERROR) { if (StrCmpi(c->LastMyIPv4, ip) != 0) { ip_changed = true; StrCpy(c->LastMyIPv4, sizeof(c->LastMyIPv4), ip); } next_interval = GenRandInterval(DDNS_GETMYIP_INTERVAL_OK_MIN, DDNS_GETMYIP_INTERVAL_OK_MAX); } else { if (IsEmptyStr(c->LastMyIPv4) == false) { ip_changed = true; } Zero(c->LastMyIPv4, sizeof(c->LastMyIPv4)); next_interval = GenRandInterval(DDNS_GETMYIP_INTERVAL_NG_MIN, DDNS_GETMYIP_INTERVAL_NG_MAX); } c->NextGetMyIpTick_IPv4 = Tick64() + (UINT64)next_interval; AddInterrupt(interrput, c->NextGetMyIpTick_IPv4); } // Self IPv6 address acquisition if (c->NextGetMyIpTick_IPv6 == 0 || now >= c->NextGetMyIpTick_IPv6) { UINT next_interval; char ip[MAX_SIZE]; Zero(ip, sizeof(ip)); c->Err_IPv6_GetMyIp = DCGetMyIp(c, true, ip, sizeof(ip), NULL); if (c->Err_IPv6_GetMyIp == ERR_NO_ERROR) { if (StrCmpi(c->LastMyIPv6, ip) != 0) { ip_changed = true; StrCpy(c->LastMyIPv6, sizeof(c->LastMyIPv6), ip); } next_interval = GenRandInterval(DDNS_GETMYIP_INTERVAL_OK_MIN, DDNS_GETMYIP_INTERVAL_OK_MAX); } else { if (IsEmptyStr(c->LastMyIPv6) == false) { ip_changed = true; } Zero(c->LastMyIPv6, sizeof(c->LastMyIPv6)); next_interval = GenRandInterval(DDNS_GETMYIP_INTERVAL_NG_MIN, DDNS_GETMYIP_INTERVAL_NG_MAX); } c->NextGetMyIpTick_IPv6 = Tick64() + (UINT64)next_interval; AddInterrupt(interrput, c->NextGetMyIpTick_IPv6); } } if (ip_changed) { c->NextRegisterTick_IPv4 = 0; c->NextRegisterTick_IPv6 = 0; } // IPv4 host registration if (c->NextRegisterTick_IPv4 == 0 || now >= c->NextRegisterTick_IPv4) { UINT next_interval; c->Err_IPv4 = DCRegister(c, false, NULL, NULL); if (c->Err_IPv4 == ERR_NO_ERROR) { next_interval = GenRandInterval(DDNS_REGISTER_INTERVAL_OK_MIN, DDNS_REGISTER_INTERVAL_OK_MAX); } else { next_interval = GenRandInterval(DDNS_REGISTER_INTERVAL_NG_MIN, DDNS_REGISTER_INTERVAL_NG_MAX); } //next_interval = 0; c->NextRegisterTick_IPv4 = Tick64() + (UINT64)next_interval; if (true) { DDNS_CLIENT_STATUS st; DCGetStatus(c, &st); SiApplyAzureConfig(c->Cedar->Server, &st); } AddInterrupt(interrput, c->NextRegisterTick_IPv4); } if (c->Halt) { break; } // IPv6 host registration if (c->NextRegisterTick_IPv6 == 0 || now >= c->NextRegisterTick_IPv6) { UINT next_interval; c->Err_IPv6 = DCRegister(c, true, NULL, NULL); if (c->Err_IPv6 == ERR_NO_ERROR) { next_interval = GenRandInterval(DDNS_REGISTER_INTERVAL_OK_MIN, DDNS_REGISTER_INTERVAL_OK_MAX); } else { next_interval = GenRandInterval(DDNS_REGISTER_INTERVAL_NG_MIN, DDNS_REGISTER_INTERVAL_NG_MAX); } c->NextRegisterTick_IPv6 = Tick64() + (UINT64)next_interval; if (true) { DDNS_CLIENT_STATUS st; DCGetStatus(c, &st); SiApplyAzureConfig(c->Cedar->Server, &st); } AddInterrupt(interrput, c->NextRegisterTick_IPv6); } interval = GetNextIntervalForInterrupt(interrput); interval = MIN(interval, 1234); if (n == 1) { interval = MIN(interval, 0); } if (c->Halt) { break; } if (c->KeyChanged) { c->KeyChanged = false; c->NextRegisterTick_IPv4 = c->NextRegisterTick_IPv6 = 0; interval = 0; } if (last_time_ip_changed) { if (c->Cedar->Server != NULL && c->Cedar->Server->AzureClient != NULL) { c->Cedar->Server->AzureClient->IpStatusRevision++; } } Wait(c->Event, interval); } FreeRouteChange(route_change_poller); FreeInterruptManager(interrput); }
// Process the timer interrupt void SstpProcessInterrupt(SSTP_SERVER *s) { // Validate arguments if (s == NULL) { return; } s->Now = Tick64(); s->FlushRecvTube = false; // Process the received packet while (true) { BLOCK *b = GetNext(s->RecvQueue); SSTP_PACKET *p; if (b == NULL) { break; } p = SstpParsePacket(b->Buf, b->Size); if (p == NULL) { // Disconnect the SSTP since a bad packet received SstpAbort(s); } else { // Process the received packet SstpProcessPacket(s, p); SstpFreePacket(p); } FreeBlock(b); } if (s->FlushRecvTube) { TubeFlush(s->TubeRecv); } // Transmit a packet that the PPP module is trying to send via the SSTP while (true) { TUBEDATA *d = TubeRecvAsync(s->TubeSend); SSTP_PACKET *p; if (d == NULL) { break; } p = SstpNewDataPacket(d->Data, d->DataSize); SstpSendPacket(s, p); SstpFreePacket(p); FreeTubeData(d); } if (s->Status == SSTP_SERVER_STATUS_ESTABLISHED) { if (s->Disconnecting == false && s->Aborting == false) { // Periodic transmission of Echo Request if (s->NextSendEchoRequestTick == 0 || s->NextSendEchoRequestTick <= s->Now) { UINT64 next_interval = (UINT64)(SSTP_ECHO_SEND_INTERVAL_MIN + Rand32() % (SSTP_ECHO_SEND_INTERVAL_MAX - SSTP_ECHO_SEND_INTERVAL_MIN)); SSTP_PACKET *p; s->NextSendEchoRequestTick = s->Now + next_interval; AddInterrupt(s->Interrupt, s->NextSendEchoRequestTick); p = SstpNewControlPacket(SSTP_MSG_ECHO_REQUEST); SstpSendPacket(s, p); SstpFreePacket(p); } } } if ((s->LastRecvTick + (UINT64)SSTP_TIMEOUT) <= s->Now) { // Disconnect the SSTP because a timeout occurred SstpAbort(s); s->Disconnected = true; } if (IsTubeConnected(s->TubeRecv) == false || IsTubeConnected(s->TubeSend) == false) { // Disconnect the SSTP since the PPP module is disconnected SstpDisconnect(s); } if (s->Disconnecting) { // Normal disconnection process if (s->DisconnectSent == false) { // Send a Disconnect SSTP_PACKET *ret = SstpNewControlPacket(s->DisconnectRecved ? SSTP_MSG_CALL_DISCONNECT_ACK : SSTP_MSG_CALL_DISCONNECT); SstpSendPacket(s, ret); SstpFreePacket(ret); s->DisconnectSent = true; } } if (s->Aborting) { // Abnormal disconnection processing if (s->AbortSent == false) { // Send the Abort SSTP_PACKET *ret = SstpNewControlPacket(SSTP_MSG_CALL_ABORT); SstpSendPacket(s, ret); SstpFreePacket(ret); s->AbortSent = true; } } if (s->DisconnectSent && s->DisconnectRecved) { // Disconnect after exchanging the Disconnect each other s->Disconnected = true; } if (s->AbortSent && s->AbortReceived) { // Disconnect after exchanging the Abort each other s->Disconnected = true; } }