InetAddr UDPRawDatagramSocket::getLocalAddr (void) { InetAddr localAddr; struct sockaddr_in saLocal; socklen_t saLen = sizeof (saLocal); if (getsockname (sockfd, (struct sockaddr *) &saLocal, &saLen)) { return localAddr; } localAddr.setIPAddress (saLocal.sin_addr.s_addr); localAddr.setPort (saLocal.sin_port); return localAddr; }
int ProxyDatagramSocket::sendTo (uint32 ui32IPAddr, uint16 ui16Port, const void *pBuf, int iBufSize, const char *pszHints) { int rc; if (_bConnectedToServer) { if (iBufSize < 0) { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_MildError, "packet size cannot be negative\n"); return -1; } if (iBufSize > (MAXIMUM_PROXY_PACKET_SIZE - 17)) { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_MildError, "packet too large to be sent - maximum size is <%d>\n", (int) (MAXIMUM_PROXY_PACKET_SIZE - 17)); return -2; } try { bool bExcludeAddr = false; bool bIncludeAddr = false; InetAddr excludeAddr; InetAddr includeAddr; if (pszHints != NULL) { // Check to see if we can handle the hints StringTokenizer st (pszHints, ';'); const char *pszHint = NULL; while ((pszHint = st.getNextToken()) != NULL) { StringTokenizer st2 (pszHint, '='); const char *pszAttr = st2.getNextToken(); const char *pszValue = st2.getNextToken(); if ((pszAttr == NULL) || (pszValue == NULL)) { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_Warning, "could not parse hint <%s> - ignoring\n", pszHint); } // Check to see if an exclude address has been specified in the hints else if (0 == stricmp (pszAttr, "exclude")) { if (InetAddr::isIPv4Addr (pszValue)) { excludeAddr.setIPAddress (pszValue); bExcludeAddr = true; } else { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_Warning, "could not parse exclude address <%s> - ignoring\n", pszValue); } } // Check to see if an include address has been specified in the hints else if (0 == stricmp (pszAttr, "include")) { if (InetAddr::isIPv4Addr (pszValue)) { includeAddr.setIPAddress (pszValue); bIncludeAddr = true; } else { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_Warning, "could not parse include address <%s> - ignoring\n", pszValue); } } // Check to see if we are doing a forced unicast else if (0 == stricmp (pszAttr, "unicast")) { if (InetAddr::isIPv4Addr (pszValue)) { InetAddr unicastAddr (pszValue); ui32IPAddr = unicastAddr.getIPAddress(); checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_Info, "overwrote destination address with unicast address %s\n", unicastAddr.getIPAsString()); } } else { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_Warning, "unknown hint attribute <%s> - ignoring\n", pszAttr); } } } /*!!*/ // Improve the efficiency of this by implementing a two-argument sendBlock() method // so that a memcpy is not needed uint8 aui8Buf [MAXIMUM_PROXY_PACKET_SIZE]; uint8 ui8Offset = 0; if (bIncludeAddr) { aui8Buf[ui8Offset] = 'I'; } else if (bExcludeAddr) { aui8Buf[ui8Offset] = 'X'; } else { aui8Buf[ui8Offset] = 'D'; } ui8Offset += 1; (*((uint32*)(aui8Buf+ui8Offset))) = _ui32LocalAddr; ui8Offset += 4; (*((uint16*)(aui8Buf+ui8Offset))) = EndianHelper::htons (_ui16LocalPort); ui8Offset += 2; (*((uint32*)(aui8Buf+ui8Offset))) = ui32IPAddr; ui8Offset += 4; if (bIncludeAddr) { (*((uint32*)(aui8Buf+ui8Offset))) = includeAddr.getIPAddress(); ui8Offset += 4; } else if (bExcludeAddr) { (*((uint32*)(aui8Buf+ui8Offset))) = excludeAddr.getIPAddress(); ui8Offset += 4; } (*((uint16*)(aui8Buf+ui8Offset))) = EndianHelper::htons (ui16Port); ui8Offset += 2; memcpy (aui8Buf+ui8Offset, pBuf, iBufSize); _pchToServer->sendBlock (aui8Buf, iBufSize + ui8Offset); _ui32SentPacketCount++; return iBufSize; } catch (Exception e) { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_MildError, "exception occurred when sending data to proxy server; message = <%s>\n", e.getMsg()); close(); rc = -3; } } else { checkAndLogMsg ("ProxyDatagramSocket::sendTo", Logger::L_MildError, "cannot send - not connected to the proxy server\n"); rc = -4; } connectToProxyServer(); return rc; }