aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-tcp-stream-raw.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2004-09-24 10:50:45 +0800
committerMichael Zucci <zucchi@src.gnome.org>2004-09-24 10:50:45 +0800
commit2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1 (patch)
tree47094ce1777a4c6fe98bfc81e70a07a6f9f5414a /camel/camel-tcp-stream-raw.c
parent6883c5737127983d776b7071c258ae74c9bfb4c1 (diff)
downloadgsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar.gz
gsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar.zst
gsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.zip
** See bug #47821.
2004-09-13 Not Zed <NotZed@Ximian.com> ** See bug #47821. * camel-service.c: removed the old hostent based hostname interfaces. * camel-sasl-kerberos4.c (krb4_challenge): new hostname interfaces. * camel-sasl-gssapi.c (gssapi_challenge): new hostname interfaces. * camel-sasl-digest-md5.c (digest_md5_challenge): use new hostname interfaces. (generate_response): just take hostname directly, not hostent. * camel-mime-utils.c (camel_header_msgid_generate): use new hostname interfaces. * providers/smtp/camel-smtp-transport.c (connect_to_server): fixed to use new addrinfo apis. * providers/pop3/camel-pop3-store.c (connect_to_server): fixed to use new addrinfo apis. * camel-tcp-stream-ssl.c (stream_connect): try all addresses supplied. * camel-tcp-stream.c (camel_tcp_stream_get_remote_address) (camel_tcp_stream_get_local_address): return a sockaddr now, and also the address length. Fixed all implementations and callers. (camel_tcp_stream_connect): use addrinfo rather than hostent for host AND port info. Fixed all implementations and callers. svn path=/trunk/; revision=27352
Diffstat (limited to 'camel/camel-tcp-stream-raw.c')
-rw-r--r--camel/camel-tcp-stream-raw.c147
1 files changed, 49 insertions, 98 deletions
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index 04e47ac64b..93f3fbdbab 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -20,7 +20,6 @@
*
*/
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -48,11 +47,11 @@ static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n);
static int stream_flush (CamelStream *stream);
static int stream_close (CamelStream *stream);
-static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port);
+static int stream_connect (CamelTcpStream *stream, struct addrinfo *host);
static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-static CamelTcpAddress *stream_get_local_address (CamelTcpStream *stream);
-static CamelTcpAddress *stream_get_remote_address (CamelTcpStream *stream);
+static struct sockaddr *stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
+static struct sockaddr *stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
static void
camel_tcp_stream_raw_class_init (CamelTcpStreamRawClass *camel_tcp_stream_raw_class)
@@ -267,13 +266,8 @@ stream_close (CamelStream *stream)
/* this is a 'cancellable' connect, cancellable from camel_operation_cancel etc */
/* returns -1 & errno == EINTR if the connection was cancelled */
static int
-socket_connect (struct hostent *h, int port)
+socket_connect(struct addrinfo *h)
{
-#ifdef ENABLE_IPv6
- struct sockaddr_in6 sin6;
-#endif
- struct sockaddr_in sin;
- struct sockaddr *saddr;
struct timeval tv;
socklen_t len;
int cancel_fd;
@@ -286,31 +280,17 @@ socket_connect (struct hostent *h, int port)
return -1;
}
- /* setup connect, we do it using a nonblocking socket so we can poll it */
-#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
+ if (h->ai_socktype != SOCK_STREAM) {
+ errno = EINVAL;
+ return -1;
}
-#endif
-
- if ((fd = socket (h->h_addrtype, SOCK_STREAM, 0)) == -1)
+
+ if ((fd = socket (h->ai_family, SOCK_STREAM, 0)) == -1)
return -1;
cancel_fd = camel_operation_cancel_fd (NULL);
if (cancel_fd == -1) {
- if (connect (fd, saddr, len) == -1) {
+ if (connect (fd, h->ai_addr, h->ai_addrlen) == -1) {
errnosav = errno;
close (fd);
errno = errnosav;
@@ -325,7 +305,7 @@ socket_connect (struct hostent *h, int port)
flags = fcntl (fd, F_GETFL);
fcntl (fd, F_SETFL, flags | O_NONBLOCK);
- if (connect (fd, saddr, len) == 0) {
+ if (connect (fd, h->ai_addr, h->ai_addrlen) == 0) {
fcntl (fd, F_SETFL, flags);
return fd;
}
@@ -383,21 +363,22 @@ socket_connect (struct hostent *h, int port)
}
static int
-stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
+stream_connect (CamelTcpStream *stream, struct addrinfo *host)
{
CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
- int fd;
g_return_val_if_fail (host != NULL, -1);
-
- if ((fd = socket_connect (host, port)) == -1)
- return -1;
-
- raw->sockfd = fd;
-
- return 0;
-}
+ while (host) {
+ raw->sockfd = socket_connect(host);
+ if (raw->sockfd != -1)
+ return 0;
+
+ host = host->ai_next;
+ }
+
+ return -1;
+}
static int
get_sockopt_level (const CamelSockOptData *data)
@@ -496,72 +477,42 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data)
sizeof (data->value));
}
+static struct sockaddr *
+stream_get_local_address (CamelTcpStream *stream, socklen_t *len)
+{
#ifdef ENABLE_IPv6
-#define MIN_SOCKADDR_BUFLEN (sizeof (struct sockaddr_in6))
+ struct sockaddr_in6 sin;
#else
-#define MIN_SOCKADDR_BUFLEN (sizeof (struct sockaddr_in))
+ struct sockaddr_in sin;
#endif
+ struct sockaddr *saddr = (struct sockaddr *)&sin;
-static CamelTcpAddress *
-stream_get_local_address (CamelTcpStream *stream)
-{
- 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)
+ *len = sizeof(sin);
+ if (getsockname (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 (family, sin->sin_port, len, address);
+
+ saddr = g_malloc(*len);
+ memcpy(saddr, &sin, *len);
+
+ return saddr;
}
-static CamelTcpAddress *
-stream_get_remote_address (CamelTcpStream *stream)
+static struct sockaddr *
+stream_get_remote_address (CamelTcpStream *stream, socklen_t *len)
{
- 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, 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;
+ struct sockaddr_in6 sin;
+#else
+ struct sockaddr_in sin;
#endif
- } else
+ struct sockaddr *saddr = (struct sockaddr *)&sin;
+
+ *len = sizeof(sin);
+ if (getpeername (CAMEL_TCP_STREAM_RAW (stream)->sockfd, saddr, len) == -1)
return NULL;
-
- return camel_tcp_address_new (family, sin->sin_port, len, address);
+
+ saddr = g_malloc(*len);
+ memcpy(saddr, &sin, *len);
+
+ return saddr;
}