I would suggest a change to the code
similar to the one that I reported below. Or _sa could have
the size equal to MAX(sizeof(sockaddr_in), sizeof(sockaddr_in6)).
Thank you in advance and kind
regards,
Dario.
Connection*
TcpBaseTransport::makeOutgoingConnection(const
Tuple &dest,
TransportFailure::FailureReason
&failReason, int &failSubCode)
{
// attempt to open
Socket sock =
InternalTransport::socket( TCP, ipVersion());
// fdset.clear(sock); !kw!
removed as part of epoll impl
if ( sock ==
INVALID_SOCKET ) // no socket found - try to free one
up and try again
{
int err =
getErrno();
InfoLog (<< "Failed
to create a socket " << strerror(err));
error(err);
mConnectionManager.gc(ConnectionManager::MinimumGcAge, 1); //
free one up
sock =
InternalTransport::socket( TCP, ipVersion());
if ( sock ==
INVALID_SOCKET )
{
err = getErrno();
WarningLog( << "Error
in finding free filedescriptor to use. " <<
strerror(err));
error(err);
failReason =
TransportFailure::TransportNoSocket;
failSubCode = err;
return NULL;
}
}
assert(sock != INVALID_SOCKET);
DebugLog (<<"Opening
new connection to " << dest);
socklen_t len = mTuple.length();
//char _sa[len];
char* _sa = new
char[len];
sockaddr *sa = reinterpret_cast<sockaddr*>(_sa);
mTuple.copySockaddrAnyPort(sa);
//if(::bind(sock, sa,
len) != 0)
int ret =
::bind(sock, sa, len);
delete [] _sa;
sa = NULL;
if (ret != 0)
{
WarningLog( << "Error
in binding to source interface address. " <<
strerror(errno));
failReason =
TransportFailure::Failure;
failSubCode = errno;
return NULL;
}
makeSocketNonBlocking(sock);
if (mSocketFunc)
{
mSocketFunc(sock, transport(),
__FILE__, __LINE__);
}
const sockaddr&
servaddr = dest.getSockaddr();
//int ret = connect(
sock, &servaddr, dest.length() );
ret = connect( sock,
&servaddr, dest.length() );
// See Chapter 15.3 of
Stevens, Unix Network Programming Vol. 1 2nd Edition
if (ret ==
SOCKET_ERROR)
{
int err =
getErrno();
switch (err)
{
case
EINPROGRESS:
case
EWOULDBLOCK:
break;
default:
{
// !jf! this has
failed
InfoLog( << "Error
on TCP connect to " << dest << ",
err=" << err << ": "
<< strerror(err));
error(err);
//fdset.clear(sock);
closeSocket(sock);
failReason =
TransportFailure::TransportBadConnect;
failSubCode = err;
return
NULL;
}
}
}
// This will add the
connection to the manager
Connection *conn =
createConnection(dest, sock, false);
assert(conn);
conn->mRequestPostConnectSocketFuncCall = true;
return conn;
}