📄 xtunnelsservermain.cpp
字号:
sQuitMessage = sMessageIllegalDestination; return 1; } int sendSocket = 0; map<long, long>::iterator p = g_cUDPPorts.find(fromport); if (p == g_cUDPPorts.end()) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestSendPacket could not find socket for port " << fromport << endl;#endif //DEBUG return 1; } sendSocket = p->second; u_buf_t destination = { 0 }; destination.sin_family = AF_INET; destination.sin_port = destport; destination.sin_addr.s_addr = destip; ssize_t sent = u_sendto(sendSocket, &packet->m_tData.clientrequestsendpacket.packetblob, packetsize, &destination); if (sent != packetsize) {#if DEBUG cout << "X-Tunnels: HandleMessageRequestSendPacket failed (" << sent << ") to send " << packetsize << " packet data bytes" << endl;#endif //DEBUG sQuitReason = kDisconnectReasonMustClose; sQuitMessage = sMessageUnexpectedError; return 1; } // for our accounting, to be stored in database at quit time LogOutgoingPacket(packetsize); return 0; }int HandleMessageClientRequestTestUDPRedirectPortCheck(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != sizeof(ClientRequestTestUDPRedirectPortCheckParam)) {#if DEBUG cout << "X-Tunnels: HandleMessageClientRequestTestUDPRedirectPortCheck expects packetsize " << sizeof(ClientRequestTestUDPRedirectPortCheckParam) << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } uuid_t tTestGUID = packet->m_tData.clientrequesttestudpredirectPortCheck.m_tTestGUID; unsigned long sourceip = sLastUDPRedirectSource.sin_addr.s_addr; unsigned short sourceport = sLastUDPRedirectSource.sin_port; // reply with identical GUID and source address/port packet->m_tHeaderBasic.commandid = HOST2XT32(EMessageServerReplyTestUDPRedirectPortCheck); long packetsize = sizeof(ServerReplyTestUDPRedirectPortCheckParam); packet->m_tHeaderBasic.payloadsize = HOST2XT32(packetsize); packet->m_tData.serverreplytestudpredirectportcheckparam.m_tTestGUID = tTestGUID; // always little endian in packets, Net addresses are big endian, so unconditional swaps packet->m_tData.serverreplytestudpredirectportcheckparam.m_dwSourceIPAddress = BIG2XT32(sourceip); packet->m_tData.serverreplytestudpredirectportcheckparam.m_wSourcePort = BIG2XT16(sourceport); if (ChildData()->SendPacketToClient(packet, packetsize, false)) // on the UDP port always return 1; #if DEBUG cout << "X-Tunnels: HandleMessageClientRequestTestUDPRedirectPortCheck succeeded" << endl;#endif //DEBUG return 0; }int HandleMessageClientRequestBindRedirectPortUDPToIP(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != sizeof(ClientRequestBindRedirectPortUDPToIPParam)) {#if DEBUG cout << "X-Tunnels: HandleMessageClientRequestBindRedirectPortUDPToIP expects packetsize " << sizeof(ClientRequestBindRedirectPortUDPToIPParam) << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } // always little endian in packets, Net addresses are big endian, so unconditional swaps sBoundUDPRedirectAddress = XT2BIG32(packet->m_tData.clientrequestbindredirectportudptoip.m_dwOnlyAllowFromIPAddress); sBoundUDPRedirectPort = XT2BIG16(packet->m_tData.clientrequestbindredirectportudptoip.m_wOnlyAllowFromPort); #if DEBUG cout << "X-Tunnels: HandleMessageClientRequestBindRedirectPortUDPToIP succeeded" << endl;#endif //DEBUG return 0; }int HandleMessageClientRequestBindTestUDPRedirectPortReply(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != sizeof(ClientRequestBindTestUDPRedirectPortReplyParam)) {#if DEBUG cout << "X-Tunnels: HandleMessageClientRequestBindTestUDPRedirectPortReply expects packetsize " << sizeof(ClientRequestBindTestUDPRedirectPortReplyParam) << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } packet->m_tHeaderBasic.commandid = HOST2XT32(EMessageServerReplyBindTestUDPRedirectPortReply); long packetsize = sizeof(ServerReplyBindTestUDPRedirectPortReplyParam); packet->m_tHeaderBasic.payloadsize = HOST2XT32(packetsize); // note that requestID from ClientRequestBindTestUDPRedirectPortReplyParam is sent back unchanged if (ChildData()->SendPacketToClient(packet, packetsize, true)) // on the UDP port always return 1; #if DEBUG cout << "X-Tunnels: HandleMessageClientRequestBindTestUDPRedirectPortReply succeeded" << endl;#endif //DEBUG return 0; }int HandleMessageClientRequestBindUDPRedirectPortPacketForward(TXTunnelsPacket* packet) { if (packet->m_tHeaderBasic.payloadsize != 0 /*sizeof(ClientRequestBindUDPRedirectPortPacketForwardParam)*/) // sizeof(ClientRequestBindUDPRedirectPortPacketForwardParam) is 1! {#if DEBUG cout << "X-Tunnels: HandleMessageClientRequestBindUDPRedirectPortPacketForward expects packetsize " << 0 /*sizeof(ClientRequestBindUDPRedirectPortPacketForwardParam)*/ << " but packet claims " << packet->m_tHeaderBasic.payloadsize << endl;#endif //DEBUG return 1; } sForwardPacketsToUDPRedirectPort = true; #if DEBUG cout << "X-Tunnels: HandleMessageClientRequestBindUDPRedirectPortPacketForward succeeded" << endl;#endif //DEBUG return 0; }#if VS_TARGET_OS_MAC#pragma mark *** high level functions#endif // VS_TARGET_OS_MACint HandleClientPacketError(bool bInUDPSocket) { if (bInUDPSocket) {#if DEBUG cout << "X-Tunnels: child " << getpid() << " UDP bogus source or packet read error, discarding data and continuing... " << endl;#endif //DEBUG return 0; } else {#if DEBUG cout << "X-Tunnels: child " << getpid() << " TCP packet error, aborting! " << endl;#endif //DEBUG return 1; } }int DispatchClientPacket(TXTunnelsPacket* tInPacket, bool bInUDPSocket) { if (!tInPacket) return 1; // note that UDP errors are ignored, so iPacketHandlingResult needn't be set for the cases that are only handled on TCP int iPacketHandlingResult = 0; // check magic number and packet index unsigned long ulMagicNumber = XT2HOST32(tInPacket->m_tData.m_ulPacketMagicNumber); if (ulMagicNumber != XT2HOST32(EPacketMagicNumber)) {#if DEBUG cout << "X-Tunnels: child " << getpid() << " failed magic number (" << EPacketMagicNumber << ") check with " << ulMagicNumber << ", aborting! " << endl;#endif //DEBUG sQuitReason = kDisconnectReasonMustClose; sQuitMessage = g_pMessageBadMagicNumber; return 1; } //unsigned long ulPacketIndex = XT2HOST32(tInPacket->m_tData.m_ulPacketIndex); // handlers validate data size of their params tInPacket->m_tHeaderBasic.payloadsize -= sizeof(tInPacket->m_tData.m_ulPacketMagicNumber); tInPacket->m_tHeaderBasic.payloadsize -= sizeof(tInPacket->m_tData.m_ulPacketIndex); switch (tInPacket->m_tHeaderBasic.commandid) { case EMessagePing: iPacketHandlingResult = HandleMessagePing(tInPacket); break; case EMessageVersion: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageVersion(tInPacket); break; case EMessageChallengeReply: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageChallengeReply(tInPacket); break; case EMessageDisconnect: if (!bInUDPSocket) { iPacketHandlingResult = HandleMessageDisconnect(tInPacket); sQuitting = true; sQuitReason = kDisconnectReasonNormal; sQuitMessage = sMessagePoliteGoodbye; } break; case EMessageClientHello: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageClientHello(tInPacket); break; case EMessageClientReady: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageClientReady(tInPacket); break; case EMessageClientRequestSinglePort: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageRequestSinglePort(tInPacket); break; case EMessageClientRequestEvenBasedPortPair: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageRequestEvenBasedPortPair(tInPacket); break; case EMessageClientRequestClosePort: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageRequestClosePort(tInPacket); break; case EMessageClientRequestSendPacket: iPacketHandlingResult = HandleMessageRequestSendPacket(tInPacket); break; case EMessageClientRequestTestUDPRedirectPortCheck: if (bInUDPSocket && !sBoundUDPRedirectAddress) iPacketHandlingResult = HandleMessageClientRequestTestUDPRedirectPortCheck(tInPacket); else iPacketHandlingResult = 1; // a UDP only packet received on TCP is a fatal protocol error break; case EMessageClientRequestBindRedirectPortUDPToIP: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageClientRequestBindRedirectPortUDPToIP(tInPacket); break; case EMessageClientRequestBindTestUDPRedirectPortReply: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageClientRequestBindTestUDPRedirectPortReply(tInPacket); break; case EMessageClientRequestBindUDPRedirectPortPacketForward: if (!bInUDPSocket) iPacketHandlingResult = HandleMessageClientRequestBindUDPRedirectPortPacketForward(tInPacket); break; case EMessageClientRequestXCipherSecureConversationKey: if (!bInUDPSocket) { if (!XCipher::XCipherEnabled()) iPacketHandlingResult = 1; else iPacketHandlingResult = GetXCipher()->HandleMessageClientRequestXCipherSecureConversationKey(tInPacket); } break; // defined for server only // EMessageServerChallenge: // EMessageServerReady: // EMessageServerPortsAvailable: // EMessageServerPacketArrived: // EMessageServerReplyTestUDPRedirectPortCheck: // EMessageServerReplyBindTestUDPRedirectPortReply: // EMessage_ServerToClient_NotifyServerSupport: // EMessage_ServerToClient_ReplyXCipherSecureConversationKey: case EMessage_GlobalXCipherSaysToClearCache: if (XCipher::XCipherEnabled()) iPacketHandlingResult = GetXCipher()->HandleMessageGlobalXCipherSaysToClearCache(tInPacket); else exit(0); break; default:#if DEBUG cout << "X-Tunnels: child " << getpid() << " doesn't understand message " << tInPacket->m_tHeaderBasic.commandid << "!" << endl;#endif //DEBUG iPacketHandlingResult = 1; break; } return iPacketHandlingResult; } int HandleClientPacket(bool bInUDPSocket) { TXTunnelsPacket* pUnencryptedPacket = ReceivePacket( sServerPacketEncryption, bInUDPSocket ? 0 : sClientTCPSocket, bInUDPSocket ? sClientUDPRedirectSocket : 0, &sLastUDPRedirectSource, sBoundUDPRedirectAddress, sBoundUDPRedirectPort, 0, ChildData()->m_szClientDecryptionKey ); if (!pUnencryptedPacket) return HandleClientPacketError(bInUDPSocket); int iPacketHandleResult = DispatchClientPacket( pUnencryptedPacket, bInUDPSocket ); // now they want accounting to not wait until logout SaveClientSessionTraffic(g_tCurrentChildInfo, false); return bInUDPSocket ? 0 : iPacketHandleResult; }int HandleRemotePacket(fd_set* readset) { int packetresult = 0; // should "couldn't find the ready socket" be a fatal error? for (map<long,long>::const_iterator iter = g_cUDPPorts.begin(); iter != g_cUDPPorts.end(); ++iter) { int socket = iter->second; if (FD_ISSET(socket, readset)) { u_port_t fromport = iter->first; u_buf_t ubufp = { 0 }; size_t nbyte = EMaxForwardedDataSize; ssize_t tReceivedDataSize = u_recvfrom(socket, g_tSendingPacket.m_tData.serverpacketarrived.packetblob, nbyte, &ubufp); unsigned long ulSourceIP = ubufp.sin_addr.s_addr; unsigned short sourceport = ubufp.sin_port; if (sClientTCPSocket) { g_tSendingPacket.m_tHeaderBasic.commandid = HOST2XT32(EMessageServerPacketArrived); long lPacketDataSize = sizeof(unsigned short) + sizeof(unsigned long) + sizeof(unsigned short) + sizeof(unsigned long) + tReceivedDataSize; g_tSendingPacket.m_tHeaderBasic.payloadsize = HOST2XT32(lPacketDataSize); g_tSendingPacket.m_tData.serverpacketarrived.fromport = HOST2XT16(fromport); // address is always big, network byte order; packet always wants XTunnels endian (now big as well) g_tSendingPacket.m_tData.serverpacketarrived.sourceip = BIG2XT32(ulSourceIP); g_tSendingPacket.m_tData.serverpacketarrived.sourceport = BIG2XT16(sourceport); g_tSendingPacket.m_tData.serverpacketarrived.packetblobsize = HOST2XT32(tReceivedDataSize); if (ChildData()->SendPacketToClient(&g_tSendingPacket, lPacketDataSize, sForwardPacketsToUDPRedirectPort)) return 1;/*#if DEBUG cout << "X-Tunnels: HandleRemotePacket forwarded " << tReceivedDataSize << " packet data in a " << lPacketDataSize << " byte payload over " << (sForwardPacketsToUDPRedirectPort ? "UDP" : "TCP") << endl;#endif //DEBUG*/ // for our accounting, to be stored in database at quit time LogIncomingPacket(lPacketDataSize); // for real time server stats, reported on request LogDestinationIPIncomingTraffic(ulSourceIP, tReceivedDataSize); } else {#if DEBUG cout << "X-Tunnels: HandleRemotePacket on deathwatch, dropped " << tReceivedDataSize << " packet data on the floor" << endl;#endif //DEBUG } return 0; } }#if DEBUG cout << "X-Tunnels: don't know what select() set!" << endl;#endif //DEBUG return packetresult; }int RunChild(int clientfd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -