int zmq::tcp_address_t::to_string (std::string &addr_) { if (address.generic.sa_family != AF_INET && address.generic.sa_family != AF_INET6) { addr_.clear (); return -1; } // not using service resolv because of https://github.com/zeromq/libzmq/commit/1824574f9b5a8ce786853320e3ea09fe1f822bc4 char hbuf[NI_MAXHOST]; int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL, 0, NI_NUMERICHOST); if (rc != 0) { addr_.clear (); return rc; } if (address.generic.sa_family == AF_INET6) { std::stringstream s; s << "tcp://[" << hbuf << "]:" << ntohs (address.ipv6.sin6_port); addr_ = s.str (); } else { std::stringstream s; s << "tcp://" << hbuf << ":" << ntohs (address.ipv4.sin_port); addr_ = s.str (); }; return 0; }
int zmq::tcp_address_mask_t::to_string (std::string &addr_) { if (address.generic.sa_family != AF_INET && address.generic.sa_family != AF_INET6) { addr_.clear (); return -1; } if (address_mask == -1) { addr_.clear (); return -1; } char hbuf[NI_MAXHOST]; int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof (hbuf), NULL, 0, NI_NUMERICHOST); if (rc != 0) { addr_.clear (); return rc; } if (address.generic.sa_family == AF_INET6) { std::stringstream s; s << "[" << hbuf << "]/" << address_mask; addr_ = s.str (); } else { std::stringstream s; s << hbuf << "/" << address_mask; addr_ = s.str (); }; return 0; }
void so_bind(int fd, int su, unsigned short port, unsigned char *addr) { int i, one; struct sockaddr_storage ss; one = 1; if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){ oserrstr(); print("setsockopt: %r"); } if(su) { for(i = 600; i < 1024; i++) { memset(&ss, 0, sizeof(ss)); ss.ss_family = family(addr); switch(ss.ss_family){ case AF_INET: ((struct sockaddr_in*)&ss)->sin_port = i; break; case AF_INET6: ((struct sockaddr_in6*)&ss)->sin6_port = i; break; } if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0) return; } oserror(); } memset(&ss, 0, sizeof(ss)); ss.ss_family = family(addr); switch(ss.ss_family){ case AF_INET: hnputs(&((struct sockaddr_in*)&ss)->sin_port, port); break; case AF_INET6: hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port); break; } if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); }
void BaseServer::OnNewConnection(EventLoop::Status _status) { if (_status == EventLoop::READ_EVENT) { // The EventLoop indicated that the socket is writable. // Which means that a new client has connected to it. auto endPoint = new ConnectionEndPoint(options_.get_sin_family() != AF_INET); struct sockaddr* serv_addr = endPoint->addr(); socklen_t addrlen = endPoint->addrlen(); sp_int32 fd = accept(listen_fd_, serv_addr, &addrlen); endPoint->set_fd(fd); if (endPoint->get_fd() > 0) { // accept succeeded. // Set defaults if (SockUtils::setSocketDefaults(endPoint->get_fd()) < 0) { close(endPoint->get_fd()); delete endPoint; return; } // Create the connection object and register our callbacks on various events. BaseConnection* conn = CreateConnection(endPoint, &connection_options_, eventLoop_); auto ccb = [conn, this](NetworkErrorCode ec) { this->OnConnectionClose(conn, ec); }; conn->registerForClose(std::move(ccb)); if (conn->start() != 0) { // Connection didn't start properly. Cleanup. // We assume here that this particular connection went bad, so we simply return. LOG(ERROR) << "Could not start the connection for read write"; close(endPoint->get_fd()); delete conn; return; } active_connections_.insert(conn); HandleNewConnection_Base(conn); return; } else { // accept failed. if (errno == EAGAIN) { // This is really odd. We thought that we had a read event LOG(ERROR) << "accept failed with EAGAIN when it should have worked. Ignoring"; } else { LOG(ERROR) << "accept failed with errno " << errno; } close(endPoint->get_fd()); delete endPoint; return; } } else { // What the hell, we only registered ourselves to reading // Just print a warning message LOG(WARNING) << "WARNING while expecting a read event we got " << _status; return; } }
void so_connect(int fd, unsigned char *raddr, unsigned short rport) { struct sockaddr_storage ss; memset(&ss, 0, sizeof(ss)); ss.ss_family = family(raddr); switch(ss.ss_family){ case AF_INET: hnputs(&((struct sockaddr_in*)&ss)->sin_port, rport); v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, raddr); break; case AF_INET6: hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, rport); memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, raddr, sizeof(struct in6_addr)); break; } if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); }
int p9announce(char *addr, char *dir) { int proto; char *buf, *unix; char *net; int port, s; int n; socklen_t sn; struct sockaddr_storage ss; buf = strdup(addr); if(buf == nil) return -1; if(p9dialparse(buf, &net, &unix, &ss, &port) < 0){ free(buf); return -1; } if(strcmp(net, "tcp") == 0) proto = SOCK_STREAM; else if(strcmp(net, "udp") == 0) proto = SOCK_DGRAM; else if(strcmp(net, "unix") == 0) goto Unix; else{ werrstr("can only handle tcp, udp, and unix: not %s", net); free(buf); return -1; } free(buf); if((s = socket(ss.ss_family, proto, 0)) < 0) return -1; sn = sizeof n; if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0 && n == SOCK_STREAM){ n = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n); } if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){ close(s); return -1; } if(proto == SOCK_STREAM){ listen(s, 8); putfd(dir, s); } return s; Unix: if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0) return -1; if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0){ if(errno == EADDRINUSE && connect(s, (struct sockaddr*)&ss, addrlen(&ss)) < 0 && errno == ECONNREFUSED){ /* dead socket, so remove it */ remove(unix); close(s); if((s = socket(ss.ss_family, SOCK_STREAM, 0)) < 0) return -1; if(bind(s, (struct sockaddr*)&ss, addrlen(&ss)) >= 0) goto Success; } close(s); return -1; } Success: listen(s, 8); putfd(dir, s); return s; }
void BaseClient::Start_Base() { if (state_ != DISCONNECTED) { LOG(ERROR) << "Attempting to start a client which is already in state_ " << state_ << "\n"; HandleConnect_Base(DUPLICATE_START); return; } // open a socket int fd = -1; fd = socket(options_.get_socket_family(), SOCK_STREAM, 0); if (fd < 0) { LOG(ERROR) << "Opening of socket failed in Client " << errno << "\n"; HandleConnect_Base(CONNECT_ERROR); return; } // set default socket options if (SockUtils::setSocketDefaults(fd) < 0) { close(fd); HandleConnect_Base(CONNECT_ERROR); return; } // construct an endpoint to store the connection information auto endpoint = new ConnectionEndPoint(options_.get_socket_family() != PF_INET); endpoint->set_fd(fd); bzero(reinterpret_cast<char*>(endpoint->addr()), endpoint->addrlen()); // Set the address if (options_.get_socket_family() == PF_INET) { struct sockaddr_in* addr = (struct sockaddr_in*)endpoint->addr(); addr->sin_family = AF_INET; addr->sin_port = htons(options_.get_port()); struct sockaddr_in t; int error = IpUtils::getAddressInfo(t, options_.get_host().c_str(), PF_INET, SOCK_STREAM); if (error) { LOG(ERROR) << "getaddrinfo failed in Client " << errno << "\n"; close(fd); delete endpoint; HandleConnect_Base(CONNECT_ERROR); return; } memcpy(&(addr->sin_addr), &(t.sin_addr), sizeof(addr->sin_addr)); } else { struct sockaddr_un* addr = (struct sockaddr_un*)endpoint->addr(); addr->sun_family = options_.get_sin_family(); snprintf(addr->sun_path, sizeof(addr->sun_path), "%s", options_.get_sin_path().c_str()); } // connect to the address errno = 0; if (connect(endpoint->get_fd(), endpoint->addr(), endpoint->addrlen()) == 0 || errno == EINPROGRESS) { state_ = CONNECTING; // Either connect succeeded or it woud block auto cb = [endpoint, this](EventLoop::Status status) { this->OnConnect(endpoint, status); }; CHECK_EQ(eventLoop_->registerForWrite(endpoint->get_fd(), std::move(cb), false), 0); return; } else { // connect failed. Bail out saying that the start failed. LOG(ERROR) << "Connect failed " << errno << std::endl; close(endpoint->get_fd()); delete endpoint; HandleConnect_Base(CONNECT_ERROR); return; } }