void Win32Network::attachUDPSocket(SOCKET s,const char* netInterface,int port){
	sockaddr_in address;
	setSocketOption(s,ESocketOption::ESO_NONBLOCK,true);
	setSocketOption(s,ESocketOption::ESO_SOCKOPT_BROADCAST,true);

	if(!netInterface || !netInterface[0] || 
		!strcmp(netInterface,"localhost")){
			//use any available interface
			address.sin_addr.s_addr=htonl(INADDR_ANY);
	}else{
		NetAddress addr;
		inner_getHostAddress(netInterface,addr);
		toSockaddr(addr,(sockaddr*)&address);
	}
	if(!port){
		address.sin_port=0;
	}else{
		address.sin_port=htons((short)port);
	}

	address.sin_family=AF_INET;

	int len=sizeof(address);
	//bind address to the socket
	if(::bind(s,(sockaddr*)&address,len)==-1){
		messages::logMessage(messages::HMSG_BIND,ELL_ERROR);
		return;
	}

}
Ejemplo n.º 2
0
/*! Construct the hardware resource UpnpDiscovery with the given \a parent. */
UpnpDiscovery::UpnpDiscovery(QObject *parent) :
    QUdpSocket(parent)
{
    // bind udp socket and join multicast group
    m_port = 1900;
    m_host = QHostAddress("239.255.255.250");

    setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1));
    setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1));

    if(!bind(QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress)){
        qCWarning(dcHardware) << "UPnP discovery could not bind to port" << m_port;
        return;
    }

    if(!joinMulticastGroup(m_host)){
        qCWarning(dcHardware) << "UPnP discovery could not join multicast group" << m_host;
        return;
    }

    // network access manager for requesting device information
    m_networkAccessManager = new QNetworkAccessManager(this);
    connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, &UpnpDiscovery::replyFinished);

    connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error(QAbstractSocket::SocketError)));
    connect(this, &UpnpDiscovery::readyRead, this, &UpnpDiscovery::readData);

    qCDebug(dcHardware) << "--> UPnP discovery created successfully.";
}
Ejemplo n.º 3
0
bool ProtocolUDP::init_derived()
{	
	int optval = 1;
	char buf[SOCKADDR_SIZE];
        struct sockaddr *sa = (struct sockaddr *)buf;
	socklen_t sa_len;
	SocketAddress *addr = NULL;
	
	if (!localIface) {
	  HAGGLE_ERR("%s Could not create UDP socket, no local interface\n", getName());
                return false;
	}

#if defined(ENABLE_IPv6)
	addr = localIface->getAddress<IPv6Address>();
#endif
	
	if (!addr)
		addr = localIface->getAddress<IPv4Address>();
	
	if (!addr) {
		HAGGLE_ERR("%s Could not create UDP socket, no IP address\n", getName());
                return false;
        }
	
	sa_len = addr->fillInSockaddr(sa);

	if (!openSocket(AF_INET, SOCK_DGRAM, 0, true)) {
		HAGGLE_ERR("%s Could not open UDP socket\n", getName());
                return false;
	}
	// For application IPC socket we need a large receive buffer.
	if (!multiplyReceiveBufferSize(2)) {
		HAGGLE_ERR("%s Could not increase receive buffer size.\n", getName());
	}
	if (!setSocketOption(SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
		closeSocket();
		HAGGLE_ERR("%s setsockopt SO_REUSEADDR failed\n", getName());
                return false;
	}
	
	if (!setSocketOption(SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval))) {
		closeSocket();
		HAGGLE_ERR("%s setsockopt SO_BROADCAST failed\n", getName());
                return false;
	}
	
	if (!bind(sa, sa_len)) {
		closeSocket();
		return false;
	}

	return true;
}
Ejemplo n.º 4
0
int TcpSocketImpl::attachFd(SOCKET_FD fd, uint32_t flags)
{
    KUMA_INFOXTRACE("attachFd, fd="<<fd<<", flags="<<flags<<", state="<<getState());
    if(getState() != ST_IDLE) {
        KUMA_ERRXTRACE("attachFd, invalid state, state="<<getState());
        return KUMA_ERROR_INVALID_STATE;
    }
    flags_ = flags;
#ifndef KUMA_HAS_OPENSSL
    if (SslEnabled()) {
        KUMA_ERRXTRACE("attachFd, OpenSSL is disabled");
        return KUMA_ERROR_UNSUPPORT;
    }
#endif
    
    fd_ = fd;
    setSocketOption();
    setState(ST_OPEN);
#ifdef KUMA_HAS_OPENSSL
    if(SslEnabled()) {
        int ret = startSslHandshake(true);
        if(ret != KUMA_ERROR_NOERR) {
            return ret;
        }
    }
#endif
    loop_->registerFd(fd_, KUMA_EV_NETWORK, [this] (uint32_t ev) { ioReady(ev); });
    registered_ = true;
    return KUMA_ERROR_NOERR;
}
Ejemplo n.º 5
0
void Socket::setLinger(bool activate, USHORT timeout)
{
	linger ln;
	ln.l_linger = timeout;
	ln.l_onoff = activate ? 1 : 0;
	setSocketOption(SO_LINGER, ln);
}
Ejemplo n.º 6
0
int TcpSocketImpl::attachFd(SOCKET_FD fd, SSL* ssl, uint32_t flags)
{
    KUMA_INFOXTRACE("attachFd, with ssl, fd="<<fd<<", flags="<<flags<<", state="<<getState());
    if(getState() != ST_IDLE) {
        KUMA_ERRXTRACE("attachFd, invalid state, state="<<getState());
        return KUMA_ERROR_INVALID_STATE;
    }
    
    fd_ = fd;
    flags_ = flags;
    setSocketOption();
    setState(ST_OPEN);
    
    if(SslEnabled()) {
        if (ssl) {
            ssl_handler_ = new SslHandler();
            ssl_handler_->attachSsl(ssl);
        } else {
            int ret = startSslHandshake(true);
            if(ret != KUMA_ERROR_NOERR) {
                return ret;
            }
        }
    }

    loop_->registerFd(fd_, KUMA_EV_NETWORK, [this] (uint32_t ev) { ioReady(ev); });
    registered_ = true;
    return KUMA_ERROR_NOERR;
}
Ejemplo n.º 7
0
bool CPPTcpServerSocket::listen(short port, int maxConnections){
    std::lock_guard<std::mutex> lockR(recvLock), lockS(sendLock);
    struct sockaddr_in local;
    memset(&local, 0, sizeof(sockaddr_in));
    m_port = port;
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    
    if (!open())
        return false;

    int on=1;
    if (!setSocketOption(SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on), false))
        return false;

    // Bind socket to local address
    if(::bind(m_sock, (struct sockaddr *)&local, sizeof(struct sockaddr_in))==-1) {
        return false;
    }

    // Create queue for client connection requests
    if(::listen(m_sock, maxConnections)==-1) {
        return false;
    }
    
    m_port = port;
    return true;
}
Ejemplo n.º 8
0
void Socket::enableNagleAlgorithm()
{
	// enable nagle's algorithm for TCP
	if ((*m_Socket).getSockType() == TCP) {
		int n = 1;
		setSocketOption(TCP_NODELAY, n, IPPROTO_TCP);
	}
}
Ejemplo n.º 9
0
CGroupClient::CGroupClient(QObject *parent) :
    QTcpSocket(parent)
{
  connectionState = Closed;
  protocolState = Idle;
  setSocketOption(QAbstractSocket::KeepAliveOption, true);
  linkSignals();
}
Ejemplo n.º 10
0
// socket to server
// for WinSock 1
SOCKET NetThread::socketToServer()
{
  SOCKET sock = INVALID_SOCKET;
  struct sockaddr_in addr;

  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;

  char server[512];
  HOSTENT *host;
  unsigned int address;
  int result;
  // server name
  result = snprintf(server, 256, "%s", qPrintable(settings->getServerName()));
  if (result <= 0 || result > 255){
	if (settings->getOutputLog()){
	  const QString text = QString("socketToServer() : snprintf() error! for server");
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
	return INVALID_SOCKET;
  }
  host = gethostbyname(server);
  if (host == 0){
	address = inet_addr(server);
	host = gethostbyaddr((char*)&address, 4, AF_INET);
  }
  if (host == 0){
	return INVALID_SOCKET;
  }

  addr.sin_port = htons(settings->getPortNo());
  addr.sin_addr.s_addr = *((u_long*)host->h_addr);

  sock = socket(AF_INET, SOCK_STREAM, 0);

  result = connect_int(sock, (struct sockaddr *)&addr, sizeof(addr));
  if (result == SOCKET_ERROR){
	sock = INVALID_SOCKET;
  }

  // for socket option
  if (sock != INVALID_SOCKET){
	// set socket option
	setSocketOption(sock);
	// check socket option
	if (outputLog)
	  checkSocketOption(sock);
  }
  else {
	// INVALID_SOCKET
	if (settings->getOutputLog()){
	  const QString text = "socketToServer() : sock = INVALID_SOCKET";
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
  }

  return sock;
}
Ejemplo n.º 11
0
CGroupClient::CGroupClient(QByteArray host, int remotePort, QObject *parent) :
  _host(host), _remotePort(remotePort), QTcpSocket(parent)
{
  linkSignals();
  setSocketOption(QAbstractSocket::KeepAliveOption, true);
  setConnectionState(Connecting);
  protocolState = AwaitingLogin;
  connectToHost(host, remotePort);
}
Ejemplo n.º 12
0
unsigned NetClient::sendData(const void *d, unsigned dataSize) throw (const SocketException &)
{
  unsigned sent = 0;
  const char *dataBuf = static_cast<const char *>(d);
  bool prev_tcpNDelay = m_tcpNDelay;
  
  // turn on nagle for large transfers
  if (dataSize > (unsigned)m_sendBuf) {
    prev_tcpNDelay = m_tcpNDelay;
    setSocketOption(TCPNoDelay, false); // modifies m_tcpNDelay
  }

  while (sent < dataSize)
    sent += Socket::sendData(dataBuf + sent, dataSize - sent);

  // reenable previous no nagle if required
  if (prev_tcpNDelay != m_tcpNDelay) 
    setSocketOption(TCPNoDelay, prev_tcpNDelay);  


  return sent;
}
Ejemplo n.º 13
0
int Socket::bind(const char* host, const int port)
{
	int res = -1;
	if(!isValid())
		return res;
	
	if (-1 == setSocketOption()) {
		return -1;
	}
	
	memset(&_address, 0, sizeof _address);
	_address.sin_family = AF_INET;
	_address.sin_addr.s_addr = host ? inet_addr(host) : htonl(INADDR_ANY);//域名
	_address.sin_port = port ? htons(port) : htons(DEFAULT_PORT);//端口
	res = ::bind(_fd, (struct sockaddr*)&_address, sizeof(_address));
	return res;
}
Ejemplo n.º 14
0
bool ProtocolTCP::initbase()
{
	int optval = 1;
        char buf[SOCKADDR_SIZE];
        struct sockaddr *local_addr = (struct sockaddr *)buf;
        socklen_t addrlen = 0;
        int af = AF_INET;
        unsigned short port = isClient() ? 0 : localport;
	char ip_str[50];
	
        if (!localIface) {
		HAGGLE_ERR("Local interface is NULL\n");
                return false;
        }

	// Check if we are already connected, i.e., we are a client
	// that was created from acceptClient()
	if (isConnected()) {
		// Nothing to initialize
		return true;
	}
        // Figure out the address type based on the local interface
#if defined(ENABLE_IPv6)
	if (localIface->getAddress<IPv6Address>() && peerIface && peerIface->getAddress<IPv6Address>())
                af = AF_INET6;
#endif

        /* Configure a sockaddr for binding to the given port. Do not
         * bind to a specific interface. */
        if (af == AF_INET) {
                struct sockaddr_in *sa = (struct sockaddr_in *)local_addr;
                sa->sin_family = AF_INET;
                sa->sin_addr.s_addr = htonl(INADDR_ANY);
                sa->sin_port = htons(port);
                addrlen = sizeof(struct sockaddr_in);
        }
#if defined(ENABLE_IPv6)
        else if (af == AF_INET6) {
                struct sockaddr_in6 *sa = (struct sockaddr_in6 *)local_addr;
                sa->sin6_family = AF_INET6;
                sa->sin6_len = SOCKADDR_SIZE;
                sa->sin6_addr = in6addr_any;
                sa->sin6_port = htons(port);
                addrlen = sizeof(struct sockaddr_in6);
        }
#endif

	if (!openSocket(local_addr->sa_family, SOCK_STREAM, IPPROTO_TCP, isServer())) {
		HAGGLE_ERR("Could not create TCP socket\n");
                return false;
	}

	if (!setSocketOption(SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
		closeSocket();
		HAGGLE_ERR("setsockopt SO_REUSEADDR failed\n");
                return false;
	}

	if (!setSocketOption(SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval))) {
		closeSocket();
		HAGGLE_ERR("setsockopt SO_KEEPALIVE failed\n");
                return false;
	}

	if (!bind(local_addr, addrlen)) {
		closeSocket();
		HAGGLE_ERR("Could not bind TCP socket\n");
                return false;
        }
	if (inet_ntop(af, &((struct sockaddr_in *)local_addr)->sin_addr, ip_str, sizeof(ip_str))) {
		HAGGLE_DBG("%s Created %s TCP socket - %s:%d\n", 
			   getName(), af == AF_INET ? "AF_INET" : "AF_INET6", ip_str, port);
	}
	return true;
}
Ejemplo n.º 15
0
// socket to server
SOCKET NetThread::socketToServer()
{
  SOCKET sock = INVALID_SOCKET;
  ADDRINFO *addrinfo;
  ADDRINFO addrinfo_hints;

  memset(&addrinfo_hints, 0, sizeof(ADDRINFO));
#if 0 // for TEST
  addrinfo_hints.ai_family = AF_INET; // for IP v4
#else // for TEST
  addrinfo_hints.ai_family = AF_UNSPEC;
#endif // for TEST
  addrinfo_hints.ai_socktype = SOCK_STREAM;

  char server[512];
  char port[16];
  int error;
  int result;
  result = snprintf(server, 256, "%s", qPrintable(settings->getServerName()));
  if (result <= 0 || result > 255){
	if (settings->getOutputLog()){
	  const QString text = QString("socketToServer() : snprintf() error! for server");
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
	return INVALID_SOCKET;
  }
  result = snprintf(port, 10, "%d", settings->getPortNo());
  if (result <= 0 || result > 9){
	if (settings->getOutputLog()){
	  const QString text = QString("socketToServer() : snprintf() error! for port");
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
	return INVALID_SOCKET;
  }
  error = getaddrinfo(server, port, &addrinfo_hints, &addrinfo);
  if (error != 0){
#if defined(QTB_NET_WIN)
	if (settings->getOutputLog()){
	  const QString text = QString("socketToServer() : getaddrinfo(): error = ") + QString::number(error);
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
#elif defined(QTB_NET_UNIX)
	if (settings->getOutputLog()){
	  const QString text = QString("socketToServer() : getaddrinfo(): strerror = ") + gai_strerror(error);
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
#endif // defined(QTB_NET_UNIX)
	return INVALID_SOCKET;
  }

  ADDRINFO *topAddrinfo = addrinfo;
  for (; addrinfo != NULL; addrinfo = addrinfo->ai_next){
#if !defined(Q_OS_WIN) // Portable Vresion (for MacOSX, FreeBSD...)
	sock = connect_retry(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol,
						 addrinfo->ai_addr, (int)addrinfo->ai_addrlen);
	if (sock == INVALID_SOCKET){
	  continue;
	}
#else
	sock = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
	if (sock == INVALID_SOCKET){
	  continue;
	}
	if (connect_retry(sock, addrinfo->ai_addr, (int)addrinfo->ai_addrlen) == SOCKET_ERROR){
	  closesocket(sock);
	  sock = INVALID_SOCKET;
	  continue;
	}
#endif
	break;
  }
  // free all addrinfo
  while(topAddrinfo != NULL){
	addrinfo = topAddrinfo;
	topAddrinfo = addrinfo->ai_next;
	freeaddrinfo(addrinfo);
  }

  // for socket option
  if (sock != INVALID_SOCKET){
	// set socket option
	setSocketOption(sock);
	// check socket option
	if (outputLog)
	  checkSocketOption(sock);
  }
  else {
	// INVALID_SOCKET
	if (settings->getOutputLog()){
	  const QString text = "socketToServer() : sock = INVALID_SOCKET";
	  emit outputLogMessage(PHASE_DEBUG, text);
	}
  }

  return sock;
}
Ejemplo n.º 16
0
void Socket::enableRouting()
{
	DWORD routing = 1;
	setSocketOption(SO_DONTROUTE, routing);
}
Ejemplo n.º 17
0
static void OSNetworkSystem_setSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option, jobject optVal) {
    NetFd fd(env, fileDescriptor);
    if (fd.isClosed()) {
        return;
    }

    int intVal;
    bool wasBoolean = false;
    if (env->IsInstanceOf(optVal, JniConstants::integerClass)) {
        intVal = (int) env->GetIntField(optVal, gCachedFields.integer_class_value);
    } else if (env->IsInstanceOf(optVal, JniConstants::booleanClass)) {
        intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value);
        wasBoolean = true;
    } else if (env->IsInstanceOf(optVal, JniConstants::inetAddressClass)) {
        // We use optVal directly as an InetAddress for IP_MULTICAST_IF.
    } else if (env->IsInstanceOf(optVal, JniConstants::multicastGroupRequestClass)) {
        // We use optVal directly as a MulticastGroupRequest for MCAST_JOIN_GROUP/MCAST_LEAVE_GROUP.
    } else {
        jniThrowSocketException(env, EINVAL);
        return;
    }

    int family = getSocketAddressFamily(fd.get());
    if (family != AF_INET && family != AF_INET6) {
        jniThrowSocketException(env, EAFNOSUPPORT);
        return;
    }

    // Since we expect to have a AF_INET6 socket even if we're communicating via IPv4, we always
    // set the IPPROTO_IP options. As long as we fall back to creating IPv4 sockets if creating
    // an IPv6 socket fails, we need to make setting the IPPROTO_IPV6 options conditional.
    switch (option) {
    case JAVASOCKOPT_IP_TOS:
        setSocketOption(env, fd, IPPROTO_IP, IP_TOS, &intVal);
        if (family == AF_INET6) {
            setSocketOption(env, fd, IPPROTO_IPV6, IPV6_TCLASS, &intVal);
        }
        return;
    case JAVASOCKOPT_SO_BROADCAST:
        setSocketOption(env, fd, SOL_SOCKET, SO_BROADCAST, &intVal);
        return;
    case JAVASOCKOPT_SO_KEEPALIVE:
        setSocketOption(env, fd, SOL_SOCKET, SO_KEEPALIVE, &intVal);
        return;
    case JAVASOCKOPT_SO_LINGER:
        {
            linger l;
            l.l_onoff = !wasBoolean;
            l.l_linger = intVal <= 65535 ? intVal : 65535;
            setSocketOption(env, fd, SOL_SOCKET, SO_LINGER, &l);
            return;
        }
    case JAVASOCKOPT_SO_OOBINLINE:
        setSocketOption(env, fd, SOL_SOCKET, SO_OOBINLINE, &intVal);
        return;
    case JAVASOCKOPT_SO_RCVBUF:
        setSocketOption(env, fd, SOL_SOCKET, SO_RCVBUF, &intVal);
        return;
    case JAVASOCKOPT_SO_REUSEADDR:
        setSocketOption(env, fd, SOL_SOCKET, SO_REUSEADDR, &intVal);
        return;
    case JAVASOCKOPT_SO_SNDBUF:
        setSocketOption(env, fd, SOL_SOCKET, SO_SNDBUF, &intVal);
        return;
    case JAVASOCKOPT_SO_TIMEOUT:
        {
            timeval timeout(toTimeval(intVal));
            setSocketOption(env, fd, SOL_SOCKET, SO_RCVTIMEO, &timeout);
            return;
        }
    case JAVASOCKOPT_TCP_NODELAY:
        setSocketOption(env, fd, IPPROTO_TCP, TCP_NODELAY, &intVal);
        return;
#ifdef ENABLE_MULTICAST
    case JAVASOCKOPT_MCAST_JOIN_GROUP:
        mcastJoinLeaveGroup(env, fd.get(), optVal, true);
        return;
    case JAVASOCKOPT_MCAST_LEAVE_GROUP:
        mcastJoinLeaveGroup(env, fd.get(), optVal, false);
        return;
    case JAVASOCKOPT_IP_MULTICAST_IF:
        {
            sockaddr_storage sockVal;
            if (!env->IsInstanceOf(optVal, JniConstants::inetAddressClass) ||
                    !inetAddressToSocketAddress(env, optVal, 0, &sockVal)) {
                return;
            }
            // This call is IPv4 only. The socket may be IPv6, but the address
            // that identifies the interface to join must be an IPv4 address.
            if (sockVal.ss_family != AF_INET) {
                jniThrowSocketException(env, EAFNOSUPPORT);
                return;
            }
            ip_mreqn mcast_req;
            memset(&mcast_req, 0, sizeof(mcast_req));
            mcast_req.imr_address = reinterpret_cast<sockaddr_in*>(&sockVal)->sin_addr;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &mcast_req);
            return;
        }
    case JAVASOCKOPT_IP_MULTICAST_IF2:
        // TODO: is this right? should we unconditionally set the IPPROTO_IP state in case
        // we have an IPv6 socket communicating via IPv4?
        if (family == AF_INET) {
            // IP_MULTICAST_IF expects a pointer to an ip_mreqn struct.
            ip_mreqn multicastRequest;
            memset(&multicastRequest, 0, sizeof(multicastRequest));
            multicastRequest.imr_ifindex = intVal;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &multicastRequest);
        } else {
            // IPV6_MULTICAST_IF expects a pointer to an integer.
            setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &intVal);
        }
        return;
    case JAVASOCKOPT_MULTICAST_TTL:
        {
            // Although IPv6 was cleaned up to use int, and IPv4 non-multicast TTL uses int,
            // IPv4 multicast TTL uses a byte.
            u_char ttl = intVal;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl);
            if (family == AF_INET6) {
                setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &intVal);
            }
            return;
        }
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        {
            // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
            u_char loopback = intVal;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback);
            if (family == AF_INET6) {
                setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &intVal);
            }
            return;
        }
