aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-tcp-stream-ssl.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-ssl.c
parent6883c5737127983d776b7071c258ae74c9bfb4c1 (diff)
downloadgsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar
gsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar.gz
gsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar.bz2
gsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar.lz
gsoc2013-evolution-2223bc36fa7b6b16ff7ea83e39e64e9375e3ebc1.tar.xz
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-ssl.c')
-rw-r--r--camel/camel-tcp-stream-ssl.c160
1 files changed, 102 insertions, 58 deletions
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index ef89d8c88e..19c534beff 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -81,11 +81,11 @@ static int stream_close (CamelStream *stream);
static PRFileDesc *enable_ssl (CamelTcpStreamSSL *ssl, PRFileDesc *fd);
-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);
struct _CamelTcpStreamSSLPrivate {
PRFileDesc *sockfd;
@@ -1025,30 +1025,58 @@ enable_ssl (CamelTcpStreamSSL *ssl, PRFileDesc *fd)
}
static int
-stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
+sockaddr_to_praddr(struct sockaddr *s, int len, PRNetAddr *addr)
+{
+ /* We assume the ip addresses are the same size - they have to be anyway.
+ We could probably just use memcpy *shrug* */
+
+ memset(addr, 0, sizeof(*addr));
+
+ if (s->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)s;
+
+ if (len < sizeof(*sin))
+ return -1;
+
+ addr->inet.family = PR_AF_INET;
+ addr->inet.port = sin->sin_port;
+ memcpy(&addr->inet.ip, &sin->sin_addr, sizeof(addr->inet.ip));
+
+ return 0;
+ }
+#ifdef ENABLE_IPv6
+ else if (s->sa_family == PR_AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)s;
+
+ if (len < sizeof(*sin))
+ return -1;
+
+ addr->ipv6.family = PR_AF_INET6;
+ addr->ipv6.port = sin->sin6_port;
+ addr->ipv6.flowinfo = sin->sin6_flowinfo;
+ memcpy(&addr->ipv6.ip, &sin->sin6_addr, sizeof(addr->ipv6.ip));
+ addr->ipv6.scope_id = sin->sin6_scope_id;
+
+ return 0;
+ }
+#endif
+
+ return -1;
+}
+
+static int
+socket_connect(CamelTcpStream *stream, struct addrinfo *host)
{
CamelTcpStreamSSL *ssl = CAMEL_TCP_STREAM_SSL (stream);
PRNetAddr netaddr;
PRFileDesc *fd, *cancel_fd;
-
- g_return_val_if_fail (host != NULL, -1);
-
- memset ((void *) &netaddr, 0, sizeof (PRNetAddr));
-#ifdef ENABLE_IPv6
- if (host->h_addrtype == AF_INET6)
- memcpy (&netaddr.ipv6.ip, host->h_addr, sizeof (netaddr.ipv6.ip));
- else
- memcpy (&netaddr.inet.ip, host->h_addr, sizeof (netaddr.inet.ip));
-#else
- memcpy (&netaddr.inet.ip, host->h_addr, sizeof (netaddr.inet.ip));
-#endif
-
- if (PR_InitializeNetAddr (PR_IpAddrNull, port, &netaddr) == PR_FAILURE) {
- set_errno (PR_GetError ());
+
+ if (sockaddr_to_praddr(host->ai_addr, host->ai_addrlen, &netaddr) != 0) {
+ errno = EINVAL;
return -1;
}
- fd = PR_OpenTCPSocket (host->h_addrtype);
+ fd = PR_OpenTCPSocket(netaddr.raw.family);
if (fd == NULL) {
set_errno (PR_GetError ());
return -1;
@@ -1127,6 +1155,17 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
return 0;
}
+static int
+stream_connect(CamelTcpStream *stream, struct addrinfo *host)
+{
+ while (host) {
+ if (socket_connect(stream, host) == 0)
+ return 0;
+ host = host->ai_next;
+ }
+
+ return -1;
+}
static int
stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data)
@@ -1158,56 +1197,61 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data)
return 0;
}
-static CamelTcpAddress *
-stream_get_local_address (CamelTcpStream *stream)
+static struct sockaddr *
+sockaddr_from_praddr(PRNetAddr *addr, socklen_t *len)
+{
+ /* We assume the ip addresses are the same size - they have to be anyway */
+
+ if (addr->raw.family == PR_AF_INET) {
+ struct sockaddr_in *sin = g_malloc0(sizeof(*sin));
+
+ sin->sin_family = AF_INET;
+ sin->sin_port = addr->inet.port;
+ memcpy(&sin->sin_addr, &addr->inet.ip, sizeof(sin->sin_addr));
+ *len = sizeof(*sin);
+
+ return (struct sockaddr *)sin;
+ }
+#ifdef ENABLE_IPv6
+ else if (addr->raw.family == PR_AF_INET6) {
+ struct sockaddr_in6 *sin = g_malloc0(sizeof(*sin));
+
+ sin->sin6_family = AF_INET6;
+ sin->sin6_port = addr->ipv6.port;
+ sin->sin6_flowinfo = addr->ipv6.flowinfo;
+ memcpy(&sin->sin6_addr, &addr->ipv6.ip, sizeof(sin->sin6_addr));
+ sin->sin6_scope_id = addr->ipv6.scope_id;
+ *len = sizeof(*sin);
+
+ return (struct sockaddr *)sin;
+ }
+#endif
+
+ return NULL;
+}
+
+static struct sockaddr *
+stream_get_local_address(CamelTcpStream *stream, socklen_t *len)
{
PRFileDesc *sockfd = CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd;
- int family, length;
- gpointer address;
PRNetAddr addr;
- PR_GetSockName (sockfd, &addr);
-
- if (addr.inet.family == PR_AF_INET) {
- family = CAMEL_TCP_ADDRESS_IPv4;
- address = &addr.inet.ip;
- length = 4;
-#ifdef ENABLE_IPv6
- } else if (addr.inet.family == PR_AF_INET6) {
- family = CAMEL_TCP_ADDRESS_IPv6;
- address = &addr.ipv6.ip;
- length = 16;
-#endif
- } else
+ if (PR_GetSockName(sockfd, &addr) != PR_SUCCESS)
return NULL;
-
- return camel_tcp_address_new (family, addr.inet.port, length, address);
+
+ return sockaddr_from_praddr(&addr, len);
}
-static CamelTcpAddress *
-stream_get_remote_address (CamelTcpStream *stream)
+static struct sockaddr *
+stream_get_remote_address (CamelTcpStream *stream, socklen_t *len)
{
PRFileDesc *sockfd = CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd;
- int family, length;
- gpointer address;
PRNetAddr addr;
- PR_GetPeerName (sockfd, &addr);
-
- if (addr.inet.family == PR_AF_INET) {
- family = CAMEL_TCP_ADDRESS_IPv4;
- address = &addr.inet.ip;
- length = sizeof (addr.inet.ip);
-#ifdef ENABLE_IPv6
- } else if (addr.inet.family == PR_AF_INET6) {
- family = CAMEL_TCP_ADDRESS_IPv6;
- address = &addr.ipv6.ip;
- length = sizeof (addr.ipv6.ip);
-#endif
- } else
+ if (PR_GetPeerName(sockfd, &addr) != PR_SUCCESS)
return NULL;
-
- return camel_tcp_address_new (family, addr.inet.port, length, address);
+
+ return sockaddr_from_praddr(&addr, len);
}
#endif /* HAVE_NSS */