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; }
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(); }
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; }
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; }
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; }
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(); }