📄 udpstack.cxx
字号:
errMsg << "no route to to destination host"; errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); } break; default: { errMsg << ": " << strerror(err); errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); } } cpLog (LOG_ERR, "UDP send() error: "); errMsg.freeze(false);#if 0 throw UdpStackException(errMsg.str()); assert(0);#endif } else if ( count != length ) { /* int err = errno; */ strstream errMsg; errMsg << "UdpStack<" << getRmtName() << ">:transmit error is send: " << "Asked to transmit " << length << " bytes but only sent " << count ; errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); errMsg.freeze(false);#if 0 throw UdpStackException(errMsg.str()); assert(0);#endif } else { numBytesTransmitted += count; numPacketsTransmitted += 1; } if ( (logFlag) && (count > 0) ) { strstream lenln3; lenln3 << ++sndCount << " " << count << char(0); out_log->write(lenln3.str(), strlen(lenln3.str())); lenln3.freeze(false); strstream rAddress1; rAddress1 << " " << getRmtName() << "\n" << char(0); out_log->write(rAddress1.str(), strlen(rAddress1.str())); rAddress1.freeze(false); out_log->write(buf, count); out_log->write(separator, 6); }}intUdpStack::transmitTo ( const char* buffer, const int length, const NetworkAddress* dest ){ if ((mode == recvonly) || (mode == inactive)) { cpLog(LOG_ERR, "The stack is not capable to transmit. "); return 4; } assert(buffer); assert(length > 0); assert(dest); //SP LockHelper helper(_lock); //SP setDestination(dest); struct sockaddr_storage xDest; memset(&xDest, 0, sizeof(xDest)); dest->getSockAddr(&xDest); int count = sendto( data->socketFd, (char*)buffer, length, 0 , // flags (struct sockaddr*) & xDest, sizeof(struct sockaddr)); if ( count < 0 ) { int err = errno; strstream errMsg; errMsg << "UdpStack<" << getRmtName() << ">::transmitTo "; switch (err) { case ECONNREFUSED: { // This is the most common error - you get it if the host // does not exist or is nor running a program to recevice // the packets. This is what you get with the other side // crashes. errMsg << "Connection refused by destination host"; errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); return 1;#if 0 throw UdpStackExceptionConectionRefused(errMsg.str());#endif } break; case EHOSTDOWN: { errMsg << "destination host is down"; errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); return 2; } break; case EHOSTUNREACH: { errMsg << "no route to to destination host"; errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); return 3; } break; default: { errMsg << ": " << strerror(err); // << " *** " << host; //assert(0); errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); return 3; } } cpLog (LOG_ERR, "UDP sendto() error: "); errMsg.freeze(false);#if 0 throw UdpStackException(errMsg.str()); assert(0);#endif } else if ( count != length ) { // int err = errno; strstream errMsg; errMsg << "UdpStack<" << getRmtName() << ">:transmit error is send: " << "Asked to transmit " << length << " bytes but only sent " << count ; errMsg << char(0); cpLog(LOG_ERR, errMsg.str()); errMsg.freeze(false);#if 0 throw UdpStackException(errMsg.str()); assert(0);#endif } else { numBytesTransmitted += count; numPacketsTransmitted += 1; } if ( (logFlag) && (count > 0) ) { strstream lenln4; lenln4 << ++sndCount << " " << count << char(0); out_log->write(lenln4.str(), strlen(lenln4.str())); lenln4.freeze(false); strstream rAddress2; rAddress2 << " " << getRmtName() << "\n" << char(0); out_log->write(rAddress2.str(), strlen(rAddress2.str())); rAddress2.freeze(false); out_log->write(buffer, count); out_log->write(separator, 6); } return 0;}///voidUdpStack::joinMulticastGroup ( NetworkAddress group, NetworkAddress* iface, int ifaceInexe ){// Previously for win32 platforms this function did nothing// Now it does what it should do using the ip_mreq structure defined// in W32McastCfg.hxx. contact nismail@cisco.com//#ifndef WIN32#if defined(__linux__) if(NetworkConfig::instance().getAddrFamily() == PF_INET) { cpLog(LOG_INFO, "Interface (%s) index (%d) joining multicast group (%s)", iface->getIpName().c_str(), ifaceInexe, group.getIpName().c_str()); struct ip_mreqn mreqn; struct sockaddr_storage groupAddr; group.getSockAddr(&groupAddr); memcpy(&mreqn.imr_multiaddr, &(((struct sockaddr_in*)&groupAddr)->sin_addr), sizeof(struct in_addr)); struct sockaddr_storage intfAddr; iface->getSockAddr(&intfAddr); memcpy(&mreqn.imr_address, &((struct sockaddr_in*)&intfAddr)->sin_addr, sizeof(struct in_addr)); mreqn.imr_ifindex = ifaceInexe; int ret; ret = setsockopt (getSocketFD(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) & mreqn, sizeof(struct ip_mreqn)); if(ret < 0) { cpLog(LOG_ERR, "Failed to join multicast group on interface %s, reason:%s", iface->getIpName().c_str(), strerror(errno)); } else { cpLog(LOG_INFO, "Joined multi-cast group"); } } else { //Join to multi-cast group struct ipv6_mreq mreq6; string mCastGroup("ff13::1"); if(inet_pton(AF_INET6, mCastGroup.c_str(), &mreq6.ipv6mr_multiaddr) < 0) { cpLog(LOG_ERR, "Failed to get the address for multicast group %s", mCastGroup.c_str()); return; } cpLog(LOG_INFO, "Interface (%s) index (%d) joining multicast group (%s)", iface->getIpName().c_str(), ifaceInexe, mCastGroup.c_str()); if(ifaceInexe > 0) { mreq6.ipv6mr_interface = ifaceInexe; } else { mreq6.ipv6mr_interface = 0; } int ret; ret = setsockopt (getSocketFD(), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char*) & mreq6, sizeof(mreq6)); if(ret < 0) { cpLog(LOG_ERR, "Failed to join multicast group on interface %s, reason:%s", iface->getIpName().c_str(), strerror(errno)); } else { cpLog(LOG_INFO, "Joined multi-cast group"); } }#elsestruct ip_mreq mreq; mreq.imr_multiaddr.s_addr = (group.getIp4Address()); mreq.imr_interface.s_addr = (iface->getIp4Address()); // mreq.imr_ifindex = ifaceInexe; int ret; ret = setsockopt (getSocketFD(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) & mreq, sizeof(struct ip_mreq));#endif//#endif // !WIN32}///voidUdpStack::leaveMulticastGroup( NetworkAddress group, NetworkAddress* iface, int ifaceInexe ){// Previously for win32 platforms this function did nothing// Now it does what it should do using the ip_mreq structure defined// in W32McastCfg.hxx. contact nismail@cisco.com//#ifndef WIN32//#ifndef WIN32#if defined(__linux__) struct ip_mreqn mreqn; mreqn.imr_multiaddr.s_addr = (group.getIp4Address()); mreqn.imr_address.s_addr = (iface->getIp4Address()); mreqn.imr_ifindex = ifaceInexe; setsockopt (getSocketFD(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&mreqn, sizeof(struct ip_mreqn));#else struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = (group.getIp4Address()); mreq.imr_interface.s_addr = (iface->getIp4Address()); // mreq.imr_ifindex = ifaceInexe; setsockopt (getSocketFD(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&mreq, sizeof(struct ip_mreq));#endif//#endif // !WIN32}UdpStack::~UdpStack(){ assert(data); if (logFlag) { in_log->close(); out_log->close(); delete in_log; delete out_log; }#ifndef WIN32 close (data->socketFd);#else closesocket(data->socketFd);#endif delete data->localAddr; delete data->remoteAddr; delete data; data = NULL;}intUdpStack::getBytesReceived () const{ return numBytesReceived;}intUdpStack::getPacketsReceived () const{ return numPacketsReceived;}intUdpStack::getBytesTransmitted () const{ return numBytesTransmitted;}intUdpStack::getPacketsTransmitted () const{ return numPacketsTransmitted;}intUdpStack::recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp, struct sockaddr *sa, socklen_t *salenptr, struct in6_pktinfo *pktp){ struct msghdr msg; struct iovec iov[1]; int n; struct cmsghdr *cmptr;#ifndef CMSG_LEN#define CMSG_LEN(size) (sizeof (struct cmsghdr) + (size))#endif#ifndef CMSG_SPACE#define CMSG_SPACE(size) (sizeof (struct cmsghdr) + (size))#endif union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(struct in6_addr)) + CMSG_SPACE(sizeof(struct in6_pktinfo))]; } control_un;#if defined (__SUNPRO_CC) msg.msg_accrights = control_un.control; msg.msg_accrightslen = sizeof(control_un.control);#else msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); msg.msg_flags = 0;#endif msg.msg_name = sa; msg.msg_namelen = *salenptr;#if defined (__FreeBSD__) || defined(__SUNPRO_CC) iov[0].iov_base = reinterpret_cast<char *>(ptr);#else iov[0].iov_base = ptr;#endif iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; if ( (n = recvmsg(fd, &msg, *flagsp)) < 0) { return(n); } *salenptr = msg.msg_namelen; if (pktp) memset(pktp, 0, sizeof(struct in6_pktinfo)); if(flagsp)#if defined (__SUNPRO_CC) if (msg.msg_accrightslen < sizeof(struct cmsghdr) || pktp == NULL) { return(n); }#else *flagsp = msg.msg_flags; /* pass back results */ if (msg.msg_controllen < sizeof(struct cmsghdr) || (msg.msg_flags & MSG_CTRUNC) || pktp == NULL) { return(n); }#endif#if defined(__sparc)/* To maintain backward compatibility, alignment needs to be 8 on sparc. */#ifndef _CMSG_HDR_ALIGNMENT#define _CMSG_HDR_ALIGNMENT 8#endif#endif#ifndef _CMSG_HDR_ALIGN#define _CMSG_HDR_ALIGN(x) (((uintptr_t)(x) + _CMSG_HDR_ALIGNMENT - 1) & \ ~(_CMSG_HDR_ALIGNMENT - 1))#endif#ifndef _CMSG_DATA_ALIGNMENT#define _CMSG_DATA_ALIGNMENT (sizeof (int))#endif#ifndef _CMSG_DATA_ALIGN#define _CMSG_DATA_ALIGN(x) (((uintptr_t)(x) + _CMSG_DATA_ALIGNMENT - 1) & \ ~(_CMSG_DATA_ALIGNMENT - 1))#endif#ifndef CMSG_FIRSTHDR//#define CMSG_FIRSTHDR(size) (sizeof (struct cmsghdr) + (size))#define CMSG_FIRSTHDR(m) ((struct cmsghdr *)((m)->msg_accrights))#endif#ifndef CMSG_DATA#define CMSG_DATA(c) \ ((unsigned char *)_CMSG_DATA_ALIGN((struct cmsghdr *)(c) + 1))#endif#ifndef CMSG_NXTHDR//#define CMSG_NXTHDR(size) (sizeof (struct cmsghdr) + (size))#define CMSG_NXTHDR(m, c) \ ((((uintptr_t)_CMSG_HDR_ALIGN((char *)(c) + \ ((struct cmsghdr *)(c))->cmsg_len) + sizeof (struct cmsghdr)) > \ (((uintptr_t)((struct msghdr *)(m))->msg_accrights) + \ ((uintptr_t)((struct msghdr *)(m))->msg_accrightslen))) ? \ ((struct cmsghdr *)0) : \ ((struct cmsghdr *)_CMSG_HDR_ALIGN((char *)(c) + \ ((struct cmsghdr *)(c))->cmsg_len)))#endif for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL; cmptr = CMSG_NXTHDR(&msg, cmptr)) { if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == IPV6_PKTINFO) { memcpy(&pktp->ipi6_addr, CMSG_DATA(cmptr), sizeof(struct in6_addr)); continue; } cpLog(LOG_DEBUG, "unknown ancillary data, len = %d, level = %d, type = %d", cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type); } return(n);}intUdpStack::setModeBlocking(bool flg){ if(blockingFlg != flg) { blockingFlg = flg; if(blockingFlg) { int flags, fd; fd = getSocketFD(); if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { cpLog(LOG_ERR, "Failed to get block flag, reason:%s", strerror(errno)); return -1; } flags &= ~O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) < 0) { cpLog(LOG_ERR, "Failed to make socket blocking, reason:%s", strerror(errno)); return -1; } } else { int flags, fd; fd = getSocketFD(); if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { cpLog(LOG_ERR, "Failed to get block flag, reason:%s", strerror(errno)); return -1; } flags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) < 0) { cpLog(LOG_ERR, "Failed to make socket non-block, reason:%s", strerror(errno)); return -1; } } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -