Beispiel #1
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;
}
Beispiel #2
0
void Socket::SetClientRemoteAddress(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SetClientRemoteAddress", 0, "remote address not valid", LOG_LEVEL_ERROR);
	}
	m_client_remote_address = ad.GetCopy();
}
Beispiel #3
0
int SctpSocket::RemoveAddress(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
		return -1;
	}
	if (GetSocket() == INVALID_SOCKET)
	{
		Handler().LogError(this, "SctpSocket", -1, "RemoveAddress called with invalid file descriptor", LOG_LEVEL_ERROR);
		return -1;
	}
	int n = sctp_bindx(GetSocket(), ad, ad, SCTP_BINDX_REM_ADDR);
	if (n == -1)
	{
		Handler().LogError(this, "SctpSocket", -1, "sctp_bindx() failed", LOG_LEVEL_ERROR);
	}
	return n;
}
Beispiel #4
0
int SctpSocket::Open(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)
	{
		if (!SetNonblocking(true))
		{
			return -1;
		}
		int n = connect(GetSocket(), ad, ad);
		if (n == -1)
		{
			// check error code that means a connect is in progress
#ifdef _WIN32
			if (Errno == WSAEWOULDBLOCK)
#else
			if (Errno == EINPROGRESS)
#endif
			{
				Handler().LogError(this, "connect: connection pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
				SetConnecting( true ); // this flag will control fd_set's
			}
			else
			{
				Handler().LogError(this, "SctpSocket", -1, "connect() failed", LOG_LEVEL_ERROR);
			}
		}
		return n;
	}
	return -1;
}
Beispiel #5
0
int SctpSocket::AddConnection(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
		return -1;
	}
	if (GetSocket() == INVALID_SOCKET)
	{
		Handler().LogError(this, "SctpSocket", -1, "AddConnection called with invalid file descriptor", LOG_LEVEL_ERROR);
		return -1;
	}
//	int n = sctp_connectx(GetSocket(), ad, ad);
	int n = sctp_connectx(GetSocket(), ad, 1, NULL);
	if (n == -1)
	{
		Handler().LogError(this, "SctpSocket", -1, "sctp_connectx() failed", LOG_LEVEL_ERROR);
	}
	else
	{
		SetConnecting();
	}
	return n;
}
Beispiel #6
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();
}