📄 xtunnelsservermain.cpp
字号:
#endif //DEBUG return 1; } // okay, we have a real session now unsigned long startingNew = true; uuid_t thisSessionUUID; bzero(&thisSessionUUID, sizeof(uuid_t)); if (sReopenSession) { memcpy(&thisSessionUUID, &sRequestedSession, sizeof(sRequestedSession)); sReopenSession = false; startingNew = false; } if (startingNew) FillWithRandomLongs(&thisSessionUUID, sizeof(thisSessionUUID)); socklen_t len = sizeof(struct sockaddr_in); struct sockaddr_in net_client; memset(&net_client, 0, sizeof(net_client)); if (-1 == getsockname(sClientTCPSocket, (struct sockaddr *)(&net_client), &len)) {#if DEBUG cout << "X-Tunnels: HandleMessageClientReady failed to get local IP" << endl;#endif //DEBUG return 1; } // pipe parent whether it's new and the ID long piperesult1 = PipeWrite(g_tCurrentChildInfo.m_pChild2ServerPipe, &startingNew, sizeof(startingNew)); long piperesult2 = PipeWrite(g_tCurrentChildInfo.m_pChild2ServerPipe, &thisSessionUUID, sizeof(thisSessionUUID)); long piperesult3 = PipeWrite(g_tCurrentChildInfo.m_pChild2ServerPipe, g_tCurrentChildInfo.m_szHost, EMaxDBHostLength); if ((sizeof(startingNew) != piperesult1) || (sizeof(thisSessionUUID) != piperesult2) || (EMaxDBHostLength != piperesult3)) {#if DEBUG cout << "X-Tunnels: HandleMessageClientReady failed to pipe session ID to parent" << endl;#endif //DEBUG return 1; }#if DEBUG cout << "X-Tunnels: HandleMessageClientReady in client " << sCurrentChildIndex << " signalling " << (startingNew ? "new" : "old") << " host " << g_tCurrentChildInfo.m_szHost << " with SIGUSR1" << endl;#endif //DEBUG if (-1 == kill(getppid(), SIGUSR1)) {#if DEBUG cout << "X-Tunnels: HandleMessageClientReady failed to signal session ID availability to parent" << endl;#endif //DEBUG } // pipe back possible replacement UUID or a list of ports from previous session ID holder long parentResult = 0; long result = PipeRead(g_tCurrentChildInfo.m_pServer2ChildPipe, &parentResult, sizeof(parentResult)); switch (parentResult) { case kStartNewSession: { result = PipeRead(g_tCurrentChildInfo.m_pServer2ChildPipe, &thisSessionUUID, sizeof(thisSessionUUID)); int iHostCurrentConnections = 0; result = PipeRead(g_tCurrentChildInfo.m_pServer2ChildPipe, &iHostCurrentConnections, sizeof(iHostCurrentConnections)); if (sizeof(iHostCurrentConnections) != result) {#if DEBUG cout << "X-Tunnels: HandleMessageClientReady failed to pipe register result from parent" << endl;#endif //DEBUG return 1; }#if DEBUG cout << "X-Tunnels: HandleMessageClientReady got " << iHostCurrentConnections << "/" << g_iHostMax << " connections in use" << endl;#endif //DEBUG if (iHostCurrentConnections >= g_iHostMax) { sQuitReason = kDisconnectReasonTooBusy; sQuitMessage = sMessageTooBusy;#if DEBUG cout << "X-Tunnels: rejected attempted connection, host is out of connections" << endl;#endif //DEBUG return 1; } } break; case kFillOutPortList: { long portCount = 0; result = PipeRead(g_tCurrentChildInfo.m_pServer2ChildPipe, &portCount, sizeof(portCount)); for (int i = 0; i < portCount; i++) { long port; result = PipeRead(g_tCurrentChildInfo.m_pServer2ChildPipe, &port, sizeof(port)); long socket = u_openudp(port); if (socket != -1) { setnonblock(socket); pair<long, long> newMapping(port, socket); /*pair<map<long, long>::iterator, bool> p =*/ g_cUDPPorts.insert(newMapping); } else {#if DEBUG cout << "X-Tunnels: HandleMessageClientReady failed to open socket on piped port!" << endl;#endif //DEBUG } } g_ulActiveDualPorts = portCount / 2; g_ulActiveSinglePorts = portCount - (g_ulActiveDualPorts * 2); } break; default:#if DEBUG cout << "X-Tunnels: HandleMessageClientReady failed to pipe register result from parent" << endl;#endif //DEBUG return 1; } CleanChildPipes(g_tCurrentChildInfo); u_port_t redirectport = 0; OpenUDPSocket(sClientUDPRedirectSocket, redirectport); g_tCurrentChildInfo.sessionID = thisSessionUUID; g_tCurrentChildInfo.status = SChild::eActive; // if client supports it, let them know we support x-cipher if (XCipher::XCipherEnabled() && ChildData()->SupportsXCipher()) { packet->m_tHeaderBasic.commandid = HOST2XT32(EMessage_ServerToClient_NotifyServerSupport); long packetsize = sizeof(TServerNotifyServerSupportParam); packet->m_tHeaderBasic.payloadsize = HOST2XT32(packetsize); packet->m_tData.m_tNotifyServerSupport.m_ulSupportFlags = HOST2XT32(ESupportXCipher); if (ChildData()->SendPacketToClient(packet, packetsize, false)) return 1;#if DEBUG cout << "X-Tunnels: HandleMessageClientReady sent XCipher enabled notification packet" << endl;#endif //DEBUG } else {#if DEBUG cout << "X-Tunnels: HandleMessageClientReady did NOT send XCipher enabled notification packet" << endl;#endif //DEBUG } // reply with session settings that client might keep for reconnection packet->m_tHeaderBasic.commandid = HOST2XT32(EMessageServerReady); long packetsize = sizeof(ServerReadyParam); packet->m_tHeaderBasic.payloadsize = HOST2XT32(packetsize); // address is always big, network byte order; packet always wants little packet->m_tData.serverready.externalip = BIG2XT32(net_client.sin_addr.s_addr); packet->m_tData.serverready.startnew = startingNew; packet->m_tData.serverready.sessionuuid = thisSessionUUID; packet->m_tData.serverready.m_dwServerSessionTimeoutInSeconds = HOST2XT32(g_ulChildDeathwatchTimeout); packet->m_tData.serverready.m_wServerAssignedUDPRedirectPort = HOST2XT16(redirectport); if (ChildData()->SendPacketToClient(packet, packetsize, false)) return 1; #if DEBUG cout << "X-Tunnels: HandleMessageClientReady succeeded" << endl;#endif //DEBUG return 0; }int HandleMessageRequestSinglePort(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != sizeof(ClientRequestSinglePortParam)) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestSinglePort expects packetsize " << sizeof(ClientRequestSinglePortParam) << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } // send a port back u_port_t newPort = 0; // 0 means request refused int socket = 0; OpenUDPSocket(socket, newPort); packet->m_tHeaderBasic.commandid = HOST2XT32(EMessageServerPortsAvailable); long packetsize = sizeof(ServerPortsAvailableParam); packet->m_tHeaderBasic.payloadsize = HOST2XT32(packetsize); // note that requestID from ClientRequestSinglePortParam is sent back unchanged packet->m_tData.serverportsavailable.portBase = HOST2XT16(newPort );#define TEST_ENCRYPTION 0#if TEST_ENCRYPTION sServerPacketEncryption = EAlgorithm_Triple_DES; //sServerPacketEncryption = kAlgorithmAES256;#endif // TEST_ENCRYPTION if (ChildData()->SendPacketToClient(packet, packetsize, false)) return 1; #if DEBUG cout << "X-Tunnels: HandleMessageRequestSinglePort (uuid " << GetUUIDString(&packet->m_tData.serverportsavailable.requestuuid, NULL) << ") found new port " << newPort << " on socket " << socket << endl;#endif //DEBUG return 0; }int HandleMessageRequestEvenBasedPortPair(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != sizeof(ClientRequestEvenBasedPortPairParam)) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestEvenBasedPortPair expects packetsize " << sizeof(ClientRequestEvenBasedPortPairParam) << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } // send a port back u_port_t newPortEven = 0; // 0 means request refused u_port_t newPortOdd = 0; // 0 means request refused int socketEven = 0; int socketOdd = 0; long attempts = 0; do { attempts++; // we'll pick port pair from 5000 - 65000 start even u_port_t tryPortBase = (rand() % 30000) * 2 + 5000; socketEven = u_openudp(tryPortBase); socketOdd = u_openudp(tryPortBase + 1); if ((socketEven != -1) && (socketOdd != -1)) { if (-1 == setnonblock(socketEven)) // UDP ports are nonblocking {#if DEBUG cout << "X-Tunnels: HandleMessageRequestEvenBasedPortPair couldn't set socketEven nonblocking!" << endl;#endif //DEBUG } if (-1 == setnonblock(socketOdd)) // UDP ports are nonblocking {#if DEBUG cout << "X-Tunnels: HandleMessageRequestEvenBasedPortPair couldn't set socketOdd nonblocking!" << endl;#endif //DEBUG } newPortEven = tryPortBase; newPortOdd = tryPortBase + 1; pair<long, long> newMappingEven(tryPortBase, socketEven); pair<long, long> newMappingOdd(tryPortBase + 1, socketOdd); pair<map<long, long>::iterator, bool> pEven = g_cUDPPorts.insert(newMappingEven); pair<map<long, long>::iterator, bool> pOdd = g_cUDPPorts.insert(newMappingOdd); g_ulActiveDualPorts++; if (!pEven.second) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestEvenBasedPortPair found new even port already listed as active!" << endl;#endif //DEBUG } if (!pOdd.second) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestEvenBasedPortPair found new odd port already listed as active!" << endl;#endif //DEBUG } } else { if (socketEven) if (r_close(socketEven) == -1) {#if DEBUG cout << "X-Tunnels: child " << getpid() << " failed to close temporary UDP socket " << socketEven << endl;#endif //DEBUG } if (socketOdd) if (r_close(socketOdd) == -1) {#if DEBUG cout << "X-Tunnels: child " << getpid() << " failed to close temporary UDP socket " << socketOdd << endl;#endif //DEBUG } } } while (!newPortEven && (attempts < 1500)); packet->m_tHeaderBasic.commandid = HOST2XT32(EMessageServerPortsAvailable); long packetsize = sizeof(ServerPortsAvailableParam); packet->m_tHeaderBasic.payloadsize = HOST2XT32(packetsize); // note that requestID from ClientRequestEvenBasedPortPairParam is sent back unchanged packet->m_tData.serverportsavailable.portBase = HOST2XT16(newPortEven); if (ChildData()->SendPacketToClient(packet, packetsize, false)) return 1; #if DEBUG cout << "X-Tunnels: HandleMessageRequestEvenBasedPortPair found new ports " << newPortEven << "," << newPortOdd << " on sockets " << socketEven << "," << socketOdd << endl;#endif //DEBUG return 0; }int HandleMessageRequestClosePort(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != sizeof(ClientRequestClosePortParam)) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestClosePort expects packetsize " << sizeof(ClientRequestClosePortParam) << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } u_port_t closebase = XT2HOST16(packet->m_tData.clientrequestcloseport.closeport);#if DEBUG cout << "X-Tunnels: HandleMessageRequestClosePort closing ports for base " << closebase << endl; int closed = 0;#endif //DEBUG // "NOTE: will only close the port base port, all other ports are part of the port base must close" -- Robin bool closedLast = false; for (u_port_t closeit = closebase; closeit < closebase + 2; closeit++) { map<long, long>::iterator p = g_cUDPPorts.find(closeit); if (p != g_cUDPPorts.end()) { int socket = p->second; if (r_close(socket) == -1) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestClosePort failed to close socket " << socket << endl;#endif //DEBUG // should we abort or something? } int removed = g_cUDPPorts.erase(p->first); if (!removed) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestClosePort failed to unmap port " << p->first << endl;#endif //DEBUG } else {#if DEBUG closed++;#endif //DEBUG } closedLast = true; } else closedLast = false; } if (closedLast && g_ulActiveDualPorts) g_ulActiveDualPorts--; else if (g_ulActiveSinglePorts) g_ulActiveSinglePorts--; #if DEBUG cout << "X-Tunnels: HandleMessageRequestClosePort closed " << closed << " port(s) " << endl;#endif //DEBUG return 0; }int HandleMessageRequestSendPacket(TXTunnelsPacket* packet) { unsigned short fromport = XT2HOST16(packet->m_tData.clientrequestsendpacket.fromport); // address is always big, network byte order; packet always wants little unsigned long destip = XT2BIG32(packet->m_tData.clientrequestsendpacket.destip); unsigned short destport = XT2BIG16(packet->m_tData.clientrequestsendpacket.destport); long packetsize = XT2HOST32(packet->m_tData.clientrequestsendpacket.packetblobsize); if (!VerifyDestinationIPAllowedAndLogOutgoingTraffic( destip, ChildData()->m_szCachedHost, packetsize )) { sQuitReason = kDisconnectReasonMustClose;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -