int CSocket::Connect (CIPAddress &rForeignIP, u16 nForeignPort) { if (nForeignPort == 0) { return -1; } assert (m_pTransportLayer != 0); if (m_hConnection >= 0) { if (m_nProtocol != IPPROTO_UDP) { return -1; } m_pTransportLayer->Disconnect (m_hConnection); m_hConnection = -1; } assert (m_pNetConfig != 0); if ( m_pNetConfig->GetIPAddress ()->IsNull () // from null source address && !( m_nProtocol == IPPROTO_UDP // only UDP broadcasts are allowed && rForeignIP.IsBroadcast ())) { return -1; } m_hConnection = m_pTransportLayer->Connect (rForeignIP, nForeignPort, m_nOwnPort, m_nProtocol); return m_hConnection >= 0 ? 0 : m_hConnection; }
int CUDPConnection::SendTo (const void *pData, unsigned nLength, int nFlags, CIPAddress &rForeignIP, u16 nForeignPort) { if (m_nErrno < 0) { int nErrno = m_nErrno; m_nErrno = 0; return nErrno; } if (m_bActiveOpen) { // ignore rForeignIP and nForeignPort return Send (pData, nLength, nFlags); } if ( nFlags != 0 && nFlags != MSG_DONTWAIT) { return -1; } unsigned nPacketLength = sizeof (TUDPHeader) + nLength; // may wrap if ( nPacketLength <= sizeof (TUDPHeader) || nPacketLength > FRAME_BUFFER_SIZE) { return -1; } assert (m_pNetConfig != 0); if ( !m_bBroadcastsAllowed && ( rForeignIP.IsBroadcast () || rForeignIP == *m_pNetConfig->GetBroadcastAddress ())) { return -1; } u8 PacketBuffer[nPacketLength]; TUDPHeader *pHeader = (TUDPHeader *) PacketBuffer; pHeader->nSourcePort = le2be16 (m_nOwnPort); pHeader->nDestPort = le2be16 (nForeignPort); pHeader->nLength = le2be16 (nPacketLength); pHeader->nChecksum = 0; assert (pData != 0); assert (nLength > 0); memcpy (PacketBuffer+sizeof (TUDPHeader), pData, nLength); m_Checksum.SetSourceAddress (*m_pNetConfig->GetIPAddress ()); m_Checksum.SetDestinationAddress (rForeignIP); pHeader->nChecksum = m_Checksum.Calculate (PacketBuffer, nPacketLength); assert (m_pNetworkLayer != 0); boolean bOK = m_pNetworkLayer->Send (rForeignIP, PacketBuffer, nPacketLength, IPPROTO_UDP); return bOK ? nLength : -1; }
int CUDPConnection::PacketReceived (const void *pPacket, unsigned nLength, CIPAddress &rSenderIP, CIPAddress &rReceiverIP, int nProtocol) { if (nProtocol != IPPROTO_UDP) { return 0; } if (nLength <= sizeof (TUDPHeader)) { return -1; } TUDPHeader *pHeader = (TUDPHeader *) pPacket; if (m_nOwnPort != be2le16 (pHeader->nDestPort)) { return 0; } assert (m_pNetConfig != 0); u16 nSourcePort = be2le16 (pHeader->nSourcePort); if (m_bActiveOpen) { if (m_nForeignPort != nSourcePort) { return 0; } if ( m_ForeignIP != rSenderIP && !m_ForeignIP.IsBroadcast () && m_ForeignIP != *m_pNetConfig->GetBroadcastAddress ()) { return 0; } } if (nLength < be2le16 (pHeader->nLength)) { return -1; } if (pHeader->nChecksum != UDP_CHECKSUM_NONE) { m_Checksum.SetSourceAddress (rSenderIP); m_Checksum.SetDestinationAddress (rReceiverIP); if (m_Checksum.Calculate (pPacket, nLength) != CHECKSUM_OK) { return -1; } } if ( !m_bBroadcastsAllowed && ( rReceiverIP.IsBroadcast () || rReceiverIP == *m_pNetConfig->GetBroadcastAddress ())) { return 1; } nLength -= sizeof (TUDPHeader); assert (nLength > 0); TUDPPrivateData *pData = new TUDPPrivateData; assert (pData != 0); rSenderIP.CopyTo (pData->SourceAddress); pData->nSourcePort = nSourcePort; m_RxQueue.Enqueue ((u8 *) pPacket + sizeof (TUDPHeader), nLength, pData); m_Event.Set (); return 1; }