mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
portability fix to avoid memory alignment problems
This commit is contained in:
parent
a00b6e258d
commit
29f09f71b4
@ -102,6 +102,18 @@
|
|||||||
#undef SO_NOSIGPIPE
|
#undef SO_NOSIGPIPE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct Curl_sockaddr_ex {
|
||||||
|
int family;
|
||||||
|
int socktype;
|
||||||
|
int protocol;
|
||||||
|
unsigned int addrlen;
|
||||||
|
union {
|
||||||
|
struct sockaddr addr;
|
||||||
|
struct Curl_sockaddr_storage buff;
|
||||||
|
} _sa_ex_u;
|
||||||
|
};
|
||||||
|
#define sa_addr _sa_ex_u.addr
|
||||||
|
|
||||||
static bool verifyconnect(curl_socket_t sockfd, int *error);
|
static bool verifyconnect(curl_socket_t sockfd, int *error);
|
||||||
|
|
||||||
static curl_socket_t
|
static curl_socket_t
|
||||||
@ -743,6 +755,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
long timeout_ms,
|
long timeout_ms,
|
||||||
bool *connected)
|
bool *connected)
|
||||||
{
|
{
|
||||||
|
struct Curl_sockaddr_ex addr;
|
||||||
char addr_buf[128];
|
char addr_buf[128];
|
||||||
int rc;
|
int rc;
|
||||||
int error;
|
int error;
|
||||||
@ -750,63 +763,72 @@ singleipconnect(struct connectdata *conn,
|
|||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
curl_socket_t sockfd;
|
curl_socket_t sockfd;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
/*
|
|
||||||
* Curl_sockaddr_storage, which is basically sockaddr_storage has a space
|
|
||||||
* for a largest possible struct sockaddr only. We should add some space for
|
|
||||||
* the other fields we are using. Hence the addr_storage size math.
|
|
||||||
*/
|
|
||||||
char addr_storage[sizeof(struct curl_sockaddr)-
|
|
||||||
sizeof(struct sockaddr)+
|
|
||||||
sizeof(struct Curl_sockaddr_storage)];
|
|
||||||
struct curl_sockaddr *addr=(struct curl_sockaddr*)&addr_storage;
|
|
||||||
const void *iptoprint;
|
const void *iptoprint;
|
||||||
|
|
||||||
addr->family=ai->ai_family;
|
/*
|
||||||
addr->socktype=conn->socktype;
|
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
||||||
addr->protocol=ai->ai_protocol;
|
* curl_sockaddr structure with enough space available to directly hold
|
||||||
addr->addrlen =
|
* any protocol-specific address structures. The variable declared here
|
||||||
(ai->ai_addrlen < (socklen_t)sizeof(struct Curl_sockaddr_storage)) ?
|
* will be used to pass / receive data to/from the fopensocket callback
|
||||||
(unsigned int)ai->ai_addrlen : sizeof(struct Curl_sockaddr_storage);
|
* if this has been set, before that, it is initialized from parameters.
|
||||||
memcpy(&addr->addr, ai->ai_addr, addr->addrlen);
|
*/
|
||||||
|
|
||||||
/* If set, use opensocket callback to get the socket */
|
addr.family = ai->ai_family;
|
||||||
if(data->set.fopensocket)
|
addr.socktype = conn->socktype;
|
||||||
sockfd = data->set.fopensocket(data->set.opensocket_client,
|
addr.protocol = ai->ai_protocol;
|
||||||
CURLSOCKTYPE_IPCXN, addr);
|
addr.addrlen = ai->ai_addrlen;
|
||||||
else
|
|
||||||
sockfd = socket(addr->family, addr->socktype, addr->protocol);
|
if(addr.addrlen > sizeof(struct Curl_sockaddr_storage))
|
||||||
if(sockfd == CURL_SOCKET_BAD)
|
addr.addrlen = sizeof(struct Curl_sockaddr_storage);
|
||||||
return CURL_SOCKET_BAD;
|
memcpy(&addr.sa_addr, ai->ai_addr, addr.addrlen);
|
||||||
|
|
||||||
*connected = FALSE; /* default is not connected */
|
*connected = FALSE; /* default is not connected */
|
||||||
|
|
||||||
|
if(data->set.fopensocket)
|
||||||
|
/*
|
||||||
|
* If the opensocket callback is set, all the destination address information
|
||||||
|
* is passed to the callback. Depending on this information the callback may
|
||||||
|
* opt to abort the connection, this is indicated returning CURL_SOCKET_BAD;
|
||||||
|
* otherwise it will return a not-connected socket. When the callback returns
|
||||||
|
* a valid socket the destination address information might have been changed
|
||||||
|
* and this 'new' address will actually be used here to connect.
|
||||||
|
*/
|
||||||
|
sockfd = data->set.fopensocket(data->set.opensocket_client,
|
||||||
|
CURLSOCKTYPE_IPCXN,
|
||||||
|
(struct curl_sockaddr *)&addr);
|
||||||
|
else
|
||||||
|
/* opensocket callback not set, so simply create the socket now */
|
||||||
|
sockfd = socket(addr.family, addr.socktype, addr.protocol);
|
||||||
|
|
||||||
|
if(sockfd == CURL_SOCKET_BAD)
|
||||||
|
/* no socket, no connection */
|
||||||
|
return CURL_SOCKET_BAD;
|
||||||
|
|
||||||
#ifdef CURLRES_IPV6
|
#ifdef CURLRES_IPV6
|
||||||
if (conn->scope && (addr->family == AF_INET6)) {
|
if (conn->scope && (addr.family == AF_INET6))
|
||||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr->addr;
|
((struct sockaddr_in6 *)(&addr.sa_addr))->sin6_scope_id = conn->scope;
|
||||||
in6->sin6_scope_id = conn->scope;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
|
/* FIXME: do we have Curl_printable_address-like with struct sockaddr* as
|
||||||
argument? */
|
argument? */
|
||||||
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
|
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
|
||||||
if(addr->family==AF_UNIX) {
|
if(addr.family == AF_UNIX) {
|
||||||
infof(data, " Trying %s... ",
|
infof(data, " Trying %s... ",
|
||||||
((const struct sockaddr_un*)(&addr->addr))->sun_path);
|
((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
|
||||||
snprintf(data->info.ip, MAX_IPADR_LEN, "%s",
|
snprintf(data->info.ip, MAX_IPADR_LEN, "%s",
|
||||||
((const struct sockaddr_un*)(&addr->addr))->sun_path);
|
((const struct sockaddr_un*)(&addr.sa_addr))->sun_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
if(addr->family==AF_INET6)
|
if(addr.family == AF_INET6)
|
||||||
iptoprint= &((const struct sockaddr_in6*)(&addr->addr))->sin6_addr;
|
iptoprint = &((const struct sockaddr_in6*)(&addr.sa_addr))->sin6_addr;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
iptoprint = &((const struct sockaddr_in*)(&addr->addr))->sin_addr;
|
iptoprint = &((const struct sockaddr_in*)(&addr.sa_addr))->sin_addr;
|
||||||
|
|
||||||
if(Curl_inet_ntop(addr->family, iptoprint, addr_buf,
|
if(Curl_inet_ntop(addr.family, iptoprint, addr_buf,
|
||||||
sizeof(addr_buf)) != NULL) {
|
sizeof(addr_buf)) != NULL) {
|
||||||
infof(data, " Trying %s... ", addr_buf);
|
infof(data, " Trying %s... ", addr_buf);
|
||||||
snprintf(data->info.ip, MAX_IPADR_LEN, "%s", addr_buf);
|
snprintf(data->info.ip, MAX_IPADR_LEN, "%s", addr_buf);
|
||||||
@ -830,7 +852,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* possibly bind the local end to an IP, interface or port */
|
/* possibly bind the local end to an IP, interface or port */
|
||||||
res = bindlocal(conn, sockfd, addr->family);
|
res = bindlocal(conn, sockfd, addr.family);
|
||||||
if(res) {
|
if(res) {
|
||||||
sclose(sockfd); /* close socket and bail out */
|
sclose(sockfd); /* close socket and bail out */
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
@ -841,7 +863,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* Connect TCP sockets, bind UDP */
|
/* Connect TCP sockets, bind UDP */
|
||||||
if(conn->socktype == SOCK_STREAM)
|
if(conn->socktype == SOCK_STREAM)
|
||||||
rc = connect(sockfd, &addr->addr, addr->addrlen);
|
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
|
||||||
else
|
else
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user