// Functionality: // Send a packet to the given address. // Parameters: // 0) [in] addr: pointer to the destination address. // 1) [in] packet: reference to a CPacket entity. // Returned value: // Actual size of data sent. public int sendto(IPEndPoint addr, CPacket packet) { // convert control information into network order if (packet.getFlag() > 0) for (int i = 0, n = packet.getLength() / 4; i < n; ++ i) *((uint *)packet.m_pcData + i) = htonl(*((uint *)packet.m_pcData + i)); // convert packet header into network order //for (int j = 0; j < 4; ++ j) // packet.m_nHeader[j] = htonl(packet.m_nHeader[j]); uint* p = packet.m_nHeader; for (int j = 0; j < 4; ++ j) { *p = htonl(*p); ++ p; } DWORD size = CPacket.m_iPktHdrSize + packet.getLength(); //int addrsize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); //int res = WSASendTo(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, 0, addr, addrsize, null, null); //int res = m_iSocket.SendTo(Buffer, addr); int res = m_iSocket.SendTo(Buffer, 0, size, SocketFlags.None, addr); res = (0 == res) ? size : -1; // convert back into local host order //for (int k = 0; k < 4; ++ k) // packet.m_nHeader[k] = ntohl(packet.m_nHeader[k]); p = packet.m_nHeader; for (int k = 0; k < 4; ++ k) { *p = ntohl(*p); ++ p; } if (packet.getFlag() > 0) for (int l = 0, n = packet.getLength() / 4; l < n; ++ l) packet.m_pcData[l] = ntohl(packet.m_pcData[l]); return res; }
// Functionality: // Receive a packet from the channel and record the source address. // Parameters: // 0) [in] addr: pointer to the source address. // 1) [in] packet: reference to a CPacket entity. // Returned value: // Actual size of data received. public int recvfrom(IPAddress addr, CPacket packet) { DWORD size = CPacket.m_iPktHdrSize + packet.getLength(); DWORD flag = 0; int addrsize = (AF_INET == m_iIPversion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); int res = WSARecvFrom(m_iSocket, (LPWSABUF)packet.m_PacketVector, 2, &size, &flag, addr, &addrsize, null, null); res = (0 == res) ? size : -1; if (res <= 0) { packet.setLength(-1); return -1; } packet.setLength(res - CPacket.m_iPktHdrSize); // convert back into local host order //for (int i = 0; i < 4; ++ i) // packet.m_nHeader[i] = ntohl(packet.m_nHeader[i]); uint* p = packet.m_nHeader; for (int i = 0; i < 4; ++ i) { *p = ntohl(*p); ++ p; } if (packet.getFlag()) for (int j = 0, n = packet.getLength() / 4; j < n; ++ j) *((uint *)packet.m_pcData + j) = ntohl(*((uint *)packet.m_pcData + j)); return packet.getLength(); }
public static int listen(IPAddress addr, out CPacket packet) { CGuard cg = new CGuard(m_ConnectionLock); if (m_bClosing) return 1002; CHandShake hs = (CHandShake )packet.m_pcData; // SYN cookie byte[] clienthost = new byte[NI_MAXHOST]; byte[] clientport = new byte[NI_MAXSERV]; getnameinfo(addr, (AF_INET == m_iVersion) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6), clienthost, sizeof(clienthost), clientport, sizeof(clientport), NI_NUMERICHOST|NI_NUMERICSERV); Int64 timestamp = (CClock.getTime() - m_StartTime) / 60000000; // secret changes every one minute //byte[] cookiestr = new byte[1024]; //sprintf(cookiestr, "%s:%s:%lld", clienthost, clientport, (long long int)timestamp); string cookiestr = string.Format("{0}:{1}:{2}", clienthost, clientport, timestamp); byte[] cookie = new byte[16]; CMD5.compute(cookiestr, cookie); if (1 == hs.m_iReqType) { hs.m_iCookie = *(int*)cookie; packet.m_iID = hs.m_iID; m_pSndQueue.sendto(addr, packet); return 0; } else { if (hs.m_iCookie != *(int*)cookie) { timestamp --; cookiestr = string.Format("{0}:{1}:{2}", clienthost, clientport, timestamp); CMD5.compute(cookiestr, out cookie); if (hs.m_iCookie != *(int*)cookie) return -1; } } Int32 id = hs.m_iID; // When a peer side connects in... if ((1 == packet.getFlag()) && (0 == packet.getType())) { if ((hs.m_iVersion != m_iVersion) || (hs.m_iType != m_iSockType) || (-1 == s_UDTUnited.newConnection(m_SocketID, addr, hs))) { // couldn't create a new connection, reject the request hs.m_iReqType = 1002; } packet.m_iID = id; m_pSndQueue.sendto(addr, packet); } return hs.m_iReqType; }