Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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();
}
Ejemplo n.º 4
0
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;
  }
}
Ejemplo n.º 5
0
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();
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
  }
}