예제 #1
0
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;
}
예제 #2
0
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 ());
}
예제 #3
0
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;
}
예제 #4
0
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();
}