/*************************************************** Description: TCPServer构造函数,初始化各个模块 Input: loop:时间循环 config:配置内容 Output: 无 Return: 无 ***************************************************/ TCPServer::TCPServer(EventLoop* loop, const Configuration &config) : config_(config), loop_(loop), server_(loop, InetAddress(config.listenPort_), "TCPServer"), jsonMessageServer_(loop, InetAddress(config.jsonListenPort_), "JSONMessageServer"), dispatcher_(loop, tcpCodec_, config.timeout_sec_), tcpCodec_(bind(&Dispatcher::onStringMessage, &dispatcher_, _1, _2, _3, _4)), protoCodec_(), rpcClient_(loop, InetAddress(config.MySQLProxyAddress_, config.MySQLRPCPort_)), messageHandler_(this, &rpcClient_), jsonHandler_(&rpcClient_, this, loop), jsonCodec_(bind(&JsonHandler::onJsonMessage, jsonHandler_, _1, _2)) { server_.setConnectionCallback(bind(&TCPServer::onServerConnection, this, _1)); server_.setMessageCallback(bind(&TCPCodec::onMessage, &tcpCodec_, _1, _2, _3)); //消息编码回调 server_.setThreadNum(config.threadNum_); //设定线程数 jsonMessageServer_.setConnectionCallback(bind(&TCPServer::onJsonConnection, this, _1)); jsonMessageServer_.setMessageCallback(bind(&JsonCodec::onMessage, &jsonCodec_, _1, _2, _3)); //设置各类处理信息的回调函数,派发器利用这些回调函数分发不同消息 dispatcher_.setCallbacks(bind(&MessageHandler::onStatusMessage, &messageHandler_, _1, _2), bind(&MessageHandler::onSensorMessage, &messageHandler_, _1, _2), bind(&MessageHandler::onErrorMessage, &messageHandler_, _1, _2), bind(&MessageHandler::onDevidMessage, &messageHandler_, _1, _2)); }
// ----------------------------------------------------------------------------- // CSdpOriginField::CloneL // Creates an exact copy of the origin field // ----------------------------------------------------------------------------- // EXPORT_C CSdpOriginField* CSdpOriginField::CloneL() const { __TEST_INVARIANT; CSdpOriginField* obj = 0; if ( InetAddress() ) { // Clones instance with TInetAddr TInetAddr addr( *InetAddress() ); obj = CSdpOriginField::NewLC( UserName(), KDummyValue, KDummyValue, addr ); } else { // Clones instance with Internet address as a standard string obj = CSdpOriginField::NewLC( UserName(), KDummyValue, KDummyValue, iNetType, iAddressType, Address() ); } // Set the real values obj->OriginFieldPtrs().SetSessionIdL( OriginFieldPtrs().SessionId() ); obj->OriginFieldPtrs().SetSessionVersionL( OriginFieldPtrs().SessionVersion() ); CleanupStack::Pop( obj ); __ASSERT_DEBUG( *this == *obj, User::Panic( KSdpCodecPanicCat, KSdpCodecPanicInternal ) ); return obj; }
static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap() throw(std::runtime_error) { std::map< Identity,std::vector<InetAddress> > sn; Identity id; std::vector<InetAddress> addrs; // Nothing special about a supernode... except that they are // designated as such. // cthulhu.zerotier.com - New York, New York, USA addrs.clear(); if (!id.fromString("271ee006a0:1:AgGXs3I+9CWrEmGMxc50x3E+trwtaa2ZMXDU6ezz92fFJXzlhRKGUY/uAToHDdH9XiLxtcA+kUQAZdC4Dy2xtqXxjw==:QgH5Nlx4oWEGVrwhNocqem+3VNd4qzt7RLrmuvqZvKPRS9R70LJYJQLlKZj0ri55Pzg+Mlwy4a4nAgfnRAWA+TW6R0EjSmq72MG585XGNfWBVk3LxMvxlNWErnVNFr2BQS9yzVp4pRjPLdCW4RB3dwEHBUgJ78rwMxQ6IghVCl8CjkDapg==")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.73.93",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // nyarlathotep.zerotier.com - San Francisco, California, USA addrs.clear(); if (!id.fromString("fa9be4008b:1:AwCHXEi/PJuhtOPUZxnBSMiuGvj6XeRMWu9R9aLR3JD1qluADLQzUPSP2+81Dqvgi2wkQ2cqEpOlDPeUCvtlZwdXEA==:QgH4usG/wzsoUCtO2LL3qkwugtoXEz1PUJbmUzY8vbwzc5bckmVPjMqb4q2CF71+QVPV1K6shIV2EKkBMRSS/D/44EGEwC6tjFGZqmmogaC0P1uQeukTAF4qta46YgC4YQx54/Vd/Yfl8n1Bwmgm0gBB4W1ZQir3p+wp37MGlEN0rlXxqA==")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // shub-niggurath.zerotier.com - Amsterdam, Netherlands addrs.clear(); if (!id.fromString("48099ecd05:1:AwHO7o1FdDj1nEArfchTDa6EG7Eh2GLdiH86BhcoNv0BHJN4tmrf0Y7/2SZiQFpTTwJf93iph84Dci5+k52u/qkHTQ==:QgGbir8CNxBFFPPj8Eo3Bnp2UmbnZxu/pOq3Ke0WaLBBhHzVuwM+88g7CaDxbZ0AY2VkFc9hmE3VG+xi7g0H86yfVUIBHZnb7N+DCtf8/mphZIHNgmasakRi4hU11kGyLi1nTVTnrmCfAb7w+8SCp64Q5RNvBC/Pvz7pxSwSdjIHkVqRaeo=")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; return sn; }
static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap() { std::map< Identity,std::vector<InetAddress> > sn; Identity id; std::vector<InetAddress> addrs; // Nothing special about a supernode... except that they are // designated as such and trusted to provide WHOIS lookup. // cthulhu.zerotier.com - New York, New York, USA addrs.clear(); if (!id.fromString("8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("162.243.77.111",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // nyarlathotep.zerotier.com - San Francisco, California, USA addrs.clear(); if (!id.fromString("7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // shub-niggurath.zerotier.com - Amsterdam, Netherlands addrs.clear(); if (!id.fromString("36f63d6574:0:67a776487a1a99b32f413329f2b67c43fbf6152e42c6b66e89043e69d93e48314c7d709b58a83016bd2612dd89400b856e18c553da94892f7d3ca16bf2c92c24")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; return sn; }
bool NetworkProxy::init(IOService& service, GameIODataEventHandler* event_handler, uint16 listen_port, uint32 io_thread_numbers) { _service = &service; _event_handler = event_handler; // initialize network // create tcp server instance _server = new TcpServer(InetAddress(listen_port), *_service, io_thread_numbers); // register io data event handler _server->registerNewConnectionEvent( BIND_EVENT_HANDLER(&NetworkProxy::__internalNewConnectionEvent, this)); _server->registerDataWriteFinishedEvent( BIND_EVENT_HANDLER(&NetworkProxy::__internalDataWriteFinishedEvent, this)); _server->registerDataReadEvent( BIND_EVENT_HANDLER(&NetworkProxy::__internalDataReadEvent, this)); _server->registerConnectionClosedEvent( BIND_EVENT_HANDLER(&NetworkProxy::__internalConnectionClosedEvent, this)); // start server _server->start(); return true; }
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) { unsigned int p = startAt; _roots.clear(); if (b[p++] != 0x01) throw std::invalid_argument("invalid World serialized version"); _id = b.template at<uint64_t>(p); p += 8; _ts = b.template at<uint64_t>(p); p += 8; memcpy(_updateSigningKey.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN); p += ZT_C25519_PUBLIC_KEY_LEN; memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; unsigned int numRoots = b[p++]; if (numRoots > ZT_WORLD_MAX_ROOTS) throw std::invalid_argument("too many roots in World"); for(unsigned int k=0;k<numRoots;++k) { _roots.push_back(Root()); Root &r = _roots.back(); p += r.identity.deserialize(b,p); unsigned int numStableEndpoints = b[p++]; if (numStableEndpoints > ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT) throw std::invalid_argument("too many stable endpoints in World/Root"); for(unsigned int kk=0;kk<numStableEndpoints;++kk) { r.stableEndpoints.push_back(InetAddress()); p += r.stableEndpoints.back().deserialize(b,p); } } return (p - startAt); }
InetAddress InetAddress::getPeerAddress(int sockfd) { struct sockaddr_in addr; socklen_t len = sizeof addr; if(::getpeername(sockfd, (SA*)&addr, &len) == -1) ERR_EXIT("getpeername"); return InetAddress(addr); }
void AppBusiness::afterInit() { string ip = iseApp().getArgString(0); int port = 10003; iseApp().tcpConnector().connect(InetAddress(ip, port), boost::bind(&AppBusiness::onConnectComplete, this, _1, _2, _3, _4)); }
InetAddress InetAddress::getLocalAddress(int sockfd) { struct sockaddr_in addr; socklen_t len = sizeof addr; if(::getsockname(sockfd, (SA*)&addr, &len) == -1) { ERR_EXIT("getsockname"); } return InetAddress(addr); }
// ----------------------------------------------------------------------------- // CSdpConnectionField::SetNumOfAddressL // Sets number of addresses // ----------------------------------------------------------------------------- // EXPORT_C void CSdpConnectionField::SetNumOfAddressL( TUint aNumOfAddress ) { const TInetAddr* addr = InetAddress(); if ( aNumOfAddress < 1 || ( !addr && aNumOfAddress != 1 ) || ( addr && !addr->IsMulticast() && aNumOfAddress != 1 ) ) { User::Leave( KErrSdpCodecConnectionField ); } iNumOfAddress = aNumOfAddress; }
int main(int argc, char* argv[]) { google::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); google::InstallFailureSignalHandler(); LOG(INFO) << "glog initialized"; uint16_t port = static_cast<uint16_t>(FLAGS_port); EventLoop loop; zerus::pubsub::PubSubServer server(&loop, InetAddress(port)); server.setThreadNum(8); server.start(); loop.loop(); }
int ConnSvr::OnInit() { if( GetConf()->msglensize() != 4 &&GetConf()->msglensize() != 2 ) { LOG_ERROR("msglensize can only 2 or 4"); return -1; } MsgHandleMgr::Init(); SEpollServer::SetSingleton(new EpollServer(InetAddress("0.0.0.0", m_config.port()), true)); SEpollServer::GetInstance()->Start(); LOG_ERROR("OnInit"); return 0; }
InetAddress Socket::peerAddress(int sockfd) { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); socklen_t len = sizeof(addr); if(-1 == ::getpeername(sockfd, (struct sockaddr*)&addr, &len)) { perror("peerAddress error"); } return InetAddress(addr); }
std::vector<InetAddress> BSDEthernetTap::ips() const { struct ifaddrs *ifa = (struct ifaddrs *)0; if (getifaddrs(&ifa)) return std::vector<InetAddress>(); std::vector<InetAddress> r; struct ifaddrs *p = ifa; while (p) { if ((!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)&&(p->ifa_netmask)&&(p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { switch(p->ifa_addr->sa_family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); } break; case AF_INET6: { struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; uint32_t b[4]; memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); } break; } } p = p->ifa_next; } if (ifa) freeifaddrs(ifa); std::sort(r.begin(),r.end()); std::unique(r.begin(),r.end()); return r; }
// ----------------------------------------------------------------------------- // CSdpOriginField::operator == // Checks if two origin fields are equal // ----------------------------------------------------------------------------- // EXPORT_C TBool CSdpOriginField::operator == ( const CSdpOriginField& aObj) const { __TEST_INVARIANT; TBool equalFields = EFalse; // Check that username, session ID and address type match before // going to internet address if ( ( UserName().CompareF( aObj.UserName() ) == 0 ) && ( SessionId() == aObj.SessionId() ) && ( AddressType() == aObj.AddressType() ) && ( Version() == aObj.Version() ) && ( NetType() == aObj.NetType() ) ) { if ( InetAddress() && aObj.InetAddress() ) { if ( (*InetAddress()).Match( *aObj.InetAddress() ) ) { equalFields = ETrue; } } else if ( !InetAddress() && !aObj.InetAddress() ) { if ( iAddress.CompareF( aObj.Address() ) == 0 ) { equalFields = ETrue; } } else { // These two are not the same } } return equalFields; }
void Network::requestConfiguration() { if (_id == ZT_TEST_NETWORK_ID) // pseudo-network-ID, uses locally generated static config return; if (controller() == RR->identity.address()) { if (RR->localNetworkController) { SharedPtr<NetworkConfig> nconf(config2()); Dictionary newconf; switch(RR->localNetworkController->doNetworkConfigRequest(InetAddress(),RR->identity,RR->identity,_id,Dictionary(),newconf)) { case NetworkController::NETCONF_QUERY_OK: this->setConfiguration(newconf,true); return; case NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND: this->setNotFound(); return; case NetworkController::NETCONF_QUERY_ACCESS_DENIED: this->setAccessDenied(); return; default: return; } } else { this->setNotFound(); return; } } TRACE("requesting netconf for network %.16llx from controller %s",(unsigned long long)_id,controller().toString().c_str()); // TODO: in the future we will include things like join tokens here, etc. Dictionary metaData; metaData.setHex(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,ZEROTIER_ONE_VERSION_MAJOR); metaData.setHex(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,ZEROTIER_ONE_VERSION_MINOR); metaData.setHex(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,ZEROTIER_ONE_VERSION_REVISION); std::string mds(metaData.toString()); Packet outp(controller(),RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST); outp.append((uint64_t)_id); outp.append((uint16_t)mds.length()); outp.append((const void *)mds.data(),(unsigned int)mds.length()); { Mutex::Lock _l(_lock); if (_config) outp.append((uint64_t)_config->revision()); else outp.append((uint64_t)0); } RR->sw->send(outp,true,0); }
InetAddress Socket::getInetAddress() const { sockaddr_in addr; socklen_t addrlen=sizeof(addr); memset(&addr, 0, sizeof(addr)); if (getpeername(*((socket_t*)m_sock), (sockaddr *)&addr, &addrlen)) { int error=errnox; Error_send("Unable to get address with error %d\n", error); } return InetAddress(inet_ntoa(addr.sin_addr)); }
AutoPointer<TCPSocket> TCPServer::accept() { AutoPointer<TCPSocketPrivate> data(new TCPSocketPrivate); struct sockaddr_in sock_peer; socklen_t len = sizeof(sock_peer); data->fd = ::accept(d->fd, reinterpret_cast<sockaddr*>(&sock_peer), &len); if (data->fd < 0) { throw IOException("TCPServer::accept", strerror(errno)); } data->peerAddress.setInetAddress(InetAddress(sock_peer.sin_addr.s_addr)); data->peerAddress.setPort(ntohs(sock_peer.sin_port)); return AutoPointer<TCPSocket>(new TCPSocket(data.release())); }
int DatagramSocket::read(DatagramPacket &pkt) { int numbytes; sockaddr_in addr; socklen_t addr_len=sizeof(addr); if ((numbytes=recvfrom(*((socket_t*)m_sock), (char *)pkt.getBuffer().getData(), pkt.getBuffer().getLength(), 0, (sockaddr *)&addr, &addr_len)) == -1) { Error_send("Unable to receive packet from UDP socket\n"); } pkt.setPort(addr.sin_port); pkt.setAddress(InetAddress(inet_ntoa(addr.sin_addr))); pkt.setLength(numbytes); return numbytes; }
void Topology::setRootServers(const Dictionary &sn) { std::map< Identity,std::vector<InetAddress> > m; for(Dictionary::const_iterator d(sn.begin());d!=sn.end();++d) { if ((d->first.length() == ZT_ADDRESS_LENGTH_HEX)&&(d->second.length() > 0)) { try { Dictionary snspec(d->second); std::vector<InetAddress> &a = m[Identity(snspec.get("id"))]; std::string udp(snspec.get("udp",std::string())); if (udp.length() > 0) a.push_back(InetAddress(udp)); } catch ( ... ) { TRACE("root server list contained invalid entry for: %s",d->first.c_str()); } } } this->setRootServers(m); }
// ----------------------------------------------------------------------------- // CSdpConnectionField::CloneL // Clones an exact copy of this object // ----------------------------------------------------------------------------- // EXPORT_C CSdpConnectionField* CSdpConnectionField::CloneL() const { __TEST_INVARIANT; CSdpConnectionField* obj = NULL; const TInetAddr* addr = InetAddress(); if ( addr ) { // Could be anything obj = CSdpConnectionField::NewL( *addr, iTTL, iNumOfAddress ); } else { // Unicast FQDN address obj = CSdpConnectionField::NewL( iNetType, iAddressType, *iAddress ); } __ASSERT_DEBUG( *this == *obj, User::Panic( KSdpCodecPanicCat, KSdpCodecPanicInternal)); return obj; }
inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) { unsigned int p = startAt; _roots.clear(); switch((Type)b[p++]) { case TYPE_NULL: _type = TYPE_NULL; break; // shouldn't ever really happen in serialized data but it's not invalid case TYPE_PLANET: _type = TYPE_PLANET; break; case TYPE_MOON: _type = TYPE_MOON; break; default: throw std::invalid_argument("invalid world type"); } _id = b.template at<uint64_t>(p); p += 8; _ts = b.template at<uint64_t>(p); p += 8; memcpy(_updatesMustBeSignedBy.data,b.field(p,ZT_C25519_PUBLIC_KEY_LEN),ZT_C25519_PUBLIC_KEY_LEN); p += ZT_C25519_PUBLIC_KEY_LEN; memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN); p += ZT_C25519_SIGNATURE_LEN; const unsigned int numRoots = (unsigned int)b[p++]; if (numRoots > ZT_WORLD_MAX_ROOTS) throw std::invalid_argument("too many roots in World"); for(unsigned int k=0;k<numRoots;++k) { _roots.push_back(Root()); Root &r = _roots.back(); p += r.identity.deserialize(b,p); unsigned int numStableEndpoints = b[p++]; if (numStableEndpoints > ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT) throw std::invalid_argument("too many stable endpoints in World/Root"); for(unsigned int kk=0;kk<numStableEndpoints;++kk) { r.stableEndpoints.push_back(InetAddress()); p += r.stableEndpoints.back().deserialize(b,p); } } if (_type == TYPE_MOON) p += b.template at<uint16_t>(p) + 2; return (p - startAt); }
int util_server_test(int argc, char *argv[]) { GetDefaultLogMgr().AddFileCat(LOGLV_FATAL, LOGLV_FATAL, 20*1024*1024, 5, "server", "log"); EPollPoller poll; poll.InitEpoll(); MyServer server(poll, InetAddress("0.0.0.0", 7789), true); //client.Connect(); server.Start(); gettimeofday(&starttime, NULL); while(1) { poll.Poll(1000); //printf("poll\n"); } return 0; }
// ----------------------------------------------------------------------------- // CSdpConnectionField::SetTTLL // Sets new TTL attribute value, leaves on error // ----------------------------------------------------------------------------- // EXPORT_C void CSdpConnectionField::SetTTLL( TInt aTTL ) { __TEST_INVARIANT; const TInetAddr* addr = InetAddress(); // FQDN; Unicast, can be only KErrNotFound // IP4 Multicast: 0 <= TTL <= 255 // IP4 Unicast, can be only KErrNotFound // IP6 can be only KErrNotFound if ( ( !addr && aTTL != KErrNotFound ) || ( addr && addr->Address() && addr->IsMulticast() && ( aTTL < 0 || aTTL > 255 ) ) || ( addr && addr->Address() && !addr->IsMulticast() && aTTL != KErrNotFound ) || ( addr && !addr->Address() && aTTL != KErrNotFound ) ) { User::Leave( KErrSdpCodecConnectionField ); } iTTL = aTTL; }
void Http::Request::main() throw() { char buf[131072]; try { http_parser_init(&_parser,HTTP_RESPONSE); _parser.data = this; http_parser_url urlParsed; if (http_parser_parse_url(_url.c_str(),_url.length(),0,&urlParsed)) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL parse error"); return; } if (!(urlParsed.field_set & (1 << UF_SCHEMA))) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL specifies no schema"); return; } std::string schema(_url.substr(urlParsed.field_data[UF_SCHEMA].off,urlParsed.field_data[UF_SCHEMA].len)); if (schema == "file") { const std::string filePath(_url.substr(urlParsed.field_data[UF_PATH].off,urlParsed.field_data[UF_PATH].len)); uint64_t lm = Utils::getLastModified(filePath.c_str()); if (lm) { const std::map<std::string,std::string>::const_iterator ifModSince(_requestHeaders.find("If-Modified-Since")); if ((ifModSince != _requestHeaders.end())&&(ifModSince->second.length())) { uint64_t t64 = Utils::fromRfc1123(ifModSince->second); if ((t64)&&(lm > t64)) { suicidalThread = !_handler(this,_arg,_url,304,_responseHeaders,""); return; } } if (Utils::readFile(filePath.c_str(),_responseBody)) { _responseHeaders["Last-Modified"] = Utils::toRfc1123(lm); suicidalThread = !_handler(this,_arg,_url,200,_responseHeaders,_responseBody); return; } } suicidalThread = !_handler(this,_arg,_url,404,_responseHeaders,"file not found or not readable"); return; } else if (schema == "http") { if (!(urlParsed.field_set & (1 << UF_HOST))) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL contains no host"); return; } std::string host(_url.substr(urlParsed.field_data[UF_HOST].off,urlParsed.field_data[UF_HOST].len)); std::list<InetAddress> v4,v6; { struct addrinfo *res = (struct addrinfo *)0; if (!getaddrinfo(host.c_str(),(const char *)0,(const struct addrinfo *)0,&res)) { struct addrinfo *p = res; do { if (p->ai_family == AF_INET) v4.push_back(InetAddress(p->ai_addr)); else if (p->ai_family == AF_INET6) v6.push_back(InetAddress(p->ai_addr)); } while ((p = p->ai_next)); freeaddrinfo(res); } } std::list<InetAddress> *addrList; if (v4.empty()&&v6.empty()) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"could not find address for host in URL"); return; } else if (v4.empty()) { addrList = &v6; } else { addrList = &v4; } InetAddress *addr; { addrList->sort(); addrList->unique(); unsigned int i = 0,k = 0; k = Utils::randomInt<unsigned int>() % addrList->size(); std::list<InetAddress>::iterator a(addrList->begin()); while (i++ != k) ++a; addr = &(*a); } int remotePort = ((urlParsed.field_set & (1 << UF_PORT))&&(urlParsed.port)) ? (int)urlParsed.port : (int)80; if ((remotePort <= 0)||(remotePort > 0xffff)) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL port out of range"); return; } addr->setPort(remotePort); _fd = socket(addr->isV6() ? AF_INET6 : AF_INET,SOCK_STREAM,0); if (_fd <= 0) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"could not open socket"); return; } for(;;) { if (connect(_fd,addr->saddr(),addr->saddrLen())) { if (errno == EINTR) continue; ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"connection failed to remote host"); return; } else break; } const char *mstr = "GET"; switch(_method) { case HTTP_METHOD_HEAD: mstr = "HEAD"; break; default: break; } int mlen = (int)snprintf(buf,sizeof(buf),"%s %s HTTP/1.1\r\nAccept-Encoding: \r\nHost: %s\r\n",mstr,_url.substr(urlParsed.field_data[UF_PATH].off,urlParsed.field_data[UF_PATH].len).c_str(),host.c_str()); if (mlen >= (int)sizeof(buf)) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL too long"); return; } if (!_sendAll(_fd,buf,mlen)) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"write error"); return; } for(std::map<std::string,std::string>::const_iterator rh(_requestHeaders.begin());rh!=_requestHeaders.end();++rh) { mlen = (int)snprintf(buf,sizeof(buf),"%s: %s\r\n",rh->first.c_str(),rh->second.c_str()); if (mlen >= (int)sizeof(buf)) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"header too long"); return; } if (!_sendAll(_fd,buf,mlen)) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"write error"); return; } } if (!_sendAll(_fd,"\r\n",2)) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"write error"); return; } _responseStatusCode = 0; _messageComplete = false; for(;;) { mlen = (int)::recv(_fd,buf,sizeof(buf),0); if (mlen < 0) { if (errno != EINTR) break; else continue; } if (((int)http_parser_execute(&_parser,&_http_parser_settings,buf,mlen) != mlen)||(_parser.upgrade)) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"invalid HTTP response from server"); return; } if (_messageComplete) { ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,_responseStatusCode,_responseHeaders,_responseBody); return; } } ::close(_fd); _fd = 0; suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"empty HTTP response from server"); return; } else { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"only 'file' and 'http' methods are supported"); return; } } catch ( ... ) { suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"unexpected exception retrieving URL"); return; } }
void NetworkConfig::_fromDictionary(const Dictionary &d) { static const std::string zero("0"); static const std::string one("1"); // NOTE: d.get(name) throws if not found, d.get(name,default) returns default _nwid = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID).c_str()); if (!_nwid) throw std::invalid_argument("configuration contains zero network ID"); _timestamp = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP).c_str()); _revision = Utils::hexStrToU64(d.get(ZT_NETWORKCONFIG_DICT_KEY_REVISION,"1").c_str()); // older controllers don't send this, so default to 1 memset(_etWhitelist,0,sizeof(_etWhitelist)); std::vector<std::string> ets(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES).c_str(),",","","")); for(std::vector<std::string>::const_iterator et(ets.begin());et!=ets.end();++et) { unsigned int tmp = Utils::hexStrToUInt(et->c_str()) & 0xffff; _etWhitelist[tmp >> 3] |= (1 << (tmp & 7)); } _issuedTo = Address(d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO)); _multicastLimit = Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,zero).c_str()); if (_multicastLimit == 0) _multicastLimit = ZT_MULTICAST_DEFAULT_LIMIT; _allowPassiveBridging = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING,zero).c_str()) != 0); _private = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_PRIVATE,one).c_str()) != 0); _enableBroadcast = (Utils::hexStrToUInt(d.get(ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST,one).c_str()) != 0); _name = d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME); if (_name.length() > ZT1_MAX_NETWORK_SHORT_NAME_LENGTH) throw std::invalid_argument("network short name too long (max: 255 characters)"); _description = d.get(ZT_NETWORKCONFIG_DICT_KEY_DESC,std::string()); // In dictionary IPs are split into V4 and V6 addresses, but we don't really // need that so merge them here. std::string ipAddrs(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC,std::string())); { std::string v6s(d.get(ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC,std::string())); if (v6s.length()) { if (ipAddrs.length()) ipAddrs.push_back(','); ipAddrs.append(v6s); } } std::vector<std::string> ipAddrsSplit(Utils::split(ipAddrs.c_str(),",","","")); for(std::vector<std::string>::const_iterator ipstr(ipAddrsSplit.begin());ipstr!=ipAddrsSplit.end();++ipstr) { InetAddress addr(*ipstr); switch(addr.ss_family) { case AF_INET: if ((!addr.netmaskBits())||(addr.netmaskBits() > 32)) continue; break; case AF_INET6: if ((!addr.netmaskBits())||(addr.netmaskBits() > 128)) continue; break; default: // ignore unrecognized address types or junk/empty fields continue; } _staticIps.push_back(addr); } if (_staticIps.size() > ZT1_MAX_ZT_ASSIGNED_ADDRESSES) throw std::invalid_argument("too many ZT-assigned IP addresses"); std::sort(_staticIps.begin(),_staticIps.end()); std::unique(_staticIps.begin(),_staticIps.end()); std::vector<std::string> activeBridgesSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES,"").c_str(),",","","")); for(std::vector<std::string>::const_iterator a(activeBridgesSplit.begin());a!=activeBridgesSplit.end();++a) { if (a->length() == ZT_ADDRESS_LENGTH_HEX) { // ignore empty or garbage fields Address tmp(*a); if (!tmp.isReserved()) _activeBridges.push_back(tmp); } } std::sort(_activeBridges.begin(),_activeBridges.end()); std::unique(_activeBridges.begin(),_activeBridges.end()); Dictionary multicastRateEntries(d.get(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_RATES,std::string())); for(Dictionary::const_iterator i(multicastRateEntries.begin());i!=multicastRateEntries.end();++i) { std::vector<std::string> params(Utils::split(i->second.c_str(),",","","")); if (params.size() >= 3) _multicastRates[MulticastGroup(i->first)] = MulticastRate(Utils::hexStrToUInt(params[0].c_str()),Utils::hexStrToUInt(params[1].c_str()),Utils::hexStrToUInt(params[2].c_str())); } std::vector<std::string> relaysSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_RELAYS,"").c_str(),",","","")); for(std::vector<std::string>::const_iterator r(relaysSplit.begin());r!=relaysSplit.end();++r) { std::size_t semi(r->find(';')); // address;ip/port,... if (semi == ZT_ADDRESS_LENGTH_HEX) { std::pair<Address,InetAddress> relay( Address(r->substr(0,semi)), ((r->length() > (semi + 1)) ? InetAddress(r->substr(semi + 1)) : InetAddress()) ); if ((relay.first)&&(!relay.first.isReserved())) _relays.push_back(relay); } } std::sort(_relays.begin(),_relays.end()); std::unique(_relays.begin(),_relays.end()); _com.fromString(d.get(ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP,std::string())); }
void TCPServer::listen(port_t port) { listen(SocketAddress(InetAddress(), port)); }
void IPIDCollector::run() { // Avoids probing null IPs (routing artifacts) if(this->target == InetAddress("0.0.0.0")) return; IPLookUpTable *table = env->getIPTable(); IPTableEntry *targetEntry = table->lookUp(this->target); // Necessarily exists (see AliasHintCollector.cpp) unsigned short nbThreads = env->getNbIPIDs(); unsigned short maxThreads = env->getMaxThreads(); // For range (see below) // Just in case (normally, should not occur, as stated above) if(targetEntry == NULL) return; /* * N.B.: since AliasHintCollector takes care of scheduling with respect to the maximum amount * of threads allowed by the user, this class does neither check nbThreads nor performs a * circular visit of the thread array. */ // Initializes an array of threads Thread **th = new Thread*[nbThreads]; for(unsigned short i = 0; i < nbThreads; i++) th[i] = NULL; // Starts spawning threads unsigned short range = (DirectProber::DEFAULT_UPPER_SRC_PORT_ICMP_ID - DirectProber::DEFAULT_LOWER_SRC_PORT_ICMP_ID) / maxThreads; for(unsigned long int i = 0; i < nbThreads; i++) { unsigned short trueOffset = this->offset + i; th[i] = new Thread(new IPIDUnit(this->env, this->parent, this->target, DirectProber::DEFAULT_LOWER_SRC_PORT_ICMP_ID + (trueOffset * range), DirectProber::DEFAULT_LOWER_SRC_PORT_ICMP_ID + (trueOffset * range) + range - 1, DirectProber::DEFAULT_LOWER_DST_PORT_ICMP_SEQ, DirectProber::DEFAULT_UPPER_DST_PORT_ICMP_SEQ)); th[i]->start(); // 0,01s of delay before next thread Thread::invokeSleep(TimeVal(0, 10000)); } // Waiting for all threads to complete and getting token, IP-ID, time value tuples list<IPIDTuple*> tuples; for(unsigned short i = 0; i < nbThreads; i++) { if(th[i] != NULL) { th[i]->join(); IPIDUnit *curUnit = (IPIDUnit*) th[i]->getRunnable(); if(curUnit->hasExploitableResults()) { tuples.push_back(curUnit->getTuple()); } delete th[i]; th[i] = NULL; } } // Sorts and stores collected data in targetEntry tuples.sort(IPIDTuple::compare); unsigned short index = 0; unsigned char inferredInitialTTL = 0; bool differentTTLs = false; while(tuples.size() > 0) { IPIDTuple *cur = tuples.front(); tuples.pop_front(); targetEntry->setProbeToken(index, cur->probeToken); targetEntry->setIPIdentifier(index, cur->IPID); if(cur->echo) targetEntry->setEcho(index); // Only if the same initial TTL was observed on every previous tuple if(!differentTTLs) { // Infers initial TTL value of the reply packet for the current tuple unsigned char initialTTL = 0; unsigned short replyTTLAsShort = (unsigned short) cur->replyTTL; if(replyTTLAsShort > 128) initialTTL = (unsigned char) 255; else if(replyTTLAsShort > 64) initialTTL = (unsigned char) 128; else if(replyTTLAsShort > 32) initialTTL = (unsigned char) 64; else initialTTL = (unsigned char) 32; // Checks if distinct initial TTLs are observed (it should always be the same) if(inferredInitialTTL == 0) { inferredInitialTTL = initialTTL; } else if(inferredInitialTTL != initialTTL) { differentTTLs = true; } } // Computes delay with next entry (no pop_front() this time) if(tuples.size() > 0) { IPIDTuple *next = tuples.front(); unsigned long time1, time2; time1 = cur->timeValue.tv_sec * 1000000 + cur->timeValue.tv_usec; time2 = next->timeValue.tv_sec * 1000000 + next->timeValue.tv_usec; unsigned long delay = time2 - time1; targetEntry->setDelay(index, delay); } // Frees memory used by current tuple and moves on delete cur; index++; } if(inferredInitialTTL > 0 && !differentTTLs) targetEntry->setEchoInitialTTL(inferredInitialTTL); delete[] th; // We're done with this IP. }