int UdpSocket::Bind(SocketAddress& ad, int range) { if (GetSocket() == INVALID_SOCKET) { Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); } if (GetSocket() != INVALID_SOCKET) { SetNonblocking(true); int n = bind(GetSocket(), ad, ad); int tries = range; while (n == -1 && tries--) { ad.SetPort(ad.GetPort() + 1); n = bind(GetSocket(), ad, ad); } if (n == -1) { Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL); SetCloseAndDelete(); #ifdef ENABLE_EXCEPTIONS throw Exception("bind() failed for UdpSocket, port:range: " + Utility::l2string(ad.GetPort()) + ":" + Utility::l2string(range)); #endif return -1; } m_bind_ok = true; m_port = ad.GetPort(); return 0; } return -1; }
TEST_F (SocketAddressTest, Set) { SocketAddress sa; ASSERT_TRUE (sa.SetToLocalhost (AF_INET, 1138)); ASSERT_STREQ ("127.0.0.1", sa.GetIPAddress ().c_str ()); ASSERT_EQ (1138, sa.GetPort ()); ASSERT_TRUE (sa.SetToAnyAddress (AF_INET, 0)); ASSERT_STREQ ("0.0.0.0", sa.GetIPAddress ().c_str ()); ASSERT_EQ (0, sa.GetPort ()); ASSERT_TRUE (sa.SetToLocalhost (AF_INET6, 1139)); ASSERT_STREQ ("::1", sa.GetIPAddress ().c_str ()); ASSERT_EQ (1139, sa.GetPort ()); }
int SctpSocket::Bind(SocketAddress& ad) { if (!ad.IsValid()) { Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR); return -1; } if (GetSocket() == INVALID_SOCKET) { Attach(CreateSocket(ad.GetFamily(), m_type, "sctp")); } if (GetSocket() != INVALID_SOCKET) { int n = bind(GetSocket(), ad, ad); if (n == -1) { Handler().LogError(this, "SctpSocket", -1, "bind() failed", LOG_LEVEL_ERROR); #ifdef ENABLE_EXCEPTIONS throw Exception("bind() failed for SctpSocket, port: " + Utility::l2string(ad.GetPort())); #endif } return n; } return -1; }
bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks) { if (!ad.IsValid()) { Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); SetCloseAndDelete(); return false; } if (Handler().GetCount() >= Handler().MaxCount()) { Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL); SetCloseAndDelete(); return false; } SetConnecting(false); #ifdef ENABLE_SOCKS4 SetSocks4(false); #endif // check for pooling #ifdef ENABLE_POOL if (Handler().PoolEnabled()) { ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); if (pools) { CopyConnection( pools ); delete pools; SetIsClient(); SetCallOnConnect(); // ISocketHandler must call OnConnect Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); return true; } } #endif // if not, create new connection SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); if (s == INVALID_SOCKET) { return false; } // socket must be nonblocking for async connect if (!SetNonblocking(true, s)) { SetCloseAndDelete(); closesocket(s); return false; } #ifdef ENABLE_POOL SetIsClient(); // client because we connect #endif SetClientRemoteAddress(ad); int n = 0; if (bind_ad.GetPort() != 0) { bind(s, bind_ad, bind_ad); } #ifdef ENABLE_SOCKS4 if (!skip_socks && GetSocks4Host() && GetSocks4Port()) { Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); { std::string sockshost; Utility::l2ip(GetSocks4Host(), sockshost); Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); } SetSocks4(); n = connect(s, sa, sa); SetRemoteAddress(sa); } else #endif { n = connect(s, ad, ad); SetRemoteAddress(ad); } if (n == -1) { // check error code that means a connect is in progress #ifdef _WIN32 if (Errno == WSAEWOULDBLOCK) #else if (Errno == EINPROGRESS) #endif { Attach(s); SetConnecting( true ); // this flag will control fd_set's } else #ifdef ENABLE_SOCKS4 if (Socks4() && Handler().Socks4TryDirect() ) // retry { closesocket(s); return Open(ad, true); } else #endif #ifdef ENABLE_RECONNECT if (Reconnect()) { Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); Attach(s); SetConnecting( true ); // this flag will control fd_set's } else #endif { Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); SetCloseAndDelete(); closesocket(s); return false; } } else { Attach(s); SetCallOnConnect(); // ISocketHandler must call OnConnect } // 'true' means connected or connecting(not yet connected) // 'false' means something failed return true; //!Connecting(); }