std::string ErrorReporter::addressErrorToString(const Address & address, const std::string & errorString) { std::ostringstream out; out << address.c_str() << ": " << errorString; return out.str(); }
//------------------------------------------------------------------------------------- bool NetworkInterface::recreateListeningSocket(const char* pEndPointName, uint16 listeningPort_min, uint16 listeningPort_max, const char * listeningInterface, EndPoint* pEP, ListenerReceiver* pLR) { KBE_ASSERT(listeningInterface && pEP && pLR); if (pEP->good()) { this->dispatcher().deregisterFileDescriptor(*pEP); pEP->close(); pEP->detach(); } Address address; address.ip = 0; address.port = 0; pEP->socket(SOCK_STREAM); if (!pEP->good()) { ERROR_MSG("NetworkInterface::recreateListeningSocket(%s): couldn't create a socket\n", pEndPointName); return false; } this->dispatcher().registerFileDescriptor(*pEP, pLR); char ifname[IFNAMSIZ]; u_int32_t ifaddr = INADDR_ANY; bool listeningInterfaceEmpty = (listeningInterface == NULL || listeningInterface[0] == 0); // Query kbemachined over the local interface (dev: lo) for what it // believes the internal interface is. if (listeningInterface && (strcmp(listeningInterface, USE_KBEMACHINED) == 0)) { INFO_MSG( "NetworkInterface::recreateListeningSocket(%s): " "Querying KBEMachined for interface\n", pEndPointName); // 没有实现, 向KBEMachined查询接口 } else if (pEP->findIndicatedInterface(listeningInterface, ifname) == 0) { INFO_MSG( "NetworkInterface::recreateListeningSocket(%s): " "Creating on interface '%s' (= %s)\n", pEndPointName, listeningInterface, ifname ); if (pEP->getInterfaceAddress( ifname, ifaddr ) != 0) { WARNING_MSG( "NetworkInterface::recreateListeningSocket(%s): " "Couldn't get addr of interface %s so using all interfaces\n", pEndPointName, ifname ); } } else if (!listeningInterfaceEmpty) { WARNING_MSG( "NetworkInterface::recreateListeningSocket(%s): " "Couldn't parse interface spec '%s' so using all interfaces\n", pEndPointName, listeningInterface ); } bool foundport = false; uint32 listeningPort = listeningPort_min; if(listeningPort_min != listeningPort_max) { for(int lpIdx=ntohs(listeningPort_min); lpIdx<ntohs(listeningPort_max); lpIdx++) { listeningPort = htons(lpIdx); if (pEP->bind(listeningPort, ifaddr) != 0) { continue; } else { foundport = true; break; } } } else { if (pEP->bind(listeningPort, ifaddr) == 0) { foundport = true; } } if(!foundport) { ERROR_MSG("NetworkInterface::recreateListeningSocket(%s): " "Couldn't bind the socket to %s (%s)\n", pEndPointName, address.c_str(), kbe_strerror()); pEP->close(); pEP->detach(); return false; } pEP->getlocaladdress( (u_int16_t*)&address.port, (u_int32_t*)&address.ip ); if (address.ip == 0) { if (pEP->findDefaultInterface(ifname) != 0 || pEP->getInterfaceAddress(ifname, (u_int32_t&)address.ip) != 0) { ERROR_MSG( "NetworkInterface::recreateListeningSocket(%s): " "Couldn't determine ip addr of default interface\n", pEndPointName ); pEP->close(); pEP->detach(); return false; } INFO_MSG( "NetworkInterface::recreateListeningSocket(%s): " "bound to all interfaces with default route " "interface on %s ( %s )\n", pEndPointName, ifname, address.c_str() ); } pEP->setnonblocking(true); pEP->setnodelay(true); pEP->addr(address); #ifdef KBE_SERVER if (!pEP->setBufferSize(SO_RCVBUF, RECV_BUFFER_SIZE)) { WARNING_MSG("NetworkInterface::recreateListeningSocket(%s): " "Operating with a receive buffer of only %d bytes (instead of %d)\n", pEndPointName, pEP->getBufferSize(SO_RCVBUF), RECV_BUFFER_SIZE); } #endif if(pEP->listen(5) == -1) { ERROR_MSG("NetworkInterface::recreateListeningSocket(%s): " "listen to %s (%s)\n", pEndPointName, address.c_str(), kbe_strerror()); pEP->close(); pEP->detach(); return false; } INFO_MSG("NetworkInterface::recreateListeningSocket(%s): address %s\n", pEndPointName, address.c_str()); return true; }
//------------------------------------------------------------------------------------- bool NetworkInterface::recreateListeningSocket(const char* pEndPointName, uint16 listeningPort_min, uint16 listeningPort_max, const char * listeningInterface, EndPoint* pEP, ListenerReceiver* pLR, uint32 rbuffer, uint32 wbuffer) { KBE_ASSERT(listeningInterface && pEP && pLR); if (pEP->good()) { this->dispatcher().deregisterReadFileDescriptor(*pEP); pEP->close(); } Address address; address.ip = 0; address.port = 0; pEP->socket(SOCK_STREAM); if (!pEP->good()) { ERROR_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): couldn't create a socket\n", pEndPointName)); return false; } if (listeningPort_min > 0 && listeningPort_min == listeningPort_max) pEP->setreuseaddr(true); this->dispatcher().registerReadFileDescriptor(*pEP, pLR); u_int32_t ifIPAddr = INADDR_ANY; bool listeningInterfaceEmpty = (listeningInterface == NULL || listeningInterface[0] == 0); // 查找指定接口名 NIP、MAC、IP是否可用 if(pEP->findIndicatedInterface(listeningInterface, ifIPAddr) == 0) { char szIp[MAX_IP] = {0}; Address::ip2string(ifIPAddr, szIp); INFO_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "Creating on interface '{}' (= {})\n", pEndPointName, listeningInterface, szIp)); } // 如果不为空又找不到那么警告用户错误的设置,同时我们采用默认的方式(绑定到INADDR_ANY) else if (!listeningInterfaceEmpty) { WARNING_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "Couldn't parse interface spec '{}' so using all interfaces\n", pEndPointName, listeningInterface)); } // 尝试绑定到端口,如果被占用向后递增 bool foundport = false; uint32 listeningPort = listeningPort_min; if(listeningPort_min != listeningPort_max) { for(int lpIdx=ntohs(listeningPort_min); lpIdx<=ntohs(listeningPort_max); ++lpIdx) { listeningPort = htons(lpIdx); if (pEP->bind(listeningPort, ifIPAddr) != 0) { continue; } else { foundport = true; break; } } } else { if (pEP->bind(listeningPort, ifIPAddr) == 0) { foundport = true; } } // 如果无法绑定到合适的端口那么报错返回,进程将退出 if(!foundport) { ERROR_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "Couldn't bind the socket to {}:{} ({})\n", pEndPointName, inet_ntoa((struct in_addr&)ifIPAddr), ntohs(listeningPort), kbe_strerror())); pEP->close(); return false; } // 获得当前绑定的地址,如果是INADDR_ANY这里获得的IP是0 pEP->getlocaladdress( (u_int16_t*)&address.port, (u_int32_t*)&address.ip ); if (0 == address.ip) { u_int32_t addr; if(0 == pEP->getDefaultInterfaceAddress(addr)) { address.ip = addr; char szIp[MAX_IP] = {0}; Address::ip2string(address.ip, szIp); INFO_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "bound to all interfaces with default route " "interface on {} ( {} )\n", pEndPointName, szIp, address.c_str())); } else { ERROR_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "Couldn't determine ip addr of default interface\n", pEndPointName)); pEP->close(); return false; } } pEP->setnonblocking(true); pEP->setnodelay(true); pEP->addr(address); if(rbuffer > 0) { if (!pEP->setBufferSize(SO_RCVBUF, rbuffer)) { WARNING_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "Operating with a receive buffer of only {} bytes (instead of {})\n", pEndPointName, pEP->getBufferSize(SO_RCVBUF), rbuffer)); } } if(wbuffer > 0) { if (!pEP->setBufferSize(SO_SNDBUF, wbuffer)) { WARNING_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "Operating with a send buffer of only {} bytes (instead of {})\n", pEndPointName, pEP->getBufferSize(SO_SNDBUF), wbuffer)); } } int backlog = Network::g_SOMAXCONN; if(backlog < 5) backlog = 5; if(pEP->listen(backlog) == -1) { ERROR_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): " "listen to {} ({})\n", pEndPointName, address.c_str(), kbe_strerror())); pEP->close(); return false; } INFO_MSG(fmt::format("NetworkInterface::recreateListeningSocket({}): address {}, SOMAXCONN={}.\n", pEndPointName, address.c_str(), backlog)); return true; }