From 8137a35173541e4a5a3ed180b6493f2166d08ac1 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Wed, 31 Jul 2002 01:03:10 +0000 Subject: Update the comment. 2002-07-30 Jeffrey Stedfast * camel-tcp-stream.c (camel_tcp_address_new): Update the comment. * camel-tcp-stream-raw.c (socket_connect): If building with IPv6 support and the address is an IPv6 address, connect using a sockaddr_in6 otherwise use the standard IPv4 sockaddr_in structure. (stream_get_local_address): Fix to work with IPv6 addresses. (stream_get_remote_address): Same. * camel-tcp-stream-openssl.c (socket_connect): Same as above. (stream_get_local_address): Fix to work with IPv6 addresses. (stream_get_remote_address): Same. * camel-tcp-stream-ssl.c (stream_connect): If building with IPv6 support and the address is an IPv6 address, initialise the PRNetAddr accordingly. (stream_get_local_address): Fix to work with IPv6 addresses. (stream_get_remote_address): Same. svn path=/trunk/; revision=17651 --- camel/camel-tcp-stream-raw.c | 96 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 18 deletions(-) (limited to 'camel/camel-tcp-stream-raw.c') diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c index 8b6a868b47..b8e6426c49 100644 --- a/camel/camel-tcp-stream-raw.c +++ b/camel/camel-tcp-stream-raw.c @@ -20,6 +20,7 @@ * */ + #ifdef HAVE_CONFIG_H #include #endif @@ -380,12 +381,15 @@ stream_close (CamelStream *stream) static int socket_connect (struct hostent *h, int port) { +#ifdef ENABLE_IPv6 + struct sockaddr_in6 sin6; +#endif struct sockaddr_in sin; - int fd; - int ret; - socklen_t len; + struct sockaddr *saddr; struct timeval tv; + socklen_t len; int cancel_fd; + int ret, fd; /* see if we're cancelled yet */ if (camel_operation_cancel_check (NULL)) { @@ -394,15 +398,29 @@ socket_connect (struct hostent *h, int port) } /* setup connect, we do it using a nonblocking socket so we can poll it */ - sin.sin_port = htons (port); - sin.sin_family = h->h_addrtype; - memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); +#ifdef ENABLE_IPv6 + if (h->h_addrtype == AF_INET6) { + sin6.sin6_port = htons (port); + sin6.sin6_family = h->h_addrtype; + memcpy (&sin6.sin6_addr, h->h_addr, sizeof (sin6.sin6_addr)); + saddr = (struct sockaddr *) &sin6; + len = sizeof (sin6); + } else { +#endif + sin.sin_port = htons (port); + sin.sin_family = h->h_addrtype; + memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); + saddr = (struct sockaddr *) &sin; + len = sizeof (sin); +#ifdef ENABLE_IPv6 + } +#endif fd = socket (h->h_addrtype, SOCK_STREAM, 0); cancel_fd = camel_operation_cancel_fd (NULL); if (cancel_fd == -1) { - ret = connect (fd, (struct sockaddr *)&sin, sizeof (sin)); + ret = connect (fd, saddr, len); if (ret == -1) { close (fd); return -1; @@ -416,7 +434,7 @@ socket_connect (struct hostent *h, int port) flags = fcntl (fd, F_GETFL); fcntl (fd, F_SETFL, flags | O_NONBLOCK); - ret = connect (fd, (struct sockaddr *) &sin, sizeof (sin)); + ret = connect (fd, saddr, len); if (ret == 0) { fcntl (fd, F_SETFL, flags); return fd; @@ -585,30 +603,72 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data) sizeof (data->value)); } +#ifdef ENABLE_IPv6 +#define MIN_SOCKADDR_BUFLEN (sizeof (struct sockaddr_in6)) +#else +#define MIN_SOCKADDR_BUFLEN (sizeof (struct sockaddr_in)) +#endif + static CamelTcpAddress * stream_get_local_address (CamelTcpStream *stream) { - struct sockaddr_in sin; + unsigned char buf[MIN_SOCKADDR_BUFLEN]; +#ifdef ENABLE_IPv6 + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) buf; +#endif + struct sockaddr_in *sin = (struct sockaddr_in *) buf; + struct sockaddr *saddr = (struct sockaddr *) buf; + gpointer address; socklen_t len; + int family; + + len = MIN_SOCKADDR_BUFLEN; + + if (getsockname (CAMEL_TCP_STREAM_RAW (stream)->sockfd, saddr, &len) == -1) + return NULL; - if (getsockname (CAMEL_TCP_STREAM_RAW (stream)->sockfd, - (struct sockaddr *) &sin, &len) == -1) + if (saddr->sa_family == AF_INET) { + family = CAMEL_TCP_ADDRESS_IPv4; + address = &sin->sin_addr; +#ifdef ENABLE_IPv6 + } else if (saddr->sa_family == AF_INET6) { + family = CAMEL_TCP_ADDRESS_IPv6; + address = &sin6->sin6_addr; +#endif + } else return NULL; - return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, sin.sin_port, - 4, &sin.sin_addr); + return camel_tcp_address_new (family, sin->sin_port, len, address); } static CamelTcpAddress * stream_get_remote_address (CamelTcpStream *stream) { - struct sockaddr_in sin; + unsigned char buf[MIN_SOCKADDR_BUFLEN]; +#ifdef ENABLE_IPv6 + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) buf; +#endif + struct sockaddr_in *sin = (struct sockaddr_in *) buf; + struct sockaddr *saddr = (struct sockaddr *) buf; + gpointer address; socklen_t len; + int family; + + len = MIN_SOCKADDR_BUFLEN; - if (getpeername (CAMEL_TCP_STREAM_RAW (stream)->sockfd, - (struct sockaddr *) &sin, &len) == -1) + if (getpeername (CAMEL_TCP_STREAM_RAW (stream)->sockfd, saddr, &len) == -1) + return NULL; + + if (saddr->sa_family == AF_INET) { + family = CAMEL_TCP_ADDRESS_IPv4; + address = &sin->sin_addr; +#ifdef ENABLE_IPv6 + } else if (saddr->sa_family == AF_INET6) { + family = CAMEL_TCP_ADDRESS_IPv6; + address = &sin6->sin6_addr; +#endif + } else return NULL; - return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, sin.sin_port, - 4, &sin.sin_addr); + return camel_tcp_address_new (family, sin->sin_port, len, address); } -- cgit v1.2.3