1 #include "hmbdc/Copyright.hpp" 4 #include "hmbdc/Exception.hpp" 10 #include <netinet/in.h> 11 #include <arpa/inet.h> 14 #include <sys/types.h> 15 #include <sys/socket.h> 18 #include <sys/ioctl.h> 23 namespace hmbdc {
namespace comm {
namespace inet {
32 std::string getLocalIpMatchMask(std::string
const& mask);
33 std::string getLocalIpThruName(std::string
const& name);
34 std::pair<std::string, uint16_t> getPeerIpPort(
int fd);
35 void extractRelicTo(msghdr& to, msghdr
const& from,
int sent);
39 getLocalIpMatchMask(std::string
const& mask) {
40 bool includeLoopback = mask !=
"0.0.0.0/0";
41 auto offset = mask.find(
'/');
43 uint32_t maskLen = 32;
45 if (offset != std::string::npos) {
46 ip_part = mask.substr(0, offset);
47 auto bit_part = mask.substr(offset + 1u);
48 maskLen = atoi(bit_part.c_str());
50 uint32_t targetIp = inet_addr(ip_part.c_str());
51 struct ifaddrs *ifaddr, *ifa;
53 char host[NI_MAXHOST];
55 if (getifaddrs(&ifaddr) == -1) {
56 HMBDC_THROW(std::runtime_error,
" getifaddrs failed ");
59 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
60 if (ifa->ifa_addr == NULL)
63 family = ifa->ifa_addr->sa_family;
65 if (family == AF_INET) {
66 s = getnameinfo(ifa->ifa_addr,
67 sizeof(
struct sockaddr_in),
68 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
70 HMBDC_THROW(std::runtime_error,
" getnameinfo failed ");
73 if (inet_aton(host, &addr)
75 || (targetIp << (32u - maskLen)) == (addr.s_addr << (32u - maskLen)))
76 && (includeLoopback || !(ifa->ifa_flags & IFF_LOOPBACK))) {
78 return std::string(host);
83 HMBDC_THROW(std::runtime_error, mask <<
" does not resolve locally");
88 getLocalIpThruName(std::string
const& name) {
89 struct ifaddrs *ifaddr, *ifa;
91 char host[NI_MAXHOST];
93 if (getifaddrs(&ifaddr) == -1) {
94 HMBDC_THROW(std::runtime_error,
" getifaddrs failed ");
97 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
98 if (ifa->ifa_addr == NULL)
101 family = ifa->ifa_addr->sa_family;
103 if (family == AF_INET
104 && strcmp(name.c_str(), ifa->ifa_name) == 0) {
105 s = getnameinfo(ifa->ifa_addr,
106 sizeof(
struct sockaddr_in),
107 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
109 HMBDC_THROW(std::runtime_error,
" getnameinfo failed ");
111 return std::string(host);
114 HMBDC_THROW(std::runtime_error, name <<
" does not resolve locally");
118 std::pair<std::string, uint16_t>
119 getPeerIpPort(
int fd) {
121 auto addrlen =
sizeof(addr);
122 if (getpeername(fd, &addr, (socklen_t*)&addrlen) == -1) {
123 HMBDC_THROW(std::runtime_error,
"invalid socket errno=" << errno);
125 sockaddr_in* p = (sockaddr_in *)&addr;
126 char ipaddr[INET_ADDRSTRLEN];
127 if (inet_ntop(AF_INET, &(p->sin_addr), ipaddr, INET_ADDRSTRLEN)) {
129 HMBDC_THROW(std::runtime_error,
"no ip addr errno=" << errno);
131 return make_pair(std::string(ipaddr), p->sin_port);
136 extractRelicTo(msghdr& to, msghdr
const& from,
int sent) {
137 auto l = size_t(sent);
139 for (; l > 0 && i < (int)from.msg_iovlen; ++i) {
140 auto& msg = from.msg_iov[i];
141 if (msg.iov_len <= l) {
148 auto& msg = from.msg_iov[i];
149 to.msg_iov[0].iov_base = (
char*)msg.iov_base + l;
150 to.msg_iov[0].iov_len = msg.iov_len - l;
151 auto to_msg_iovlen = from.msg_iovlen - i;
153 memmove(to.msg_iov + 1
154 , from.msg_iov + i + 1
155 , (to_msg_iovlen - 1) *
sizeof(iovec)
157 to.msg_iovlen = to_msg_iovlen;