⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pana_udp_transport.h

📁 Diameter协议栈
💻 H
📖 第 1 页 / 共 2 页
字号:
#endiftemplate<int PF>class PANA_EXPORT PANA_Socket : public PANA_IO{    public:        virtual ACE_INT32 open(std::string &iface,                               ACE_INET_Addr &listenAddr) {            m_AdapterInfo.Ifname() = iface;            m_BindAddr = listenAddr;            return m_Socket.open(SOCK_DGRAM, PF, IPPROTO_UDP, 0);        }        virtual ACE_INT32 recv(void *buf,                               size_t n,                               ACE_UINT32 &srcPort,                               PANA_DeviceIdContainer &srcDevices) {            ACE_Handle_Set handle_set;            handle_set.reset();            handle_set.set_bit(m_Socket.get_handle());             // Check the status of the current socket to make sure there's data            // to recv (or time out).            ACE_Time_Value tm(5, 0);            int selectWidth;#if defined (ACE_WIN64) || defined(ACE_WIN32)            // This arg is ignored on Windows and causes pointer truncation            // warnings on 64-bit compiles.            selectWidth = 0;#else            selectWidth = (int)m_Socket.get_handle () + 1;#endif /* ACE_WIN64 */            switch (ACE_OS::select (selectWidth,                                    handle_set,                                    0, 0, &tm)) {                case -1: return -1;                case 0: errno = ETIME; return -1;                default: break;            }            // Read the data            ACE_INET_Addr srcAddr;            sockaddr *saddr = (sockaddr *) srcAddr.get_addr ();            ACE_INT32 addrLen = srcAddr.get_size ();            ACE_INT32 pktLen = ACE_OS::recvfrom(m_Socket.get_handle(),                                                (char*)buf, n, 0,                                                saddr, &addrLen);            if (pktLen > 0) {                                srcAddr.set_size(addrLen);                srcPort = srcAddr.get_port_number();                PANA_DUMP_RXADDR(srcAddr);                PANA_DeviceId *ip = PANA_DeviceIdConverter::CreateFromAddr(srcAddr);                srcDevices.push_back(ip);            }            return (pktLen);        }        virtual ACE_INT32 send(void *buf,                               size_t n,                               ACE_UINT32 destPort,                               PANA_DeviceIdContainer &destDevices) {            PANA_DeviceId *id = PANA_DeviceIdConverter::                                GetIpOnlyAddress(destDevices,                                                 (PF == PF_INET6));            if (id) {                ACE_INET_Addr addr;                PANA_DeviceIdConverter::FormatToAddr(*id, addr);                addr.set_port_number(destPort);		PANA_DUMP_TXADDR(addr);                return (ACE_OS::sendto(m_Socket.get_handle(),                                       (char*)buf, n,                                       0, (sockaddr*)addr.get_addr(),                                       addr.get_size()));            }            return (-1);        }        virtual ACE_INT32 get_local_addr(PANA_DeviceIdContainer &localDevices) {            return m_AdapterInfo.get_local_addr(localDevices);        }        virtual void close() {            m_Socket.close();        }    protected:        ACE_SOCK_IO m_Socket;        ACE_INET_Addr m_BindAddr;        PANA_IfAdapterInfo m_AdapterInfo;};template<int PF>    class PANA_EXPORT PANA_BoundedSocket : public PANA_Socket<PF>{    public:        virtual ACE_INT32 open(std::string &iface,                               ACE_INET_Addr &listenAddr) {            if (PANA_Socket<PF>::open(iface, listenAddr) >= 0) {                if (ACE_OS::bind(PANA_Socket<PF>::m_Socket.get_handle(),                                 (sockaddr*)listenAddr.get_addr(),                                 listenAddr.get_size()) == 0) {                    return 0;                }                ACE_DEBUG((LM_ERROR, "(%P|%t) UDP bind failure\n"));                PANA_Socket<PF>::close();            }            return -1;        }};    #if defined(ACE_HAS_IPV6)template<bool BIND, bool MCAST, bool JOIN>class PANA_EXPORT PANA_UdpIPv6 : public PANA_Socket<PF_INET6>{    public:        virtual ACE_INT32 open(std::string &iface,                               ACE_INET_Addr &listenAddr) {            m_AdapterInfo.Ifname() = iface;            m_BindAddr = listenAddr;            struct addrinfo hints, *res, *ressave;            memset(&hints, 0, sizeof(struct addrinfo));            /*              AI_PASSIVE flag: the resulting address is used to bind              to a socket for accepting incoming connections.              So, when the hostname==NULL, getaddrinfo function will              return one entry per allowed protocol family containing              the unspecified address for that family.            */            hints.ai_flags    = AI_PASSIVE;            hints.ai_family   = AF_INET6;            hints.ai_socktype = SOCK_DGRAM;            char service[32];            ACE_OS::sprintf(service, "%d",                             listenAddr.get_port_number());            if (getaddrinfo(NULL, service,                             &hints, &res) != 0) {                ACE_DEBUG((LM_ERROR, "(%P|%t) Address info failure\n"));                return -1;            }            ressave=res;            /*              Try open socket with each address getaddrinfo returned,              until getting a valid listening socket.             */            try {                while (res) {                    if (m_Socket.open(res->ai_socktype,                                      res->ai_family,                                      res->ai_protocol,                                      0) < 0) {                        res = res->ai_next;                        continue;                    }                    if (BIND && ACE_OS::bind(m_Socket.get_handle(),                                      res->ai_addr,                                      (int)res->ai_addrlen) < 0) {                        ACE_DEBUG((LM_ERROR, "(%P|%t) UDP bind failure\n"));                        throw (1);                    }                    sockaddr_in6 *in6 = (sockaddr_in6*)listenAddr.get_addr();                    if (MCAST && IN6_IS_ADDR_MULTICAST(&in6->sin6_addr) &&                        McastSetup(listenAddr) < 0) {                        throw (1);                    }                    freeaddrinfo(ressave);                    return 0;                }            } catch (...) {            }            close();            freeaddrinfo(ressave);            return -1;        }        virtual ACE_INT32 send(void *buf,                               size_t n,                               ACE_UINT32 destPort,                               PANA_DeviceIdContainer &destDevices) {            PANA_DeviceId *id = PANA_DeviceIdConverter::                                GetIpOnlyAddress(destDevices, true);            if (id) {                sockaddr_in6 daddr;                ACE_OS::memset(&daddr, 0, sizeof(daddr));                daddr.sin6_family = AF_INET6;                daddr.sin6_port = ACE_HTONS(destPort);                ACE_OS::memcpy(&daddr.sin6_addr,                                id->value.data(),                               id->value.size());#if defined(ACE_WIN32)                if (IN6_IS_ADDR_LINKLOCAL(&daddr.sin6_addr)) {#else                if (IN6_IS_ADDR_LINKLOCAL(&daddr.sin6_addr) ||                    IN6_IS_ADDR_MULTICAST(&daddr.sin6_addr)) {#endif                    daddr.sin6_scope_id = m_AdapterInfo.get_adapter_index                                   (          m_AdapterInfo.Ifname().data());                    if (daddr.sin6_scope_id == 0) {                        ACE_DEBUG((LM_ERROR, "(%P|%t) IF index failed to resolve: %s\n",                         m_AdapterInfo.Ifname().data()));                        return -1;                    }                }#if defined(PANA_UDP_ADDR_DEBUG)                ACE_INET_Addr aceAddr;                PANA_DeviceIdConverter::FormatToAddr(*id, aceAddr);                PANA_DUMP_TXADDR(aceAddr);#endif                return (ACE_OS::sendto(m_Socket.get_handle(),                                       (char*)buf, n,                                        0, (sockaddr*)&daddr,                                       sizeof(sockaddr_in6)));            }            return (-1);        }    private:        int McastSetup(ACE_INET_Addr &mcastAddr) {            int hops = 8;            if (m_Socket.set_option(IPPROTO_IPV6,                                     IPV6_MULTICAST_HOPS,                                     &hops,                                     sizeof(hops)) < 0) {                ACE_DEBUG((LM_ERROR, "(%P|%t) Multicast hops option failed\n"));                return -1;            }            int ifindex = m_AdapterInfo.get_adapter_index                (m_AdapterInfo.Ifname().data());            if (ifindex == 0) {                ACE_DEBUG((LM_ERROR, "(%P|%t) Invalid ifname: %s\n",                           m_AdapterInfo.Ifname().data()));                return -1;            }            if (m_Socket.set_option(IPPROTO_IPV6,                                     IPV6_MULTICAST_IF,                                    &ifindex,                                     sizeof(ifindex)) < 0) {                ACE_DEBUG((LM_ERROR, "(%P|%t) Multicast IF option failed\n"));                return -1;             }            if (JOIN) {                struct ipv6_mreq mreq;                sockaddr_in6 *sin = (sockaddr_in6*)mcastAddr.get_addr();                ACE_OS::memcpy(&mreq.ipv6mr_multiaddr,                               &sin->sin6_addr, sizeof(in6_addr));                mreq.ipv6mr_interface = ifindex;                if (m_Socket.set_option(IPPROTO_IPV6,                                         IPV6_JOIN_GROUP,                                        (char *)&mreq,                                         sizeof(mreq)) < 0) {                    ACE_DEBUG((LM_ERROR, "(%P|%t) Multicast join failed: %s\n",                              strerror(errno)));                    return -1;                }            }            return (0);        }};typedef PANA_UdpIPv6<false, true, true> PANA_McastSender;typedef PANA_UdpIPv6<true, true, true>  PANA_McastListener;#if defined(ACE_WIN32)typedef PANA_UdpIPv6<false, true, false> PANA_UdpBoundedSender;#elsetypedef PANA_UdpIPv6<false, true, true> PANA_UdpBoundedSender;#endif#elseclass PANA_EXPORT PANA_McastSender : public PANA_BoundedSocket<PF_INET>{    public:        virtual ACE_INT32 open(std::string &iface,                               ACE_INET_Addr &listenAddr) {            if (PANA_Socket<PF_INET>::open(iface, listenAddr) >= 0) {                return McastIFSetup();            }            return -1;        }    private:        int McastIFSetup() {            PANA_DeviceIdContainer localDevices;            m_AdapterInfo.get_local_addr(localDevices);            PANA_DeviceId *id = PANA_DeviceIdConverter::                                GetIpOnlyAddress(localDevices);            if (id) {                ACE_INET_Addr ifAddr;                PANA_DeviceIdConverter::FormatToAddr(*id, ifAddr);                ip_mreq mcastAddr;                mcastAddr.imr_interface.s_addr =                    htonl(ifAddr.get_ip_address());                if (m_Socket.set_option(IPPROTO_IP,                                         IP_MULTICAST_IF,                                        &mcastAddr.imr_interface.s_addr,                                        sizeof (struct in_addr)) >= 0) {                    return 0;                 }            }            ACE_DEBUG((LM_ERROR, "(%P|%t) Multicast IF option failed\n"));            close();            return -1;        }};class PANA_EXPORT PANA_McastListener : public PANA_BoundedSocket<PF_INET>{    public:        virtual ACE_INT32 open(std::string &iface,                               ACE_INET_Addr &mcastAddr) {            ACE_INET_Addr listenAddr(mcastAddr.get_port_number());            if (PANA_BoundedSocket<PF_INET>::open(iface, listenAddr) >= 0) {                struct ip_mreq mreq;                memset(&mreq, 0, sizeof(mreq));                PANA_DeviceIdContainer localDevices;                m_AdapterInfo.get_local_addr(localDevices);                PANA_DeviceId *id = PANA_DeviceIdConverter::                                    GetIpOnlyAddress(localDevices);                if (id) {                    ACE_INET_Addr ifAddr;                    PANA_DeviceIdConverter::FormatToAddr(*id, ifAddr);                    mreq.imr_interface.s_addr =                        htonl(ifAddr.get_ip_address());                }                else {                    mreq.imr_interface.s_addr = ACE_HTONS(INADDR_ANY);                 }                mreq.imr_multiaddr.s_addr = htonl(mcastAddr.get_ip_address());                if (m_Socket.set_option(IPPROTO_IP,                                         IP_ADD_MEMBERSHIP,                                        (char *)&mreq,                                         sizeof(mreq)) >= 0) {                    return (0);                }                printf("Error: %s\n", strerror(errno));                ACE_DEBUG((LM_ERROR, "(%P|%t) Multicast add membership failed\n"));                close();            }            return -1;        }};typedef PANA_McastSender PANA_UdpBoundedSender;#endif // ACE_HAS_IPV6#endif /* __PANA_UDP_TRANSPORT_H__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -