return;
}
- m_Socket = SocketAndConnectResolved(Remote, Bind);
+ int ErrorCode;
+ m_Socket = SocketAndConnectResolved(Remote, Bind, &ErrorCode);
free(m_HostAddr);
m_HostAddr = NULL;
if (m_Socket == INVALID_SOCKET) {
- int ErrorCode;
-
- ErrorCode = errno;
-
#ifndef _WIN32
if (ErrorCode == 0) {
ErrorCode = -1;
* @param Response the response
*/
void CConnection::AsyncDnsFinished(hostent *Response) {
- if (Response == NULL) {
+ if (Response == NULL || Response->h_addr_list[0] == NULL) {
// we cannot destroy the object here as there might still be the other
// dns query (bind ip) in the queue which would get destroyed in the
// destructor; this causes a crash in the StartMainLoop() function
m_LatchedDestruction = true;
- } else {
- int Size;
- m_Family = Response->h_addrtype;
-
- if (Response->h_addrtype == AF_INET) {
- Size = sizeof(in_addr);
- } else if (Response->h_addrtype == AF_INET6) {
- Size = sizeof(in6_addr);
- } else {
- m_LatchedDestruction = true;
-
- return;
- }
-
- m_HostAddr = (in_addr *)malloc(Size);
+ return;
+ }
- if (AllocFailed(m_HostAddr)) {
- m_LatchedDestruction = true;
+ int Size = INADDR_LEN(Response->h_addrtype);
- return;
- }
+ m_HostAddr = malloc(Size);
- memcpy(m_HostAddr, Response->h_addr_list[0], Size);
+ if (AllocFailed(m_HostAddr)) {
+ m_LatchedDestruction = true;
+ return;
+ }
- if (m_BindIpCache != NULL) {
- m_BindDnsQuery = new CDnsQuery(this, USE_DNSEVENTPROXY(CConnection, AsyncBindIpDnsFinished));
- m_BindDnsQuery->GetHostByName(m_BindIpCache, Response->h_addrtype);
- }
+ m_Family = Response->h_addrtype;
+ memcpy(m_HostAddr, Response->h_addr_list[0], Size);
- AsyncConnect();
+ if (m_BindIpCache != NULL) {
+ m_BindDnsQuery = new CDnsQuery(this, USE_DNSEVENTPROXY(CConnection, AsyncBindIpDnsFinished));
+ m_BindDnsQuery->GetHostByName(m_BindIpCache, Response->h_addrtype);
}
+
+ AsyncConnect();
}
/**
*/
void CConnection::AsyncBindIpDnsFinished(hostent *Response) {
- if (Response != NULL) {
- int Size;
-
- if (Response->h_addrtype == AF_INET) {
- Size = sizeof(in_addr);
- } else if (Response->h_addrtype == AF_INET6) {
- Size = sizeof(in6_addr);
- } else {
- Size = 0;
- }
+ if (Response != NULL && Response->h_addr_list[0] != NULL) {
+ int Size = INADDR_LEN(Response->h_addrtype);
- if (Size != 0) {
- m_BindAddr = (in_addr *)malloc(Size);
+ m_BindAddr = malloc(Size);
- if (!AllocFailed(m_BindAddr)) {
- memcpy(m_BindAddr, Response->h_addr_list[0], Size);
- }
+ if (!AllocFailed(m_BindAddr)) {
+ memcpy(m_BindAddr, Response->h_addr_list[0], Size);
}
}
CFIFOBuffer *m_SendQ; /**< send queue */
CFIFOBuffer *m_RecvQ; /**< receive queue */
+ bool m_LatchedDestruction; /**< should the connection object be destroyed? */
+
public:
virtual void AsyncDnsFinished(hostent *Response);
virtual void AsyncBindIpDnsFinished(hostent *Response);
unsigned int m_PortCache; /**< the port or -1 if the cache is invalided */
char *m_BindIpCache; /**< the bind address */
- bool m_LatchedDestruction; /**< should the connection object be destroyed? */
CTrafficStats *m_Traffic; /**< the traffic statistics for this connection */
void *m_BindAddr; /**< the bind address (an in_addr or in_addr6) */
* @param Response the reponse from the DNS server
*/
void CIRCConnection::AsyncBindIpDnsFinished(hostent *Response) {
- if (Response == NULL && GetOwner() != NULL) {
- g_Bouncer->LogUser(GetOwner(), "DNS request (vhost) for user %s failed.", GetOwner()->GetUsername());
+ if ((Response == NULL || Response->h_addr_list[0] == NULL) && GetOwner() != NULL) {
+ g_Bouncer->LogUser(GetOwner(), "DNS request (vhost) for user %s failed. Cancelling connection attempt.", GetOwner()->GetUsername());
+
+ m_LatchedDestruction = true;
+
+ return;
}
CConnection::AsyncBindIpDnsFinished(Response);
* @param Host the host's ip address
* @param BindIp the ip address which should be used for binding the socket
*/
-SOCKET SocketAndConnectResolved(const sockaddr *Host, const sockaddr *BindIp) {
+SOCKET SocketAndConnectResolved(const sockaddr *Host, const sockaddr *BindIp, int *error) {
unsigned long lTrue = 1;
int Code, Size;
SOCKET Socket = socket(Host->sa_family, SOCK_STREAM, IPPROTO_TCP);
+#ifdef _WIN32
+ *error = WSAGetLastError();
+#else
+ *error = errno;
+#endif
+
if (Socket == INVALID_SOCKET) {
return INVALID_SOCKET;
}
ioctlsocket(Socket, FIONBIO, &lTrue);
if (BindIp != NULL) {
- bind(Socket, (sockaddr *)BindIp, SOCKADDR_LEN(BindIp->sa_family));
+ if (bind(Socket, (sockaddr *)BindIp, SOCKADDR_LEN(BindIp->sa_family)) != 0) {
+#ifdef _WIN32
+ *error = WSAGetLastError();
+#else
+ *error = errno;
+#endif
+
+ closesocket(Socket);
+
+ return INVALID_SOCKET;
+ }
}
Size = SOCKADDR_LEN(Host->sa_family);
Code = connect(Socket, Host, Size);
#ifdef _WIN32
- if (Code != 0 && WSAGetLastError() != WSAEWOULDBLOCK) {
+ *error = WSAGetLastError();
#else
- if (Code != 0 && errno != EINPROGRESS) {
+ *error = errno;
+#endif
+
+#ifdef _WIN32
+ if (Code != 0 && *error != WSAEWOULDBLOCK) {
+#else
+ if (Code != 0 && *error != EINPROGRESS) {
#endif
closesocket(Socket);
return INVALID_SOCKET;
}
+ *error = 0;
+
return Socket;
}