#else
    case JAVASOCKOPT_MULTICAST_TTL:
    case JAVASOCKOPT_MCAST_JOIN_GROUP:
    case JAVASOCKOPT_MCAST_LEAVE_GROUP:
    case JAVASOCKOPT_IP_MULTICAST_IF:
    case JAVASOCKOPT_IP_MULTICAST_IF2:
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
        return;
#endif // def ENABLE_MULTICAST
    default:
        jniThrowSocketException(env, ENOPROTOOPT);
    }
}
Ejemplo n.º 18
0
int TcpSocketImpl::connect_i(const char* host, uint16_t port, uint32_t timeout)
{
    KUMA_INFOXTRACE("connect_i, host="<<host<<", port="<<port<<", this="<<this);
#ifndef KUMA_HAS_OPENSSL
    if (SslEnabled()) {
        KUMA_ERRXTRACE("connect_i, OpenSSL is disabled");
        return KUMA_ERROR_UNSUPPORT;
    }
#endif
    sockaddr_storage ss_addr = {0};
    struct addrinfo hints = {0};
    hints.ai_family = AF_UNSPEC;
    hints.ai_flags = AI_ADDRCONFIG; // will block 10 seconds in some case if not set AI_ADDRCONFIG
    if(km_set_sock_addr(host, port, &hints, (struct sockaddr*)&ss_addr, sizeof(ss_addr)) != 0) {
        return KUMA_ERROR_INVALID_PARAM;
    }
    if(INVALID_FD == fd_) {
        fd_ = ::socket(ss_addr.ss_family, SOCK_STREAM, 0);
        if(INVALID_FD == fd_) {
            KUMA_ERRXTRACE("connect_i, socket failed, err="<<getLastError());
            return KUMA_ERROR_FAILED;
        }
    }
    setSocketOption();
    
    int addr_len = sizeof(ss_addr);
#ifdef KUMA_OS_MAC
    if(AF_INET == ss_addr.ss_family)
        addr_len = sizeof(sockaddr_in);
    else
        addr_len = sizeof(sockaddr_in6);
#endif
    int ret = ::connect(fd_, (struct sockaddr *)&ss_addr, addr_len);
    if(0 == ret) {
        setState(ST_CONNECTING); // wait for writable event
    } else if(ret < 0 &&
#ifdef KUMA_OS_WIN
              WSAEWOULDBLOCK
#else
              EINPROGRESS
#endif
              == getLastError()) {
        setState(ST_CONNECTING);
    } else {
        KUMA_ERRXTRACE("connect_i, error, fd="<<fd_<<", err="<<getLastError());
        cleanup();
        setState(ST_CLOSED);
        return KUMA_ERROR_FAILED;
    }
#if defined(KUMA_OS_LINUX) || defined(KUMA_OS_MAC)
    socklen_t len = sizeof(ss_addr);
#else
    int len = sizeof(ss_addr);
#endif
    char local_ip[128] = {0};
    uint16_t local_port = 0;
    ret = getsockname(fd_, (struct sockaddr*)&ss_addr, &len);
    if(ret != -1) {
        km_get_sock_addr((struct sockaddr*)&ss_addr, sizeof(ss_addr), local_ip, sizeof(local_ip), &local_port);
    }
    
    KUMA_INFOXTRACE("connect_i, fd="<<fd_<<", local_ip="<<local_ip
                   <<", local_port="<<local_port<<", state="<<getState());
    
    loop_->registerFd(fd_, KUMA_EV_NETWORK, [this] (uint32_t ev) { ioReady(ev); });
    registered_ = true;
    return KUMA_ERROR_NOERR;
}
Ejemplo n.º 19
0
void Socket::disableKeepalive()
{
	DWORD keepAlive = 0;
	setSocketOption(SO_KEEPALIVE, keepAlive);
}
Ejemplo n.º 20
0
void Socket::setOutputTimeout(DWORD timeout)
{
	setSocketOption(SO_SNDTIMEO, timeout);
}
void TMultiplexingServer::run()
{
    // Listen socket
    quint16 port = Tf::app()->appSettings().value("ListenPort").toUInt();
    int sock = TApplicationServerBase::nativeListen(QHostAddress::Any, port);
    if (sock > 0) {
        tSystemDebug("listen successfully.  port:%d", port);
    } else {
        tSystemError("Failed to set socket descriptor: %d", sock);
        TApplicationServerBase::nativeClose(sock);
        return;
    }

    listenSocket = sock;
    setSocketOption(listenSocket);

    maxWorkers = Tf::app()->maxNumberOfServers(10);
    tSystemDebug("MaxWorkers: %d", maxWorkers);

    // Get send buffer size and recv buffer size
    int res, sendBufSize, recvBufSize;
    socklen_t optlen = sizeof(int);
    res = getsockopt(listenSocket, SOL_SOCKET, SO_SNDBUF, &sendBufSize, &optlen);
    if (res < 0)
        tSystemDebug("SO_SNDBUF: %d", sendBufSize);

    res = getsockopt(listenSocket, SOL_SOCKET, SO_RCVBUF, &recvBufSize, &optlen);
    if (res < 0)
        tSystemDebug("SO_RCVBUF: %d", recvBufSize);

    const int MaxEvents = 128;
    struct epoll_event events[MaxEvents];
    sendBufSize *= 0.8;
    char *sndbuffer = new char[sendBufSize];
    char *rcvbuffer = new char[recvBufSize];

    // Create epoll
    epollFd = epoll_create(1);
    if (epollFd < 0) {
        tSystemError("Failed epoll_create()");
        goto socket_error;
    }

    if (epollAdd(listenSocket, EPOLLIN) < 0) {
        tSystemError("Failed epoll_ctl()");
        goto epoll_error;
    }

    for (;;) {
        // Get send-request
        getSendRequest();

        // Check pending requests
        while (!pendingRequests.isEmpty() && (int)threadCounter < maxWorkers) {
            int fd = pendingRequests.takeFirst();
            THttpBuffer &recvbuf = recvBuffers[fd];
            emitIncomingRequest(fd, recvbuf);
        }

        // Poll Sending/Receiving/Incoming
        int timeout = ((int)threadCounter > 0) ? 1 : 100;
        int nfd = tf_epoll_wait(epollFd, events, MaxEvents, timeout);
        int err = errno;
        if (nfd < 0) {
            tSystemError("Failed epoll_wait() : errno:%d", err);
            break;
        }

        for (int i = 0; i < nfd; ++i) {
            if (events[i].data.fd == listenSocket) {
                if (!pendingRequests.isEmpty())
                    continue;

                // Incoming connection
                struct sockaddr_storage addr;
                socklen_t addrlen = sizeof(addr);

                int clt = ::accept(events[i].data.fd, (sockaddr *)&addr, &addrlen);
                if (clt < 0) {
                    tSystemWarn("Failed accept");
                    continue;
                }

                setNonBlocking(clt);
                if (epollAdd(clt, EPOLLIN) == 0) {
                    THttpBuffer &recvbuf = recvBuffers[clt];
                    recvbuf.clear();
                    recvbuf.setClientAddress(QHostAddress((sockaddr *)&addr));
                }

            } else {
                int cltfd = events[i].data.fd;

                if ( (events[i].events & EPOLLIN) ) {
                    // Receive data
                    int len = ::recv(cltfd, rcvbuffer, recvBufSize, 0);
                    err = errno;
                    if (len > 0) {
                        // Read successfully
                        THttpBuffer &recvbuf = recvBuffers[cltfd];
                        recvbuf.write(rcvbuffer, len);

                        if (recvbuf.canReadHttpRequest()) {
                            // Incoming a request
                            if ((int)threadCounter >= maxWorkers) {
                                pendingRequests << cltfd;
                            } else {
                                emitIncomingRequest(cltfd, recvbuf);
                            }
                        }

                    } else {
                        if (len < 0 && err != ECONNRESET) {
                            tSystemError("Failed recv : errno:%d", err);
                        }

                        // Disconnect
                        epollClose(cltfd);
                        continue;
                    }
                }

                if ( (events[i].events & EPOLLOUT) ) {
                    // Send data
                    THttpSendBuffer *sendbuf = sendBuffers[cltfd].first();
                    if (!sendbuf) {
                        tSystemError("Not found send-buffer");
                        epollClose(cltfd);
                        continue;
                    }

                    int len = sendbuf->read(sndbuffer, sendBufSize);
                    int sentlen = ::send(cltfd, sndbuffer, len, 0);
                    err = errno;
                    TAccessLogger &logger = sendbuf->accessLogger();

                    if (sentlen <= 0) {
                        if (err != ECONNRESET) {
                            tSystemError("Failed send : errno:%d", err);
                        }
                        // Access log
                        logger.setResponseBytes(-1);
                        logger.write();

                        epollClose(cltfd);
                        continue;
                    } else {
                        logger.setResponseBytes(logger.responseBytes() + sentlen);

                        if (len > sentlen) {
                            tSystemDebug("sendbuf prepend: len:%d", len - sentlen);
                            sendbuf->prepend(sndbuffer + sentlen, len - sentlen);
                        }

                        if (sendbuf->atEnd()) {
                            logger.write();  // Writes access log
                            sendbuf->release();

                            QQueue<THttpSendBuffer*> &que = sendBuffers[cltfd];
                            delete que.dequeue(); // delete send-buffer obj

                            // Prepare recv
                            if (que.isEmpty())
                                epollModify(cltfd, EPOLLIN);
                        }
                    }
                }
            }
        }

        // Check stop flag
        if (stopped) {
            if (listenSocket > 0) {
                // Close the listen-socket
                epollClose(listenSocket);
                listenSocket = 0;
            }

            if (!recvBuffers.isEmpty()) {
                for (QMapIterator<int, THttpBuffer> it(recvBuffers); it.hasNext(); ) {
                    it.next();
                    epollClose(it.key());
                }
            }

            if (recvBuffers.isEmpty() && sendBuffers.isEmpty()) {
                break;
            }
        }
    }

epoll_error:
    TF_CLOSE(epollFd);
    epollFd = 0;

socket_error:
    if (listenSocket > 0)
        TF_CLOSE(listenSocket);
    listenSocket = 0;
    delete sndbuffer;
    delete rcvbuffer;
}
Ejemplo n.º 22
0
void Socket::setInputTimeout(DWORD timeout)
{
	setSocketOption(SO_RCVTIMEO, timeout);
}