diff options
Diffstat (limited to 'libmailutils/server/ipsrv.c')
-rw-r--r-- | libmailutils/server/ipsrv.c | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/libmailutils/server/ipsrv.c b/libmailutils/server/ipsrv.c index a80290834..73b2e361e 100644 --- a/libmailutils/server/ipsrv.c +++ b/libmailutils/server/ipsrv.c @@ -31,19 +31,19 @@ #include <mailutils/acl.h> #include <mailutils/server.h> #include <mailutils/debug.h> #include <mailutils/diag.h> #include <mailutils/errno.h> #include <mailutils/nls.h> +#include <mailutils/sockaddr.h> struct _mu_ip_server { char *ident; - struct sockaddr *addr; - int addrlen; + struct mu_sockaddr *addr; int fd; int type; mu_acl_t acl; mu_ip_server_conn_fp f_conn; mu_ip_server_intr_fp f_intr; mu_ip_server_free_fp f_free; @@ -63,14 +63,13 @@ struct _mu_ip_server } v; }; #define IDENTSTR(s) ((s)->ident ? (s)->ident : "default") int -mu_ip_server_create (mu_ip_server_t *psrv, struct sockaddr *addr, - int addrlen, int type) +mu_ip_server_create (mu_ip_server_t *psrv, struct mu_sockaddr *addr, int type) { struct _mu_ip_server *srv; switch (type) { case MU_IP_UDP: @@ -81,20 +80,13 @@ mu_ip_server_create (mu_ip_server_t *psrv, struct sockaddr *addr, return EINVAL; } srv = calloc (1, sizeof *srv); if (!srv) return ENOMEM; - srv->addr = calloc (1, addrlen); - if (!srv->addr) - { - free (srv); - return ENOMEM; - } - memcpy (srv->addr, addr, addrlen); - srv->addrlen = addrlen; + srv->addr = addr; srv->type = type; srv->fd = -1; switch (type) { case MU_IP_UDP: srv->v.udp_data.bufsize = 4096; @@ -117,13 +109,13 @@ mu_ip_server_destroy (mu_ip_server_t *psrv) srv = *psrv; if (!srv) return 0; if (srv->f_free) srv->f_free (srv->data); close (srv->fd); - free (srv->addr); + mu_sockaddr_free (srv->addr); free (srv->ident); if (srv->type == MU_IP_UDP && srv->v.udp_data.buf) free (srv->v.udp_data.buf); free (srv); *psrv = NULL; return 0; @@ -231,12 +223,17 @@ mu_address_family_to_domain (int family) case AF_UNIX: return PF_UNIX; case AF_INET: return PF_INET; +#ifdef MAILUTILS_IPV6 + case AF_INET6: + return PF_INET6; +#endif + default: abort (); } } int @@ -244,29 +241,26 @@ mu_ip_server_open (mu_ip_server_t srv) { int fd; if (!srv || srv->fd != -1) return EINVAL; - if (mu_debug_level_p (MU_DEBCAT_SERVER, MU_DEBUG_TRACE0)) - { - char *p = mu_sockaddr_to_astr (srv->addr, srv->addrlen); - mu_debug_log ("opening server \"%s\" %s", IDENTSTR (srv), p); - free (p); - } + mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_TRACE0, + ("opening server \"%s\" %s", IDENTSTR (srv), + mu_sockaddr_str (srv->addr))); - fd = socket (mu_address_family_to_domain (srv->addr->sa_family), + fd = socket (mu_address_family_to_domain (srv->addr->addr->sa_family), ((srv->type == MU_IP_UDP) ? SOCK_DGRAM : SOCK_STREAM), 0); if (fd == -1) { mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR, ("%s: socket: %s", IDENTSTR (srv), mu_strerror (errno))); return errno; } - switch (srv->addr->sa_family) + switch (srv->addr->addr->sa_family) { case AF_UNIX: { struct stat st; struct sockaddr_un *s_un = (struct sockaddr_un *) srv->addr; @@ -296,22 +290,22 @@ mu_ip_server_open (mu_ip_server_t srv) IDENTSTR (srv), s_un->sun_path, mu_strerror (errno))); return EAGAIN; } } break; - case AF_INET: + default: { int t; t = 1; setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &t, sizeof (t)); } } - if (bind (fd, srv->addr, srv->addrlen) == -1) + if (bind (fd, srv->addr->addr, srv->addr->addrlen) == -1) { mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR, ("%s: bind: %s", IDENTSTR (srv), mu_strerror (errno))); close (fd); return errno; } @@ -333,18 +327,15 @@ mu_ip_server_open (mu_ip_server_t srv) int mu_ip_server_shutdown (mu_ip_server_t srv) { if (!srv || srv->fd != -1) return EINVAL; - if (mu_debug_level_p (MU_DEBCAT_SERVER, MU_DEBUG_TRACE0)) - { - char *p = mu_sockaddr_to_astr (srv->addr, srv->addrlen); - mu_debug_log ("closing server \"%s\" %s", IDENTSTR (srv), p); - free (p); - } + mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_TRACE0, + ("closing server \"%s\" %s", IDENTSTR (srv), + mu_sockaddr_str (srv->addr))); close (srv->fd); return 0; } int mu_ip_tcp_accept (mu_ip_server_t srv, void *call_data) @@ -353,12 +344,15 @@ mu_ip_tcp_accept (mu_ip_server_t srv, void *call_data) int connfd; union { struct sockaddr sa; struct sockaddr_in s_in; struct sockaddr_un s_un; +#ifdef MAILUTILS_IPV6 + struct sockaddr_in6 s_in6; +#endif } client; socklen_t size = sizeof (client); if (!srv || srv->fd == -1 || srv->type == MU_IP_UDP) return EINVAL; @@ -404,12 +398,15 @@ mu_ip_udp_accept (mu_ip_server_t srv, void *call_data) int rc; union { struct sockaddr sa; struct sockaddr_in s_in; struct sockaddr_un s_un; +#ifdef MAILUTILS_IPV6 + struct sockaddr_in6 s_in6; +#endif } client; fd_set rdset; socklen_t salen = sizeof (client); ssize_t size; @@ -460,13 +457,13 @@ mu_ip_udp_accept (mu_ip_server_t srv, void *call_data) if (rc) mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR, ("%s: mu_acl_check_sockaddr: %s\n", IDENTSTR (srv), strerror (rc))); if (res == mu_acl_result_deny) { - char *p = mu_sockaddr_to_astr (srv->addr, srv->addrlen); + char *p = mu_sockaddr_to_astr (&client.sa, salen); mu_diag_output (MU_DIAG_INFO, "Denying connection from %s", p); free (p); return 0; } } rc = srv->f_conn (-1, &client.sa, size, srv->data, call_data, srv); @@ -525,25 +522,19 @@ mu_udp_server_get_rdata (mu_ip_server_t srv, char **pbuf, size_t *pbufsize) *pbuf = srv->v.udp_data.buf; *pbufsize = srv->v.udp_data.rdsize; return 0; } int -mu_ip_server_get_sockaddr (mu_ip_server_t srv, struct sockaddr *s, int *size) +mu_ip_server_get_sockaddr (mu_ip_server_t srv, struct mu_sockaddr **psa) { - int len; - - if (!srv || !s) + if (!srv || !psa) return EINVAL; - if (s == 0) - len = srv->addrlen; - else - { - len = srv->addrlen; - if (*size < len) - return MU_ERR_BUFSPACE; - memcpy (s, srv->addr, len); - } - *size = len; - return 0; + return mu_sockaddr_copy (psa, srv->addr); } - + +const char * +mu_ip_server_addrstr (mu_ip_server_t srv) +{ + return mu_sockaddr_str (srv->addr); +} + |