? mkpatch.sh ? net.c ? include/asterisk/net.h Index: Makefile =================================================================== RCS file: /usr/cvsroot/asterisk/Makefile,v retrieving revision 1.147 diff -u -r1.147 Makefile --- Makefile 1 Apr 2005 21:18:39 -0000 1.147 +++ Makefile 4 Apr 2005 20:50:10 -0000 @@ -235,6 +235,7 @@ CFLAGS+= $(OPTIONS) CFLAGS+= -fomit-frame-pointer SUBDIRS=res channels pbx apps codecs formats agi cdr utils stdtime +#SUBDIRS=channels pbx ifeq (${OSARCH},Linux) LIBS=-ldl -lpthread endif @@ -265,7 +266,7 @@ cdr.o tdd.o acl.o rtp.o manager.o asterisk.o ast_expr.o \ dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \ astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \ - utils.o config_old.o plc.o jitterbuf.o + utils.o config_old.o plc.o jitterbuf.o net.o ifeq (${OSARCH},Darwin) OBJS+=poll.o dlfcn.o ASTLINK=-Wl,-dynamic Index: acl.c =================================================================== RCS file: /usr/cvsroot/asterisk/acl.c,v retrieving revision 1.39 diff -u -r1.39 acl.c --- acl.c 9 Mar 2005 05:48:11 -0000 1.39 +++ acl.c 4 Apr 2005 20:50:10 -0000 @@ -43,9 +43,10 @@ #include #endif + struct ast_netsock { ASTOBJ_COMPONENTS(struct ast_netsock); - struct sockaddr_in bindaddr; + net_sockaddr *bindaddr; int sockfd; int *ioref; struct io_context *ioc; @@ -55,8 +56,8 @@ struct ast_ha { /* Host access rule */ - struct in_addr netaddr; - struct in_addr netmask; + net_sockaddr *netaddr; + net_sockaddr *netmask; int sense; struct ast_ha *next; }; @@ -66,7 +67,7 @@ struct my_ifreq { char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "eth0", "ppp0", etc. */ - struct sockaddr_in ifru_addr; + net_sockaddr *ifru_addr; }; /* Free HA structure */ @@ -76,6 +77,12 @@ while(ha) { hal = ha; ha = ha->next; + if (hal->netaddr) { + net_addr_delete(hal->netaddr); + } + if (hal->netmask) { + net_addr_delete(hal->netmask); + } free(hal); } } @@ -83,8 +90,8 @@ /* Copy HA structure */ static void ast_copy_ha(struct ast_ha *from, struct ast_ha *to) { - memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr)); - memcpy(&to->netmask, &from->netmask, sizeof(from->netmask)); + net_addr_cpy(to->netaddr, from->netaddr); + net_addr_cpy(to->netmask, from->netmask); to->sense = from->sense; } @@ -129,42 +136,48 @@ char tmp[256] = ""; struct ast_ha *prev = NULL; struct ast_ha *ret; - int x,z; - unsigned int y; ret = path; while(path) { prev = path; path = path->next; } if (ha) { + ha->netaddr = net_addr_new(); + ha->netmask = net_addr_new(); + strncpy(tmp, stuff, sizeof(tmp) - 1); nm = strchr(tmp, '/'); - if (!nm) - nm = "255.255.255.255"; - else { + if (nm) { *nm = '\0'; nm++; } - if (!strchr(nm, '.')) { - if ((sscanf(nm, "%i", &x) == 1) && (x >= 0) && (x <= 32)) { - y = 0; - for (z=0;z>= 1; - y |= 0x80000000; - } - ha->netmask.s_addr = htonl(y); - } - } else if (!inet_aton(nm, &ha->netmask)) { - ast_log(LOG_WARNING, "%s is not a valid netmask\n", nm); - free(ha); + if (!net_aton(tmp, ha->netaddr)) { + ast_log(LOG_WARNING, "%s is not a valid IP\n", tmp); + ast_free_ha(ha); return path; } - if (!inet_aton(tmp, &ha->netaddr)) { - ast_log(LOG_WARNING, "%s is not a valid IP\n", tmp); - free(ha); + if (!nm) { + switch (net_addr_getfamily(ha->netaddr)) { + case AF_INET: + nm = "255.255.255.255"; + break; + case AF_INET6: + nm = "128"; + break; + default: + ast_log(LOG_ERROR, "Unknown address family %d\n", + net_addr_getfamily(ha->netaddr)); return path; + } } - ha->netaddr.s_addr &= ha->netmask.s_addr; + if (!strchr(nm, '.')) { + net_addr_initmask(ha->netmask, ha->netaddr, nm); + } else if (!net_aton(nm, ha->netmask)) { + ast_log(LOG_WARNING, "%s is not a valid netmask\n", nm); + ast_free_ha(ha); + return path; + } + net_addr_andmask(ha->netaddr, ha->netmask); if (!strncasecmp(sense, "p", 1)) { ha->sense = AST_SENSE_ALLOW; } else { @@ -180,58 +193,66 @@ return ret; } -int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin) +int ast_apply_ha(struct ast_ha *ha, net_sockaddr *sin) { /* Start optimistic */ int res = AST_SENSE_ALLOW; while(ha) { - char iabuf[INET_ADDRSTRLEN]; - char iabuf2[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; + char iabuf2[NET_ADDRSTRLEN]; + /* DEBUG */ ast_log(LOG_DEBUG, "##### Testing %s with %s\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), - ast_inet_ntoa(iabuf2, sizeof(iabuf2), ha->netaddr)); + net_ntoa(iabuf, sizeof(iabuf), sin), + net_ntoa(iabuf2, sizeof(iabuf2), ha->netaddr)); /* For each rule, if this address and the netmask = the net address apply the current rule */ - if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr)) + if (net_addr_checkmask(sin, ha->netaddr, ha->netmask) > 0) { res = ha->sense; + } ha = ha->next; } return res; } -int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service) +int ast_get_ip_or_srv(net_sockaddr *sin, const char *value, const char *service) { - struct hostent *hp; - struct ast_hostent ahp; char srv[256]; char host[256]; - int tportno = ntohs(sin->sin_port); - if (inet_aton(value, &sin->sin_addr)) + int tportno = 0; + int err; + + tportno = net_addr_getport(sin); + + if (net_addr_get(sin, value)) return 0; + + net_addr_setport(sin, tportno); + if (service) { snprintf(srv, sizeof(srv), "%s.%s", service, value); if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) { - sin->sin_port = htons(tportno); +// sin->sin_port = htons(tportno); value = host; } } - hp = ast_gethostbyname(value, &ahp); - if (hp) { - memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); - } else { + err = net_addr_get(sin, value); + + if (err) { ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value); return -1; } + return 0; } -int ast_get_ip(struct sockaddr_in *sin, const char *value) +int ast_get_ip(net_sockaddr *sin, const char *value) { return ast_get_ip_or_srv(sin, value, NULL); } +#if 0 /* iface is the interface (e.g. eth0); address is the return value */ int ast_lookup_iface(char *iface, struct in_addr *address) { @@ -254,34 +275,49 @@ return 0; } } +#endif -int ast_ouraddrfor(struct in_addr *them, struct in_addr *us) +int ast_ouraddrfor(net_sockaddr *them, net_sockaddr *us) { int s; - struct sockaddr_in sin; - socklen_t slen; + net_sockaddr *sin; + + net_addr_alloca(&sin); + net_addr_cpy(sin, them); + net_addr_setsocktype(sin, SOCK_DGRAM); + net_addr_setprotocol(sin, 0); + net_addr_setport(sin, 5060); - s = socket(PF_INET, SOCK_DGRAM, 0); + s = net_socket(sin); if (s == -1) { ast_log(LOG_WARNING, "Cannot create socket\n"); + { + char buf[256]; + ast_log(LOG_WARNING, "Addr: %s %d %d %d\n", + net_ntostr(buf, sizeof(buf), sin), + net_addr_getfamily(sin), + net_addr_getsocktype(sin), + net_addr_getprotocol(sin)); + } +/* net_addr_delete(sin); */ return -1; } - sin.sin_family = AF_INET; - sin.sin_port = 5060; - sin.sin_addr = *them; - if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) { + + if (net_connect(s, sin)) { ast_log(LOG_WARNING, "Cannot connect\n"); close(s); +/* net_addr_delete(sin); */ return -1; } - slen = sizeof(sin); - if (getsockname(s, (struct sockaddr *)&sin, &slen)) { + if (net_getsockname(s, sin)) { ast_log(LOG_WARNING, "Cannot get socket name\n"); close(s); +/* net_addr_delete(sin); */ return -1; } close(s); - *us = sin.sin_addr; + net_addr_cpy(us, sin); +/* net_addr_delete(sin); */ return 0; } @@ -292,23 +328,29 @@ return -1; } -struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct sockaddr_in *bindaddr, int tos, ast_io_cb callback, void *data) +struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, net_sockaddr *bindaddr, int tos, ast_io_cb callback, void *data) { int netsocket = -1; int *ioref; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct ast_netsock *ns; /* Make a UDP socket */ - netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + net_addr_setsocktype(bindaddr, SOCK_DGRAM); + net_addr_setprotocol(bindaddr, 0); + netsocket = net_socket(bindaddr); /* FIXME IPPROTO_IP */ if (netsocket < 0) { ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); + ast_log(LOG_ERROR, "socket: %d %d %d\n", + net_addr_getfamily(bindaddr), + net_addr_getsocktype(bindaddr), + net_addr_getprotocol(bindaddr)); return NULL; } - if (bind(netsocket,(struct sockaddr *)bindaddr, sizeof(struct sockaddr_in))) { - ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr->sin_addr), ntohs(bindaddr->sin_port), strerror(errno)); + if (net_bind(netsocket, bindaddr)) { + ast_log(LOG_ERROR, "Unable to bind to %s: %s\n", net_ntostr(iabuf, sizeof(iabuf), bindaddr), strerror(errno)); close(netsocket); return NULL; } @@ -333,7 +375,8 @@ ns->ioc = ioc; ns->sockfd = netsocket; ns->data = data; - memcpy(&ns->bindaddr, bindaddr, sizeof(ns->bindaddr)); + ns->bindaddr = net_addr_new(); + net_addr_cpy(ns->bindaddr, bindaddr); ASTOBJ_CONTAINER_LINK(list, ns); } else { ast_log(LOG_WARNING, "Out of memory!\n"); @@ -346,6 +389,9 @@ { ast_io_remove(netsock->ioc, netsock->ioref); close(netsock->sockfd); + if (netsock->bindaddr) { + net_addr_delete(netsock->bindaddr); + } free(netsock); } @@ -363,9 +409,9 @@ return 0; } -const struct sockaddr_in *ast_netsock_boundaddr(struct ast_netsock *ns) +const net_sockaddr *ast_netsock_boundaddr(struct ast_netsock *ns) { - return &(ns->bindaddr); + return (ns->bindaddr); } void *ast_netsock_data(struct ast_netsock *ns) @@ -375,54 +421,83 @@ struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, ast_io_cb callback, void *data) { - struct sockaddr_in sin; + net_sockaddr *sin; char *tmp; - char *port; - int portno; - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(defaultport); + int portno = defaultport; + + net_addr_alloca(&sin); tmp = ast_strdupa(bindinfo); if (tmp) { + char *port; + char *host; + + if (*tmp == '[') { + tmp++; + host = tmp; + tmp = strchr(tmp, ']'); + if (tmp) { + *tmp = '\0'; + tmp++; + } + } else { + host = tmp; + } + port = strchr(tmp, ':'); if (port) { *port = '\0'; port++; - if ((portno = atoi(port)) > 0) - sin.sin_port = htons(portno); } - inet_aton(tmp, &sin.sin_addr); - return ast_netsock_bindaddr(list, ioc, &sin, tos, callback, data); + + if (!net_aton(host, sin)) { + ast_log(LOG_WARNING, "Invalid address %s %s\n", + bindinfo, host); + return NULL; + } + + if (port) { + if ((portno = atoi(port)) <= 0) { + ast_log(LOG_WARNING, "Invalid port %s\n", + port); + return NULL; + } + } + + net_addr_setport(sin, portno); + + return ast_netsock_bindaddr(list, ioc, sin, tos, callback, data); } else ast_log(LOG_WARNING, "Out of memory!\n"); return NULL; } -int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr) +int ast_find_ourip(net_sockaddr *ourip, net_sockaddr *bindaddr) { char ourhost[256]; - struct ast_hostent ahp; - struct hostent *hp; - struct in_addr saddr; + net_sockaddr *saddr; + int res; + + net_addr_alloca(&saddr); /* just use the bind address if it is nonzero */ - if (ntohl(bindaddr.sin_addr.s_addr)) { - memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip)); + if (!net_addr_ishostnull(bindaddr)) { + net_addr_cpy(ourip, bindaddr); return 0; } /* try to use our hostname */ if (gethostname(ourhost, sizeof(ourhost))) { ast_log(LOG_WARNING, "Unable to get hostname\n"); } else { - hp = ast_gethostbyname(ourhost, &ahp); - if (hp) { - memcpy(ourip, hp->h_addr, sizeof(*ourip)); + if (!net_addr_get(ourip, ourhost)) { return 0; } } /* A.ROOT-SERVERS.NET. */ - if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip)) - return 0; - return -1; + res = -1; + if (net_aton("198.41.0.4", saddr) && !ast_ouraddrfor(saddr, ourip)) + res = 0; + +/* net_addr_delete(saddr); */ + return res; } Index: manager.c =================================================================== RCS file: /usr/cvsroot/asterisk/manager.c,v retrieving revision 1.89 diff -u -r1.89 manager.c --- manager.c 2 Apr 2005 00:58:33 -0000 1.89 +++ manager.c 4 Apr 2005 20:50:10 -0000 @@ -40,6 +40,7 @@ #include #include #include +#include struct fast_originate_helper { @@ -191,13 +192,13 @@ static int handle_showmanconn(int fd, int argc, char *argv[]) { struct mansession *s; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[INET6_ADDRSTRLEN]; char *format = " %-15.15s %-15.15s\n"; ast_mutex_lock(&sessionlock); s = sessions; ast_cli(fd, format, "Username", "IP Address"); while (s) { - ast_cli(fd, format,s->username, ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_cli(fd, format,s->username, net_ntoa(iabuf, sizeof(iabuf), s->sin)); s = s->next; } @@ -249,6 +250,9 @@ if (s->fd > -1) close(s->fd); ast_mutex_destroy(&s->lock); + if (s->sin) { + net_addr_delete(s->sin); + } free(s); } else ast_log(LOG_WARNING, "Trying to delete non-existant session %p?\n", s); @@ -395,7 +399,7 @@ static int authenticate(struct mansession *s, struct message *m) { struct ast_config *cfg; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[INET6_ADDRSTRLEN]; char *cat; char *user = astman_get_header(m, "Username"); char *pass = astman_get_header(m, "Secret"); @@ -425,8 +429,8 @@ v = v->next; } - if (ha && !ast_apply_ha(ha, &(s->sin))) { - ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), user); + if (ha && !ast_apply_ha(ha, s->sin)) { + ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", net_ntoa(iabuf, sizeof(iabuf), s->sin), user); ast_free_ha(ha); ast_config_destroy(cfg); return -1; @@ -455,7 +459,7 @@ } else if (password && !strcasecmp(password, pass)) { break; } else { - ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), user); + ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", net_ntoa(iabuf, sizeof(iabuf), s->sin), user); ast_config_destroy(cfg); return -1; } @@ -472,7 +476,7 @@ set_eventmask(s, events); return 0; } - ast_log(LOG_NOTICE, "%s tried to authenticate with non-existant user '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), user); + ast_log(LOG_NOTICE, "%s tried to authenticate with non-existant user '%s'\n", net_ntoa(iabuf, sizeof(iabuf), s->sin), user); ast_config_destroy(cfg); return -1; } @@ -1166,7 +1170,7 @@ struct manager_action *tmp = first_action; char *id = astman_get_header(m,"ActionID"); char idText[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[INET6_ADDRSTRLEN]; strncpy(action, astman_get_header(m, "Action"), sizeof(action) - 1); ast_log( LOG_DEBUG, "Manager received command '%s'\n", action ); @@ -1208,10 +1212,10 @@ s->authenticated = 1; if (option_verbose > 1) { if ( displayconnects ) { - ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged on from %s\n", s->username, ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged on from %s\n", s->username, net_ntoa(iabuf, sizeof(iabuf), s->sin)); } } - ast_log(LOG_EVENT, "Manager '%s' logged on from %s\n", s->username, ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_log(LOG_EVENT, "Manager '%s' logged on from %s\n", s->username, net_ntoa(iabuf, sizeof(iabuf), s->sin)); astman_send_ack(s, m, "Authentication accepted"); } } else if (!strcasecmp(action, "Logoff")) { @@ -1243,7 +1247,7 @@ int res; int x; struct pollfd fds[1]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[INET6_ADDRSTRLEN]; for (x=1;xinlen;x++) { if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) { /* Copy output data up to and including \r\n */ @@ -1257,7 +1261,7 @@ } } if (s->inlen >= sizeof(s->inbuf) - 1) { - ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), s->inbuf); + ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", net_ntoa(iabuf, sizeof(iabuf), s->sin), s->inbuf); s->inlen = 0; } fds[0].fd = s->fd; @@ -1281,7 +1285,7 @@ { struct mansession *s = data; struct message m; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[INET6_ADDRSTRLEN]; int res; ast_mutex_lock(&s->lock); @@ -1307,15 +1311,15 @@ if (s->authenticated) { if (option_verbose > 1) { if (displayconnects) - ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, net_ntoa(iabuf, sizeof(iabuf), s->sin)); } - ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, net_ntoa(iabuf, sizeof(iabuf), s->sin)); } else { if (option_verbose > 1) { if ( displayconnects ) - ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", net_ntoa(iabuf, sizeof(iabuf), s->sin)); } - ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr)); + ast_log(LOG_EVENT, "Failed attempt from %s\n", net_ntoa(iabuf, sizeof(iabuf), s->sin)); } destroy_session(s); return NULL; @@ -1324,8 +1328,7 @@ static void *accept_thread(void *ignore) { int as; - struct sockaddr_in sin; - int sinlen; + net_sockaddr *sin; struct mansession *s; struct protoent *p; int arg = 1; @@ -1335,13 +1338,14 @@ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + sin = net_addr_new(); for (;;) { - sinlen = sizeof(sin); - as = accept(asock, (struct sockaddr *)&sin, &sinlen); + as = net_accept(asock, sin); if (as < 0) { ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); continue; } + p = getprotobyname("tcp"); if (p) { if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { @@ -1354,7 +1358,8 @@ continue; } memset(s, 0, sizeof(struct mansession)); - memcpy(&s->sin, &sin, sizeof(sin)); + s->sin = sin; + sin = net_addr_new(); if(! block_sockets) { /* For safety, make sure socket is non-blocking */ @@ -1371,6 +1376,7 @@ if (ast_pthread_create(&t, &attr, session_do, s)) destroy_session(s); } + net_addr_delete(sin); pthread_attr_destroy(&attr); return NULL; } @@ -1499,7 +1505,7 @@ struct ast_config *cfg; char *val; int oldportno = portno; - static struct sockaddr_in ba; + net_sockaddr *ba; int x = 1; if (!registered) { /* Register default actions */ @@ -1532,7 +1538,6 @@ ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n"); return 0; } - memset(&ba, 0, sizeof(ba)); val = ast_variable_retrieve(cfg, "general", "enabled"); if (val) enabled = ast_true(val); @@ -1557,17 +1562,21 @@ if ((val = ast_variable_retrieve(cfg, "general", "displayconnects"))) { displayconnects = ast_true(val);; } - - - ba.sin_family = AF_INET; - ba.sin_port = htons(portno); - memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); + + net_addr_alloca(&ba); + net_addr_init(ba, PF_UNSPEC, SOCK_STREAM, 0); if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) { - if (!inet_aton(val, &ba.sin_addr)) { + if (!net_aton(val, ba)) { ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val); - memset(&ba.sin_addr, 0, sizeof(ba.sin_addr)); + net_aton("0.0.0.0", ba); } + } else { + net_aton("0.0.0.0", ba); + } + + if (net_addr_setport(ba, portno) < 0) { + ast_log(LOG_ERROR, "Can't set port %d\n", portno); } if ((asock > -1) && ((portno != oldportno) || !enabled)) { @@ -1586,13 +1595,13 @@ return 0; } if (asock < 0) { - asock = socket(AF_INET, SOCK_STREAM, 0); + asock = net_socket(ba); if (asock < 0) { ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); return -1; } setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); - if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) { + if (net_bind(asock, ba)) { ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno)); close(asock); asock = -1; Index: rtp.c =================================================================== RCS file: /usr/cvsroot/asterisk/rtp.c,v retrieving revision 1.118 diff -u -r1.118 rtp.c --- rtp.c 31 Mar 2005 19:09:48 -0000 1.118 +++ rtp.c 4 Apr 2005 20:50:11 -0000 @@ -54,7 +54,7 @@ static int rtpstart = 0; static int rtpend = 0; static int rtpdebug = 0; /* Are we debugging? */ -static struct sockaddr_in rtpdebugaddr; /* Debug packets to/from this host */ +static net_sockaddr *rtpdebugaddr; /* Debug packets to/from this host */ #ifdef SO_NO_CHECK static int nochecksums = 0; #endif @@ -86,8 +86,8 @@ unsigned int dtmfduration; int nat; int flags; - struct sockaddr_in us; - struct sockaddr_in them; + net_sockaddr *us; + net_sockaddr *them; struct timeval rxcore; struct timeval txcore; struct timeval dtmfmute; @@ -109,12 +109,14 @@ struct ast_rtcp { int s; /* Socket */ - struct sockaddr_in us; - struct sockaddr_in them; + net_sockaddr *us; + net_sockaddr *them; }; static struct ast_rtp_protocol *protos = NULL; +static void ast_rtcp_destroy(struct ast_rtcp *rtcp); + int ast_rtp_fd(struct ast_rtp *rtp) { return rtp->s; @@ -187,13 +189,13 @@ if ((tv.tv_sec < rtp->dtmfmute.tv_sec) || ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) { if (option_debug) - ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr)); + ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", net_ntoa(iabuf, sizeof(iabuf), rtp->them)); rtp->resp = 0; rtp->dtmfduration = 0; return &null_frame; } if (option_debug) - ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr)); + ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, net_ntoa(iabuf, sizeof(iabuf), rtp->them)); if (rtp->resp == 'X') { rtp->f.frametype = AST_FRAME_CONTROL; rtp->f.subclass = AST_CONTROL_FLASH; @@ -211,15 +213,16 @@ } -static inline int rtp_debug_test_addr(struct sockaddr_in *addr) +static inline int rtp_debug_test_addr(net_sockaddr *addr) { if (rtpdebug == 0) return 0; - if (rtpdebugaddr.sin_addr.s_addr) { - if (((ntohs(rtpdebugaddr.sin_port) != 0) - && (rtpdebugaddr.sin_port != addr->sin_port)) - || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) - return 0; + if (rtpdebugaddr) { + if ((!net_addr_isportnull(rtpdebugaddr) && + net_addr_cmpport(rtpdebugaddr, addr)) + || net_addr_cmp(rtpdebugaddr, addr)) { + return 0; + } } return 1; } @@ -354,20 +357,17 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp) { static struct ast_frame null_frame = { AST_FRAME_NULL, }; - int len; int hdrlen = 8; int res; - struct sockaddr_in sin; + net_sockaddr *sin; unsigned int rtcpdata[1024]; char iabuf[INET_ADDRSTRLEN]; if (!rtp->rtcp) return &null_frame; - len = sizeof(sin); - - res = recvfrom(rtp->rtcp->s, rtcpdata, sizeof(rtcpdata), - 0, (struct sockaddr *)&sin, &len); + net_addr_alloca(&sin); + res = net_recvfrom(rtp->rtcp->s, rtcpdata, sizeof(rtcpdata), 0, sin); if (res < 0) { if (errno == EAGAIN) @@ -386,12 +386,12 @@ if (rtp->nat) { /* Send to whoever sent to us */ - if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || - (rtp->rtcp->them.sin_port != sin.sin_port)) { - memcpy(&rtp->them, &sin, sizeof(rtp->them)); + if (net_addr_cmp(rtp->rtcp->them, sin)) { + net_addr_cpy(rtp->them, sin); rtp->rxseqno = 0; - if (option_debug) - ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); + if (option_debug) { + ast_log(LOG_DEBUG, "RTP NAT: Using address %s\n", net_ntostr(iabuf, sizeof(iabuf), rtp->rtcp->them)); + } } } if (option_debug) @@ -424,8 +424,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp) { int res; - struct sockaddr_in sin; - int len; + net_sockaddr *sin; unsigned int seqno; int version; int payloadtype; @@ -438,12 +437,11 @@ unsigned int *rtpheader; static struct ast_frame *f, null_frame = { AST_FRAME_NULL, }; struct rtpPayloadType rtpPT; - - len = sizeof(sin); - + + net_addr_alloca(&sin); /* Cache where the header will go */ - res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, - 0, (struct sockaddr *)&sin, &len); + res = net_recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, + 0, sin); rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET); @@ -463,16 +461,16 @@ /* Ignore if the other side hasn't been given an address yet. */ - if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) + if (!rtp->them) { return &null_frame; + } if (rtp->nat) { /* Send to whoever sent to us */ - if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || - (rtp->them.sin_port != sin.sin_port)) { - memcpy(&rtp->them, &sin, sizeof(rtp->them)); + if (net_addr_cmp(rtp->them, sin)) { + net_addr_cpy(rtp->them, sin); rtp->rxseqno = 0; - ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port)); + ast_log(LOG_DEBUG, "RTP NAT: Using address %s\n", net_ntostr(iabuf, sizeof(iabuf), rtp->them)); } } @@ -481,8 +479,9 @@ /* Check RTP version */ version = (seqno & 0xC0000000) >> 30; - if (version != 2) + if (version != 2) { return &null_frame; + } payloadtype = (seqno & 0x7f0000) >> 16; mark = seqno & (1 << 23); @@ -500,9 +499,12 @@ return &null_frame; } - if(rtp_debug_test_addr(&sin)) - ast_verbose("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len %d)\n" - , ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); + if(rtp_debug_test_addr(sin)) { + ast_verbose("Got RTP packet from %s (type %d, seq %d, ts %d, len %d)\n" + , net_ntostr(iabuf, sizeof(iabuf), sin), payloadtype, seqno, timestamp,res - hdrlen); + } + +/* sin = NULL; */ rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); if (!rtpPT.isAstFormat) { @@ -848,40 +850,42 @@ return ""; } -static int rtp_socket(void) +static int rtp_socket(net_sockaddr *sa) { int s; long flags; - s = socket(AF_INET, SOCK_DGRAM, 0); + s = net_socket(sa); if (s > -1) { flags = fcntl(s, F_GETFL); fcntl(s, F_SETFL, flags | O_NONBLOCK); #ifdef SO_NO_CHECK if (nochecksums) - setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); + net_setnochecksums(s, nochecksums); #endif } return s; } -static struct ast_rtcp *ast_rtcp_new(void) +static struct ast_rtcp *ast_rtcp_new(int ai_family) { struct ast_rtcp *rtcp; rtcp = malloc(sizeof(struct ast_rtcp)); if (!rtcp) return NULL; memset(rtcp, 0, sizeof(struct ast_rtcp)); - rtcp->s = rtp_socket(); - rtcp->us.sin_family = AF_INET; + rtcp->us = net_addr_new(); + net_addr_init(rtcp->us, ai_family, SOCK_DGRAM, 0); + rtcp->them = net_addr_new(); + rtcp->s = rtp_socket(rtcp->us); if (rtcp->s < 0) { - free(rtcp); + ast_rtcp_destroy(rtcp); ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno)); return NULL; } return rtcp; } -struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr) +struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, net_sockaddr *addr) { struct ast_rtp *rtp; int x; @@ -891,19 +895,21 @@ if (!rtp) return NULL; memset(rtp, 0, sizeof(struct ast_rtp)); - rtp->them.sin_family = AF_INET; - rtp->us.sin_family = AF_INET; - rtp->s = rtp_socket(); + rtp->them = net_addr_new(); + net_addr_init(rtp->them, net_addr_getfamily(addr), SOCK_DGRAM, 0); + rtp->us = net_addr_new(); + net_addr_init(rtp->us, net_addr_getfamily(addr), SOCK_DGRAM, 0); + rtp->s = rtp_socket(rtp->us); rtp->ssrc = rand(); rtp->seqno = rand() & 0xffff; if (rtp->s < 0) { - free(rtp); + ast_rtp_destroy(rtp); ast_log(LOG_ERROR, "Unable to allocate socket: %s\n", strerror(errno)); return NULL; } if (sched && rtcpenable) { rtp->sched = sched; - rtp->rtcp = ast_rtcp_new(); + rtp->rtcp = ast_rtcp_new(net_addr_getfamily(addr)); } /* Find us a place */ x = (rand() % (rtpend-rtpstart)) + rtpstart; @@ -911,26 +917,22 @@ startplace = x; for (;;) { /* Must be an even port number by RTP spec */ - rtp->us.sin_port = htons(x); - rtp->us.sin_addr = addr; - if (rtp->rtcp) - rtp->rtcp->us.sin_port = htons(x + 1); - if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) && - (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us)))) + net_addr_cpy(rtp->us, addr); + net_addr_setport(rtp->us, x); + if (rtp->rtcp) { + net_addr_setport(rtp->rtcp->us, x + 1); + } + if (!(first = net_bind(rtp->s, rtp->us)) && + (!rtp->rtcp || !net_bind(rtp->rtcp->s, rtp->rtcp->us))) break; if (!first) { /* Primary bind succeeded! Gotta recreate it */ close(rtp->s); - rtp->s = rtp_socket(); + rtp->s = rtp_socket(rtp->us); } if (errno != EADDRINUSE) { ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno)); - close(rtp->s); - if (rtp->rtcp) { - close(rtp->rtcp->s); - free(rtp->rtcp); - } - free(rtp); + ast_rtp_destroy(rtp); return NULL; } x += 2; @@ -938,12 +940,7 @@ x = (rtpstart + 1) & ~1; if (x == startplace) { ast_log(LOG_ERROR, "No RTP ports remaining\n"); - close(rtp->s); - if (rtp->rtcp) { - close(rtp->rtcp->s); - free(rtp->rtcp); - } - free(rtp); + ast_rtp_destroy(rtp); return NULL; } } @@ -959,10 +956,14 @@ struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode) { - struct in_addr ia; + net_sockaddr *ia; + struct ast_rtp *res; - memset(&ia, 0, sizeof(ia)); - return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia); + net_addr_alloca(&ia); + net_addr_init(ia, PF_INET, SOCK_DGRAM, 0); + res = ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia); +/* net_addr_delete(ia); */ + return res; } int ast_rtp_settos(struct ast_rtp *rtp, int tos) @@ -974,36 +975,50 @@ return res; } -void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them) +void ast_rtp_set_peer(struct ast_rtp *rtp, net_sockaddr *them) { - rtp->them.sin_port = them->sin_port; - rtp->them.sin_addr = them->sin_addr; + if (net_addr_ishostnull(them) || net_addr_isportnull(them)) { + if (rtp->them) { + net_addr_delete(rtp->them); + rtp->them = NULL; + } + if (rtp->rtcp && rtp->rtcp->them) { + net_addr_delete(rtp->rtcp->them); + rtp->rtcp->them = NULL; + } + return; + } + + if (!rtp->them) { + rtp->them = net_addr_new(); + } + net_addr_cpy(rtp->them, them); if (rtp->rtcp) { - rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1); - rtp->rtcp->them.sin_addr = them->sin_addr; + if (!rtp->rtcp->them) { + rtp->rtcp->them = net_addr_new(); + } + net_addr_cpy(rtp->rtcp->them, them); + net_addr_setport(rtp->rtcp->them, + net_addr_getport(them) + 1); } rtp->rxseqno = 0; } -void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them) +void ast_rtp_get_peer(struct ast_rtp *rtp, net_sockaddr *them) { - them->sin_family = AF_INET; - them->sin_port = rtp->them.sin_port; - them->sin_addr = rtp->them.sin_addr; + net_addr_cpy(them, rtp->them); } -void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us) +void ast_rtp_get_us(struct ast_rtp *rtp, net_sockaddr *us) { - memcpy(us, &rtp->us, sizeof(rtp->us)); + net_addr_cpy(us, rtp->us); } void ast_rtp_stop(struct ast_rtp *rtp) { - memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr)); - memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port)); + net_addr_clr(rtp->them); if (rtp->rtcp) { - memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->them.sin_addr)); - memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->them.sin_port)); + net_addr_clr(rtp->rtcp->them); } } @@ -1025,6 +1040,20 @@ rtp->rxseqno = 0; } +static void ast_rtcp_destroy(struct ast_rtcp *rtcp) +{ + if (rtcp->s >= 0) { + close(rtcp->s); + } + if (rtcp->us) { + net_addr_delete(rtcp->us); + } + if (rtcp->them) { + net_addr_delete(rtcp->them); + } + free(rtcp); +} + void ast_rtp_destroy(struct ast_rtp *rtp) { if (rtp->smoother) @@ -1033,9 +1062,14 @@ ast_io_remove(rtp->io, rtp->ioid); if (rtp->s > -1) close(rtp->s); + if (rtp->us) { + net_addr_delete(rtp->us); + } + if (rtp->them) { + net_addr_delete(rtp->them); + } if (rtp->rtcp) { - close(rtp->rtcp->s); - free(rtp->rtcp); + ast_rtcp_destroy(rtp->rtcp); } free(rtp); } @@ -1093,7 +1127,7 @@ payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF); /* If we have no peer, return immediately */ - if (!rtp->them.sin_addr.s_addr) + if (!rtp->them) return 0; gettimeofday(&rtp->dtmfmute, NULL); @@ -1110,13 +1144,15 @@ rtpheader[2] = htonl(rtp->ssrc); rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0)); for (x=0;x<6;x++) { - if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { - res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); - if (res <0) - ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); - if(rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n" - , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen); + if (rtp->them) { + res = net_sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, rtp->them); + if (res <0) { + ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n", net_ntostr(iabuf, sizeof(iabuf), rtp->them), strerror(errno)); + } + if(rtp_debug_test_addr(rtp->them)) { + ast_verbose("Sent RTP packet to %s (type %d, seq %d, ts %d, len %d)\n" + , net_ntostr(iabuf, sizeof(iabuf), rtp->them), payload, rtp->seqno, rtp->lastts,res - hdrlen); + } } if (x == 2) { @@ -1145,7 +1181,7 @@ payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN); /* If we have no peer, return immediately */ - if (!rtp->them.sin_addr.s_addr) + if (!rtp->them) return 0; gettimeofday(&rtp->dtmfmute, NULL); @@ -1161,13 +1197,14 @@ rtpheader[1] = htonl(rtp->lastts); rtpheader[2] = htonl(rtp->ssrc); data[12] = level; - if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { - res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); - if (res <0) - ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); - if(rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n" - , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen); + if (rtp->them) { + res = net_sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, rtp->them); + if (res <0) { + ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s %s\n", net_ntostr(iabuf, sizeof(iabuf), rtp->them), strerror(errno)); + } + if(rtp_debug_test_addr(rtp->them)) + ast_verbose("Sent Comfort Noise RTP packet to %s (type %d, seq %d, ts %d, len %d)\n" + , net_ntostr(iabuf, sizeof(iabuf), rtp->them), payload, rtp->seqno, rtp->lastts,res - hdrlen); } return 0; @@ -1262,13 +1299,13 @@ put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts)); put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); - if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { - res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); + if (rtp->them) { + res = net_sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, rtp->them); if (res <0) - ast_log(LOG_NOTICE, "RTP Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); - if(rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n" - , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen); + ast_log(LOG_NOTICE, "RTP Transmission error to %s: %s\n", net_ntostr(iabuf, sizeof(iabuf), rtp->them), strerror(errno)); + if(rtp_debug_test_addr(rtp->them)) + ast_verbose("Sent RTP packet to %s (type %d, seq %d, ts %d, len %d)\n" + , net_ntostr(iabuf, sizeof(iabuf), rtp->them), codec, rtp->seqno, rtp->lastts,res - hdrlen); } rtp->seqno++; @@ -1285,7 +1322,7 @@ /* If we have no peer, return immediately */ - if (!rtp->them.sin_addr.s_addr) + if (!rtp->them) return 0; /* If there is no data length, return immediately */ @@ -1463,20 +1500,24 @@ struct ast_rtp *p0, *p1; struct ast_rtp *vp0, *vp1; struct ast_rtp_protocol *pr0, *pr1; - struct sockaddr_in ac0, ac1; - struct sockaddr_in vac0, vac1; - struct sockaddr_in t0, t1; - struct sockaddr_in vt0, vt1; + net_sockaddr *ac0, *ac1; + net_sockaddr *vac0, *vac1; + net_sockaddr *t0, *t1; + net_sockaddr *vt0, *vt1; char iabuf[INET_ADDRSTRLEN]; void *pvt0, *pvt1; int to; int codec0,codec1, oldcodec0, oldcodec1; - memset(&vt0, 0, sizeof(vt0)); - memset(&vt1, 0, sizeof(vt1)); - memset(&vac0, 0, sizeof(vac0)); - memset(&vac1, 0, sizeof(vac1)); + net_addr_alloca(&ac0); + net_addr_alloca(&ac1); + net_addr_alloca(&t0); + net_addr_alloca(&t1); + net_addr_alloca(&vt0); + net_addr_alloca(&vt1); + net_addr_alloca(&vac0); + net_addr_alloca(&vac1); /* if need DTMF, cant native bridge */ if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) @@ -1540,17 +1581,17 @@ ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name); else { /* Store RTP peer */ - ast_rtp_get_peer(p1, &ac1); + ast_rtp_get_peer(p1, ac1); if (vp1) - ast_rtp_get_peer(vp1, &vac1); + ast_rtp_get_peer(vp1, vac1); } if (pr1->set_rtp_peer(c1, p0, vp0, codec0)) ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name); else { /* Store RTP peer */ - ast_rtp_get_peer(p0, &ac0); + ast_rtp_get_peer(p0, ac0); if (vp0) - ast_rtp_get_peer(vp0, &vac0); + ast_rtp_get_peer(vp0, vac0); } ast_mutex_unlock(&c0->lock); ast_mutex_unlock(&c1->lock); @@ -1576,44 +1617,44 @@ return -3; } to = -1; - ast_rtp_get_peer(p1, &t1); - ast_rtp_get_peer(p0, &t0); + ast_rtp_get_peer(p1, t1); + ast_rtp_get_peer(p0, t0); if (pr0->get_codec) codec0 = pr0->get_codec(c0); if (pr1->get_codec) codec1 = pr1->get_codec(c1); if (vp1) - ast_rtp_get_peer(vp1, &vt1); + ast_rtp_get_peer(vp1, vt1); if (vp0) - ast_rtp_get_peer(vp0, &vt0); - if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) { + ast_rtp_get_peer(vp0, vt0); + if (net_addr_cmp(t1, ac1) || (vp1 && net_addr_cmp(vt1, vac1)) || (codec1 != oldcodec1)) { if (option_debug) { - ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", - c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1); - ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", - c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1); - ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", - c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1); - ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s:%d/(format %d)\n", - c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1); + ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s (format %d)\n", + c1->name, net_ntostr(iabuf, sizeof(iabuf), t1), codec1); + ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s (format %d)\n", + c1->name, net_ntostr(iabuf, sizeof(iabuf), vt1), codec1); + ast_log(LOG_DEBUG, "Oooh, '%s' was %s/(format %d)\n", + c1->name, net_ntostr(iabuf, sizeof(iabuf), ac1), oldcodec1); + ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s/(format %d)\n", + c1->name, net_ntostr(iabuf, sizeof(iabuf), vac1), oldcodec1); } - if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1)) + if (pr0->set_rtp_peer(c0, !net_addr_ishostnull(t1) ? p1 : NULL, !net_addr_ishostnull(vt1) ? vp1 : NULL, codec1)) ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name); - memcpy(&ac1, &t1, sizeof(ac1)); - memcpy(&vac1, &vt1, sizeof(vac1)); + net_addr_cpy(ac1, t1); + net_addr_cpy(vac1, vt1); oldcodec1 = codec1; } - if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) { + if (net_addr_cmp(t0, ac0) || (vp0 && net_addr_cmp(vt0, vac0))) { if (option_debug) { - ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", - c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0); - ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", - c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0); + ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %sd (format %d)\n", + c0->name, net_ntostr(iabuf, sizeof(iabuf), t0), codec0); + ast_log(LOG_DEBUG, "Oooh, '%s' was %s/(format %d)\n", + c0->name, net_ntostr(iabuf, sizeof(iabuf), ac0), oldcodec0); } - if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0)) + if (pr1->set_rtp_peer(c1, !net_addr_ishostnull(t0) ? p0 : NULL, !net_addr_ishostnull(vt0) ? vp0 : NULL, codec0)) ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name); - memcpy(&ac0, &t0, sizeof(ac0)); - memcpy(&vac0, &vt0, sizeof(vac0)); + net_addr_cpy(ac0, t0); + net_addr_cpy(vac0, vt0); oldcodec0 = codec0; } who = ast_waitfor_n(cs, 2, &to); @@ -1667,31 +1708,27 @@ static int rtp_do_debug_ip(int fd, int argc, char *argv[]) { - struct hostent *hp; - struct ast_hostent ahp; char iabuf[INET_ADDRSTRLEN]; int port = 0; - char *p, *arg; + char *arg; - if (argc != 4) + if (argc != 4 && argc != 5) return RESULT_SHOWUSAGE; arg = argv[3]; - p = strstr(arg, ":"); - if (p) { - *p = '\0'; - p++; - port = atoi(p); + if (argc == 5) { + port = atoi(argv[4]); + } + if (!rtpdebugaddr) { + rtpdebugaddr = net_addr_new(); } - hp = ast_gethostbyname(arg, &ahp); - if (hp == NULL) + if (net_addr_get(rtpdebugaddr, arg) < 0) { return RESULT_SHOWUSAGE; - rtpdebugaddr.sin_family = AF_INET; - memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr)); - rtpdebugaddr.sin_port = htons(port); + } + net_addr_setport(rtpdebugaddr, port); if (port == 0) - ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr)); + ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", net_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr)); else - ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr), port); + ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", net_ntostr(iabuf, sizeof(iabuf), rtpdebugaddr)); rtpdebug = 1; return RESULT_SUCCESS; } @@ -1704,7 +1741,10 @@ return rtp_do_debug_ip(fd, argc, argv); } rtpdebug = 1; - memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr)); + if (rtpdebugaddr) { + net_addr_delete(rtpdebugaddr); + rtpdebugaddr = NULL; + } ast_cli(fd, "RTP Debugging Enabled\n"); return RESULT_SUCCESS; } Index: channels/Makefile =================================================================== RCS file: /usr/cvsroot/asterisk/channels/Makefile,v retrieving revision 1.68 diff -u -r1.68 Makefile --- channels/Makefile 28 Mar 2005 16:28:00 -0000 1.68 +++ channels/Makefile 4 Apr 2005 20:50:11 -0000 @@ -22,11 +22,13 @@ HOSTCC=gcc endif -CHANNEL_LIBS=chan_modem.so chan_sip.so \ - chan_modem_aopen.so \ - chan_modem_bestdata.so \ - chan_agent.so chan_mgcp.so chan_iax2.so \ - chan_local.so chan_skinny.so chan_features.so +# CHANNEL_LIBS=chan_modem.so chan_sip.so \ +# chan_modem_aopen.so \ +# chan_modem_bestdata.so \ +# chan_agent.so chan_mgcp.so chan_iax2.so \ +# chan_local.so chan_skinny.so chan_features.so + +CHANNEL_LIBS=chan_sip.so chan_iax2.so ifeq (${OSARCH},OpenBSD) CFLAGS+=-I$(CROSS_COMPILE_TARGET)/usr/local/include @@ -93,8 +95,8 @@ ZAPDIR=/usr/lib -CHANNEL_LIBS+=$(shell [ -f $(CROSS_COMPILE_TARGET)/usr/include/linux/zaptel.h ] && echo "chan_zap.so") -CHANNEL_LIBS+=$(shell [ -f $(CROSS_COMPILE_TARGET)/usr/local/include/zaptel.h ] && echo "chan_zap.so") +#CHANNEL_LIBS+=$(shell [ -f $(CROSS_COMPILE_TARGET)/usr/include/linux/zaptel.h ] && echo "chan_zap.so") +#CHANNEL_LIBS+=$(shell [ -f $(CROSS_COMPILE_TARGET)/usr/local/include/zaptel.h ] && echo "chan_zap.so") CHANNEL_LIBS+=$(shell [ -f $(CROSS_COMPILE_TARGET)/usr/include/nbs.h ] && echo "chan_nbs.so" ) Index: channels/chan_iax2.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v retrieving revision 1.264 diff -u -r1.264 chan_iax2.c --- channels/chan_iax2.c 1 Apr 2005 15:52:26 -0000 1.264 +++ channels/chan_iax2.c 4 Apr 2005 20:50:15 -0000 @@ -265,14 +265,14 @@ char peercontext[AST_MAX_EXTENSION]; /* Context to pass to peer */ char mailbox[AST_MAX_EXTENSION]; /* Mailbox */ struct ast_codec_pref prefs; - struct sockaddr_in addr; + net_sockaddr *addr; int formats; int sockfd; /* Socket to use for transmission */ - struct in_addr mask; + net_sockaddr *mask; unsigned int flags; /* Dynamic Registration fields */ - struct sockaddr_in defaddr; /* Default address if there is one */ + net_sockaddr *defaddr; /* Default address if there is one */ int authmethods; /* Authentication methods (IAX_AUTH_*) */ int encmethods; /* Encryption methods (IAX_ENCRYPT_*) */ char inkeys[80]; /* Key(s) this peer can use to authenticate to us */ @@ -301,7 +301,7 @@ static struct iax2_trunk_peer { ast_mutex_t lock; int sockfd; - struct sockaddr_in addr; + net_sockaddr *addr; /* */ struct timeval txtrunktime; /* Transmit trunktime */ struct timeval rxtrunktime; /* Receive trunktime */ struct timeval lasttxtime; /* Last transmitted trunktime */ @@ -342,7 +342,7 @@ #define TRANSFER_PASSTHROUGH 4 struct iax2_registry { - struct sockaddr_in addr; /* Who we connect to for registration purposes */ + net_sockaddr *addr; /* Who we connect to for registration purposes */ char username[80]; char secret[80]; /* Password or key name in []'s */ char random[80]; @@ -351,7 +351,7 @@ int regstate; int messages; /* Message count */ int callno; /* Associated call number if applicable */ - struct sockaddr_in us; /* Who the server thinks we are */ + net_sockaddr *us; /* Who the server thinks we are */ struct iax2_registry *next; }; @@ -413,7 +413,7 @@ /* Max time for initial response */ int maxtime; /* Peer Address */ - struct sockaddr_in addr; + net_sockaddr *addr; struct ast_codec_pref prefs; /* Our call number */ unsigned short callno; @@ -509,7 +509,7 @@ /* Transfer identifier */ int transferid; /* Who we are IAX transfering to */ - struct sockaddr_in transfer; + net_sockaddr *transfer; /* What's the new call number for the transfer */ unsigned short transfercallno; /* Transfer decrypt AES-128 Key */ @@ -671,7 +671,7 @@ static int iax2_do_register(struct iax2_registry *reg); static void prune_peers(void); static int iax2_poke_peer(struct iax2_peer *peer, int heldcall); -static int iax2_provision(struct sockaddr_in *end, char *dest, const char *template, int force); +static int iax2_provision(net_sockaddr *end, char *dest, const char *template, int force); static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause); static int iax2_devicestate(void *data); @@ -803,7 +803,7 @@ return peer; } -static int iax2_getpeername(struct sockaddr_in sin, char *host, int len, int lockpeer) +static int iax2_getpeername(net_sockaddr *sin, char *host, int len, int lockpeer) { struct iax2_peer *peer; int res = 0; @@ -811,8 +811,7 @@ ast_mutex_lock(&peerl.lock); peer = peerl.peers; while(peer) { - if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && - (peer->addr.sin_port == sin.sin_port)) { + if (!net_addr_cmp(peer->addr, sin)) { strncpy(host, peer->name, len-1); res = 1; break; @@ -824,7 +823,7 @@ return res; } -static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, const char *host) +static struct chan_iax2_pvt *new_iax(net_sockaddr *sin, int lockpeer, const char *host) { struct chan_iax2_pvt *tmp; tmp = malloc(sizeof(struct chan_iax2_pvt)); @@ -918,19 +917,25 @@ #define NEW_ALLOW 1 #define NEW_FORCE 2 -static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur) +static int match(net_sockaddr *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur) { - if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->addr.sin_port == sin->sin_port)) { + if (!net_addr_cmp(cur->addr, sin)) { /* This is the main host */ if ((cur->peercallno == callno) || ((dcallno == cur->callno) && !cur->peercallno)) { /* That's us. Be sure we keep track of the peer call number */ return 1; } + } else { + char buf1[NET_ADDRSTRLEN]; + char buf2[NET_ADDRSTRLEN]; + ast_log(LOG_NOTICE, "Diff: %d %s %d %s\n", + net_addr_getfamily(cur->addr), + net_ntoa(buf1, sizeof(buf1), cur->addr), + net_addr_getfamily(sin), + net_ntoa(buf2, sizeof(buf2), sin)); } - if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { + if ((cur->transferring) && !net_addr_cmp(cur->transfer, sin)) { /* We're transferring */ if (dcallno == cur->callno) return 1; @@ -1013,12 +1018,12 @@ return res; } -static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd) +static int find_callno(unsigned short callno, unsigned short dcallno, net_sockaddr *sin, int new, int lockpeer, int sockfd) { int res = 0; int x; struct timeval now; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char host[80]; if (new <= NEW_ALLOW) { /* Look for an existing connection first */ @@ -1044,8 +1049,8 @@ } } if ((res < 1) && (new >= NEW_ALLOW)) { - if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) - snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); + if (!iax2_getpeername(sin, host, sizeof(host), lockpeer)) + snprintf(host, sizeof(host), "%s:%d", net_ntoa(iabuf, sizeof(iabuf), sin), net_addr_getport(sin)); gettimeofday(&now, NULL); for (x=1;xsockfd = sockfd; - iaxs[x]->addr.sin_port = sin->sin_port; - iaxs[x]->addr.sin_family = sin->sin_family; - iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; + iaxs[x]->addr = net_addr_new(); + net_addr_cpy(iaxs[x]->addr, sin); iaxs[x]->peercallno = callno; iaxs[x]->callno = x; iaxs[x]->pingtime = DEFAULT_RETRY_TIME; @@ -1430,7 +1434,7 @@ if (m.msg_controllen) { sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); if (sin) - ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_WARNING, "Receive error from %s\n", net_ntoa(iabuf, sizeof(iabuf), sin)); else ast_log(LOG_WARNING, "No address detected??\n"); } else { @@ -1441,11 +1445,10 @@ return 0; } -static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd) +static int transmit_trunk(struct iax_frame *f, net_sockaddr *sin, int sockfd) { int res; - res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, - sizeof(*sin)); + res = net_sendto(sockfd, f->data, f->datalen, 0, sin); if (res < 0) { if (option_debug) ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); @@ -1458,10 +1461,10 @@ static int send_packet(struct iax_frame *f) { int res; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; /* Called with iaxsl held */ if (option_debug) - ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port)); + ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s\n", f->ts, f->callno, iaxs[f->callno]->peercallno, net_ntostr(iabuf, sizeof(iabuf), iaxs[f->callno]->addr)); /* Don't send if there was an error, but return error instead */ if (!f->callno) { ast_log(LOG_WARNING, "Call number = %d\n", f->callno); @@ -1473,14 +1476,12 @@ return -1; if (f->transfer) { if (iaxdebug) - iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); - res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer, - sizeof(iaxs[f->callno]->transfer)); + iax_showframe(f, NULL, 0, iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); + res = net_sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0, iaxs[f->callno]->transfer); } else { if (iaxdebug) - iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); - res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr, - sizeof(iaxs[f->callno]->addr)); + iax_showframe(f, NULL, 0, iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); + res = net_sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0, iaxs[f->callno]->addr); } if (res < 0) { if (option_debug) @@ -1604,6 +1605,14 @@ if (pvt->bridgetrans) ast_translator_free_path(pvt->bridgetrans); pvt->bridgetrans = NULL; + if (pvt->addr) { + net_addr_delete(pvt->addr); + pvt->addr = NULL; + } + if (pvt->transfer) { + net_addr_delete(pvt->transfer); + pvt->addr = NULL; + } /* Already gone */ ast_set_flag(pvt, IAX_ALREADYGONE); @@ -1672,7 +1681,7 @@ struct iax_frame *f = data; int freeme=0; int callno = f->callno; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; /* Make sure this call is still active */ if (callno) ast_mutex_lock(&iaxsl[callno]); @@ -1689,7 +1698,7 @@ iax2_destroy_nolock(f->callno); } else { if (iaxs[f->callno]->owner) - ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); + ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", net_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); iaxs[f->callno]->error = ETIMEDOUT; if (iaxs[f->callno]->owner) { struct ast_frame fr = { 0, }; @@ -1702,7 +1711,7 @@ iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; } else { if (iaxs[f->callno]->reg) { - memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us)); + net_addr_clr(iaxs[f->callno]->reg->us); iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT; iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; } @@ -1830,7 +1839,7 @@ { char status[30] = ""; char cbuf[256]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct iax2_peer *peer; char codec_buf[512]; int x = 0, codec = 0, load_realtime = 0; @@ -1851,8 +1860,8 @@ ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); ast_cli(fd, " Expire : %d\n", peer->expire); ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); - ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); - ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); + ast_cli(fd, " Addr->IP : %s Port %d\n", !net_addr_ishostnull(peer->addr) ? net_ntoa(iabuf, sizeof(iabuf), peer->addr) : "(Unspecified)", net_addr_getport(peer->addr)); + ast_cli(fd, " Defaddr->IP : %s Port %d\n", net_ntoa(iabuf, sizeof(iabuf), peer->defaddr), net_addr_getport(peer->defaddr)); ast_cli(fd, " Username : %s\n", peer->username); ast_cli(fd, " Codecs : "); ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); @@ -2035,7 +2044,7 @@ static int forward_delivery(struct iax_frame *fr) { struct chan_iax2_pvt *p1, *p2; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int res, orig_ts; p1 = iaxs[fr->callno]; @@ -2046,12 +2055,11 @@ return -1; if (option_debug) - ast_log(LOG_DEBUG, "forward_delivery: Forwarding ts=%d on %d/%d to %d/%d on %s:%d\n", + ast_log(LOG_DEBUG, "forward_delivery: Forwarding ts=%d on %d/%d to %d/%d on %s\n", fr->ts, p1->callno, p1->peercallno, p2->callno, p2->peercallno, - ast_inet_ntoa(iabuf, sizeof(iabuf), p2->addr.sin_addr), - ntohs(p2->addr.sin_port)); + net_ntostr(iabuf, sizeof(iabuf), p2->addr)); /* Undo wraparound - which can happen when full VOICE frame wasn't sent by our peer. This is necessary for when our peer is chan_iax2.c v1.1nn or earlier which didn't @@ -2562,9 +2570,9 @@ if (sscanf(tmp->value, "%li", ®seconds) != 1) regseconds = 0; } else if (!strcasecmp(tmp->name, "ipaddr")) { - inet_aton(tmp->value, &(peer->addr.sin_addr)); + net_aton(tmp->value, peer->addr); } else if (!strcasecmp(tmp->name, "port")) { - peer->addr.sin_port = htons(atoi(tmp->value)); + net_addr_setport(peer->addr, atoi(tmp->value)); } else if (!strcasecmp(tmp->name, "host")) { if (!strcasecmp(tmp->value, "dynamic")) dynamic = 1; @@ -2592,7 +2600,7 @@ if (peer && dynamic) { time(&nowtime); if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { - memset(&peer->addr, 0, sizeof(peer->addr)); + net_addr_clr(peer->addr); if (option_debug) ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime); } @@ -2642,7 +2650,7 @@ return user; } -static void realtime_update_peer(const char *peername, struct sockaddr_in *sin) +static void realtime_update_peer(const char *peername, net_sockaddr *sin) { char port[10]; char ipaddr[20]; @@ -2651,20 +2659,19 @@ time(&nowtime); snprintf(regseconds, sizeof(regseconds), "%ld", nowtime); - ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); - snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); + net_ntoa(ipaddr, sizeof(ipaddr), sin); + snprintf(port, sizeof(port), "%d", net_addr_getport(sin)); ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL); } -static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, +static int create_addr(net_sockaddr *sin, int *capability, int *sendani, int *maxtime, char *peer, char *context, int *trunk, int *notransfer, int *usejitterbuf, int *forcejitterbuf, int *encmethods, char *username, int usernlen, char *secret, int seclen, int *ofound, char *peercontext, char *timezone, int tzlen, char *pref_str, size_t pref_size, int *sockfd) { - struct ast_hostent ahp; struct hostent *hp; struct iax2_peer *p; int found=0; if (sendani) @@ -2675,11 +2682,11 @@ *trunk = 0; if (sockfd) *sockfd = defaultsockfd; - sin->sin_family = AF_INET; +/* sin->sin_family = AF_INET; */ p = find_peer(peer, 1); if (p) { found++; - if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && + if ((!net_addr_ishostnull(p->addr) || !net_addr_ishostnull(p->defaddr)) && (!p->maxms || ((p->lastms > 0) && (p->lastms <= p->maxms)))) { if(pref_str) { @@ -2701,12 +2708,10 @@ *encmethods = p->encmethods; if (username) strncpy(username, p->username, usernlen); - if (p->addr.sin_addr.s_addr) { - sin->sin_addr = p->addr.sin_addr; - sin->sin_port = p->addr.sin_port; + if (!net_addr_ishostnull(p->addr)) { + net_addr_cpy(sin, p->addr); } else { - sin->sin_addr = p->defaddr.sin_addr; - sin->sin_port = p->defaddr.sin_port; + net_addr_cpy(sin, p->defaddr); } if (sockfd) *sockfd = p->sockfd; @@ -2751,10 +2756,8 @@ ast_codec_pref_convert(&prefs, pref_str, pref_size, 1); } - hp = ast_gethostbyname(peer, &ahp); - if (hp) { - memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); - sin->sin_port = htons(IAX_DEFAULT_PORTNO); + if(!net_addr_get(sin, peer)) { + net_addr_setport(sin, IAX_DEFAULT_PORTNO); return 0; } else { ast_log(LOG_WARNING, "No such host: %s\n", peer); @@ -2801,7 +2804,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) { - struct sockaddr_in sin; + net_sockaddr *sin; char host[256]; char *rdest; char *rcontext; @@ -2822,6 +2825,7 @@ char tz[80] = ""; char out_prefs[32]; + net_addr_alloca(&sin); memset(out_prefs,0,32); if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { @@ -2865,14 +2869,14 @@ strsep(&stringp, ":"); portno = strsep(&stringp, ":"); } - if (create_addr(&sin, NULL, NULL, NULL, hname, context, NULL, NULL, NULL, NULL, &encmethods, storedusern, sizeof(storedusern) - 1, storedsecret, sizeof(storedsecret) - 1, NULL, peercontext, tz, sizeof(tz), out_prefs, sizeof(out_prefs), NULL)) { + if (create_addr(sin, NULL, NULL, NULL, hname, context, NULL, NULL, NULL, NULL, &encmethods, storedusern, sizeof(storedusern) - 1, storedsecret, sizeof(storedsecret) - 1, NULL, peercontext, tz, sizeof(tz), out_prefs, sizeof(out_prefs), NULL)) { ast_log(LOG_WARNING, "No address associated with '%s'\n", hname); return -1; } /* Keep track of the context for outgoing calls too */ strncpy(c->context, context, sizeof(c->context) - 1); if (portno) { - sin.sin_port = htons(atoi(portno)); + net_addr_setport(sin, atoi(portno)); } l = c->cid.cid_num; n = c->cid.cid_name; @@ -3016,12 +3020,12 @@ struct iax_ie_data ied1; unsigned int transferid = rand(); memset(&ied0, 0, sizeof(ied0)); - iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); + iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, iaxs[callno1]->addr); iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); memset(&ied1, 0, sizeof(ied1)); - iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); + iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, iaxs[callno0]->addr); iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); @@ -3250,15 +3254,14 @@ static int iax2_write(struct ast_channel *c, struct ast_frame *f); -static int iax2_getpeertrunk(struct sockaddr_in sin) +static int iax2_getpeertrunk(net_sockaddr *sin) { struct iax2_peer *peer; int res = 0; ast_mutex_lock(&peerl.lock); peer = peerl.peers; while(peer) { - if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && - (peer->addr.sin_port == sin.sin_port)) { + if (!net_addr_cmp(peer->addr, sin)) { res = ast_test_flag(peer, IAX_TRUNK); break; } @@ -3555,16 +3558,16 @@ return ms; } -static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd) +static struct iax2_trunk_peer *find_tpeer(net_sockaddr *sin, int fd) { struct iax2_trunk_peer *tpeer; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; /* Finds and locks trunk peer */ ast_mutex_lock(&tpeerlock); tpeer = tpeers; while(tpeer) { /* We don't lock here because tpeer->addr *never* changes */ - if (!inaddrcmp(&tpeer->addr, sin)) { + if (!net_addr_cmp(tpeer->addr, sin)) { ast_mutex_lock(&tpeer->lock); break; } @@ -3576,16 +3579,16 @@ memset(tpeer, 0, sizeof(struct iax2_trunk_peer)); ast_mutex_init(&tpeer->lock); tpeer->lastsent = 9999; - memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); + net_addr_cpy(tpeer->addr, sin); gettimeofday(&tpeer->trunkact, NULL); ast_mutex_lock(&tpeer->lock); tpeer->next = tpeers; tpeer->sockfd = fd; tpeers = tpeer; #ifdef SO_NO_CHECK - setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); + net_setnochecksums(tpeer->sockfd, nochecksums); #endif - ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); + ast_log(LOG_DEBUG, "Created trunk peer for '%s'\n", net_ntostr(iabuf, sizeof(iabuf), tpeer->addr)); } } ast_mutex_unlock(&tpeerlock); @@ -3599,10 +3602,10 @@ void *tmp, *ptr; struct ast_iax2_meta_trunk_entry *met; struct ast_iax2_meta_trunk_mini *mtm; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; f = &fr->af; - tpeer = find_tpeer(&pvt->addr, pvt->sockfd); + tpeer = find_tpeer(pvt->addr, pvt->sockfd); if (tpeer) { if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { /* Need to reallocate space */ @@ -3611,14 +3614,14 @@ if (tmp) { tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; tpeer->trunkdata = tmp; - ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); + ast_log(LOG_DEBUG, "Expanded trunk '%s' to %d bytes\n", net_ntostr(iabuf, sizeof(iabuf), tpeer->addr), tpeer->trunkdataalloc); } else { - ast_log(LOG_WARNING, "Insufficient memory to expand trunk data to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); + ast_log(LOG_WARNING, "Insufficient memory to expand trunk data to %s\n", net_ntostr(iabuf, sizeof(iabuf), tpeer->addr)); ast_mutex_unlock(&tpeer->lock); return -1; } } else { - ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); + ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s\n", net_ntostr(iabuf, sizeof(iabuf), tpeer->addr)); ast_mutex_unlock(&tpeer->lock); return -1; } @@ -4035,7 +4038,7 @@ struct iax2_peer *peer; char name[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int registeredonly=0; if (argc > 5) @@ -4076,7 +4079,7 @@ char status[20] = ""; char srch[2000] = ""; - if (registeredonly && !peer->addr.sin_addr.s_addr) + if (registeredonly && net_addr_ishostnull(peer->addr)) continue; if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) continue; @@ -4106,20 +4109,20 @@ strncpy(status, "Unmonitored", sizeof(status) - 1); unmonitored_peers++; } - strncpy(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm)-1); + strncpy(nm, net_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm)-1); snprintf(srch, sizeof(srch), FORMAT, name, - peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", + !net_addr_ishostnull(peer->addr) ? net_ntoa(iabuf, sizeof(iabuf), peer->addr) : "(Unspecified)", ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", nm, - ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", + net_addr_getport(peer->addr), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", peer->encmethods ? "(E)" : " ", status); ast_cli(fd, FORMAT, name, - peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", + !net_addr_ishostnull(peer->addr) ? net_ntoa(iabuf, sizeof(iabuf), peer->addr) : "(Unspecified)", ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", nm, - ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", + net_addr_getport(peer->addr), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", peer->encmethods ? "(E)" : " ", status); total_peers++; } @@ -4195,15 +4198,15 @@ struct iax2_registry *reg; char host[80]; char perceived[80] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (argc != 3) return RESULT_SHOWUSAGE; ast_mutex_lock(&peerl.lock); ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State"); for (reg = registrations;reg;reg = reg->next) { - snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port)); - if (reg->us.sin_addr.s_addr) - snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); + snprintf(host, sizeof(host), "%s:%d", net_ntoa(iabuf, sizeof(iabuf), reg->addr), net_addr_getport(reg->addr)); + if (!net_addr_ishostnull(reg->us)) + snprintf(perceived, sizeof(perceived), "%s", net_ntostr(iabuf, sizeof(iabuf), reg->us)); else strncpy(perceived, "", sizeof(perceived) - 1); ast_cli(fd, FORMAT, host, @@ -4237,7 +4240,7 @@ #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" int x; int numchans = 0; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (argc != 3) return RESULT_SHOWUSAGE; @@ -4249,7 +4252,7 @@ if (iaxs[x]->bridgecallno) ast_cli(fd, FORMATB, iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", - ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), + net_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr), !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", iaxs[x]->callno, iaxs[x]->peercallno, iaxs[x]->oseqno, iaxs[x]->iseqno, @@ -4276,7 +4279,7 @@ lag = iaxs[x]->remote_rr.delay; ast_cli(fd, FORMAT, iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", - ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), + net_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr), !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", iaxs[x]->callno, iaxs[x]->peercallno, iaxs[x]->oseqno, iaxs[x]->iseqno, @@ -4564,7 +4567,7 @@ } -static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies) +static int check_access(int callno, net_sockaddr *sin, struct iax_ies *ies) { /* Start pessimistic */ int res = -1; @@ -4572,7 +4575,7 @@ struct iax2_user *user, *best = NULL; int bestscore = 0; int gotcapability=0; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct ast_variable *v = NULL, *tmpvar = NULL; if (!iaxs[callno]) @@ -4619,7 +4622,7 @@ iaxs[callno]->peercapability = iaxs[callno]->peerformat; if (version > IAX_PROTO_VERSION) { ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version); + net_ntoa(iabuf, sizeof(iabuf), sin), version); return res; } ast_mutex_lock(&userl.lock); @@ -4751,14 +4754,14 @@ strncpy(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret) - 1); res = 0; } - ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); + ast_set2_flag(iaxs[callno], iax2_getpeertrunk(sin), IAX_TRUNK); return res; } -static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) +static int raw_hangup(net_sockaddr *sin, unsigned short src, unsigned short dst, int sockfd) { struct ast_iax2_full_hdr fh; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; fh.scallno = htons(src | IAX_FLAG_FULL); fh.dcallno = htons(dst); fh.ts = 0; @@ -4769,9 +4772,9 @@ #if 0 if (option_debug) #endif - ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst); - return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); + ast_log(LOG_DEBUG, "Raw Hangup %s, src=%d, dst=%d\n", + net_ntostr(iabuf, sizeof(iabuf), sin), src, dst); + return net_sendto(sockfd, &fh, sizeof(fh), 0, sin); } static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc) @@ -4866,14 +4869,14 @@ return res; } -static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies) +static int register_verify(int callno, net_sockaddr *sin, struct iax_ies *ies) { char requeststr[256] = ""; char peer[256] = ""; char md5secret[256] = ""; char rsasecret[256] = ""; char secret[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct iax2_peer *p; struct ast_key *key; char *keyn; @@ -4894,7 +4897,7 @@ expire = ies->refresh; if (ast_strlen_zero(peer)) { - ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "Empty registration from %s\n", net_ntoa(iabuf, sizeof(iabuf), sin)); return -1; } /* We release the lock for the call to prevent a deadlock, but it's okay because @@ -4905,13 +4908,13 @@ if (!p) { if (authdebug) - ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, net_ntoa(iabuf, sizeof(iabuf), sin)); return -1; } if (!ast_test_flag(p, IAX_DYNAMIC)) { if (authdebug) - ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, net_ntoa(iabuf, sizeof(iabuf), sin)); if (ast_test_flag(p, IAX_TEMPONLY)) destroy_peer(p); return -1; @@ -4919,7 +4922,7 @@ if (!ast_apply_ha(p->ha, sin)) { if (authdebug) - ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name); + ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin), p->name); if (ast_test_flag(p, IAX_TEMPONLY)) destroy_peer(p); return -1; @@ -4961,7 +4964,7 @@ /* They've provided a plain text password and we support that */ if (strcmp(secret, p->secret)) { if (authdebug) - ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name); + ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin), p->name); if (ast_test_flag(p, IAX_TEMPONLY)) destroy_peer(p); return -1; @@ -4988,7 +4991,7 @@ iaxs[callno]->state |= IAX_STATE_AUTHENTICATED; } else { if (authdebug) - ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name, requeststr, md5secret); + ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", net_ntoa(iabuf, sizeof(iabuf), sin), p->name, requeststr, md5secret); if (ast_test_flag(p, IAX_TEMPONLY)) destroy_peer(p); return -1; @@ -5013,17 +5016,17 @@ } -static int authenticate(char *challenge, char *secret, char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) +static int authenticate(char *challenge, char *secret, char *keyn, int authmethods, struct iax_ie_data *ied, net_sockaddr *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) { int res = -1; int x; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (keyn && !ast_strlen_zero(keyn)) { if (!(authmethods & IAX_AUTH_RSA)) { if (!secret || ast_strlen_zero(secret)) - ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", net_ntoa(iabuf, sizeof(iabuf), sin)); } else if (ast_strlen_zero(challenge)) { - ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", net_ntoa(iabuf, sizeof(iabuf), sin)); } else { char sig[256]; struct ast_key *key; @@ -5062,12 +5065,12 @@ iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); res = 0; } else - ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), authmethods); + ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", net_ntoa(iabuf, sizeof(iabuf), sin), authmethods); } return res; } -static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey) +static int authenticate_reply(struct chan_iax2_pvt *p, net_sockaddr *sin, struct iax_ies *ies, char *override, char *okey) { struct iax2_peer *peer; /* Start pessimistic */ @@ -5096,11 +5099,16 @@ ast_mutex_lock(&peerl.lock); peer = peerl.peers; while(peer) { + net_sockaddr *addr; + net_addr_alloca(&addr); + net_addr_cpy(addr, peer->addr); + net_addr_andmask(addr, peer->mask); + if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) /* No peer specified at our end, or this is the peer */ && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) /* No username specified in peer rule, or this is the right username */ - && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr))) + && (net_addr_ishostnull(peer->addr) || ((net_addr_checkmask(sin, addr, peer->mask)))) /* No specified host, or this is our host */ ) { res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); @@ -5133,22 +5141,24 @@ int newcall = 0; char newip[256] = ""; struct iax_ie_data ied; - struct sockaddr_in new; - + net_sockaddr *new; + net_addr_alloca(&new); memset(&ied, 0, sizeof(ied)); if (ies->apparent_addr) - memcpy(&new, ies->apparent_addr, sizeof(new)); + net_addr_cpy(new, ies->apparent_addr); if (ies->callno) newcall = ies->callno; - if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { + if (!newcall || net_addr_ishostnull(new) || net_addr_isportnull(new)) { ast_log(LOG_WARNING, "Invalid transfer request\n"); return -1; } pvt->transfercallno = newcall; - memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); - inet_aton(newip, &pvt->transfer.sin_addr); - pvt->transfer.sin_family = AF_INET; + if (!pvt->transfer) + pvt->transfer = net_addr_new(); + net_addr_cpy(pvt->transfer, new); + net_aton(newip, pvt->transfer); + net_addr_cpyport(pvt->transfer, new); pvt->transferring = TRANSFER_BEGIN; pvt->transferid = ies->transferid; if (ies->transferid) @@ -5226,8 +5236,9 @@ ast_log(LOG_WARNING, "Invalid transfer request\n"); return -1; } - memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); - memset(&pvt->transfer, 0, sizeof(pvt->transfer)); + net_addr_cpy(pvt->addr, pvt->transfer); + net_addr_delete(pvt->transfer); + pvt->transfer = NULL; /* Reset sequence numbers */ pvt->oseqno = 0; pvt->iseqno = 0; @@ -5272,7 +5283,7 @@ return 0; } -static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno) +static int iax2_ack_registry(struct iax_ies *ies, net_sockaddr *sin, int callno) { struct iax2_registry *reg; /* Start pessimistic */ @@ -5280,14 +5291,15 @@ char msgstatus[40] = ""; int refresh = 0; char ourip[256] = ""; - struct sockaddr_in oldus; - struct sockaddr_in us; - char iabuf[INET_ADDRSTRLEN]; + net_sockaddr *oldus; + net_sockaddr *us; + char iabuf[NET_ADDRSTRLEN]; int oldmsgs; - memset(&us, 0, sizeof(us)); + net_addr_alloca(&oldus); + net_addr_alloca(&us); if (ies->apparent_addr) - memcpy(&us, ies->apparent_addr, sizeof(us)); + net_addr_cpy(us, ies->apparent_addr); if (ies->username) strncpy(peer, ies->username, sizeof(peer) - 1); if (ies->refresh) @@ -5300,13 +5312,13 @@ ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); return -1; } - memcpy(&oldus, ®->us, sizeof(oldus)); + net_addr_cpy(oldus, reg->us); oldmsgs = reg->messages; - if (inaddrcmp(®->addr, sin)) { - ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + if (net_addr_cmp(reg->addr, sin)) { + ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin)); return -1; } - memcpy(®->us, &us, sizeof(reg->us)); + net_addr_cpy(reg->us, us); reg->messages = ies->msgcount; if (refresh && (reg->refresh > refresh)) { /* Refresh faster if necessary */ @@ -5315,7 +5327,7 @@ ast_sched_del(sched, reg->expire); reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); } - if ((inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) { + if ((net_addr_cmp(oldus, reg->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) { if (reg->messages > 65534) snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n"); else if (reg->messages > 1) @@ -5324,9 +5336,9 @@ snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n"); else if (reg->messages > -1) snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); - snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port)); - ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ourip, msgstatus); - manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + snprintf(ourip, sizeof(ourip), "%s", net_ntoa(iabuf, sizeof(iabuf), reg->us)); + ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", net_ntoa(iabuf, sizeof(iabuf), sin), ourip, msgstatus); + manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", net_ntoa(iabuf, sizeof(iabuf), sin)); } reg->regstate = REG_STATE_REGISTERED; return 0; @@ -5339,8 +5351,9 @@ char *username, *hostname, *secret; char *porta; char *stringp=NULL; + net_sockaddr *sin; - struct ast_hostent ahp; struct hostent *hp; + net_addr_alloca(&sin); if (!value) return -1; strncpy(copy, value, sizeof(copy)-1); @@ -5362,8 +5375,7 @@ ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); return -1; } - hp = ast_gethostbyname(hostname, &ahp); - if (!hp) { + if (!net_addr_get(sin, hostname)) { ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno); return -1; } @@ -5375,9 +5387,8 @@ strncpy(reg->secret, secret, sizeof(reg->secret)-1); reg->expire = -1; reg->refresh = IAX_DEFAULT_REG_EXPIRE; - reg->addr.sin_family = AF_INET; - memcpy(®->addr.sin_addr, hp->h_addr, sizeof(®->addr.sin_addr)); - reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); + net_addr_cpy(reg->addr, sin); + net_addr_setport(reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); reg->next = registrations; reg->callno = 0; registrations = reg; @@ -5410,7 +5421,7 @@ { struct iax2_peer *p = data; /* Reset the address */ - memset(&p->addr, 0, sizeof(p->addr)); + net_addr_clr(p->addr); /* Reset expire notice */ p->expire = -1; /* Reset expirey value */ @@ -5436,28 +5447,27 @@ static void reg_source_db(struct iax2_peer *p) { char data[80]; - struct in_addr in; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char *c, *d; if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { c = strchr(data, ':'); if (c) { + net_sockaddr *in; *c = '\0'; c++; - if (inet_aton(data, &in)) { + net_addr_alloca(&in); + if (net_aton(data, in)) { d = strchr(c, ':'); if (d) { *d = '\0'; d++; if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, - ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); + net_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); iax2_poke_peer(p, 0); p->expirey = atoi(d); - memset(&p->addr, 0, sizeof(p->addr)); - p->addr.sin_family = AF_INET; - p->addr.sin_addr = in; - p->addr.sin_port = htons(atoi(c)); + net_addr_cpy(p->addr, in); + net_addr_setport(p->addr, atoi(c)); if (p->expire > -1) ast_sched_del(sched, p->expire); ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ @@ -5472,29 +5482,29 @@ } } -static int update_registry(char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd) +static int update_registry(char *name, net_sockaddr *sin, int callno, char *devtype, int fd) { /* Called from IAX thread only, with proper iaxsl lock */ struct iax_ie_data ied; struct iax2_peer *p; int msgcount; char data[80]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int version; memset(&ied, 0, sizeof(ied)); p = find_peer(name, 1); if (p) { if (!ast_test_flag((&globalflags), IAX_RTNOUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) realtime_update_peer(name, sin); - if (inaddrcmp(&p->addr, sin)) { + if (net_addr_cmp(p->addr, sin)) { if (iax2_regfunk) iax2_regfunk(p->name, 1); - snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expirey); - if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { + snprintf(data, sizeof(data), "%s:%d", net_ntoa(iabuf, sizeof(iabuf), sin), p->expirey); + if (!ast_test_flag(p, IAX_TEMPONLY) && !net_addr_ishostnull(sin)) { ast_db_put("IAX/Registry", p->name, data); if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, - iaxs[callno]->state & IAX_STATE_AUTHENTICATED ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); + ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s\n", p->name, + iaxs[callno]->state & IAX_STATE_AUTHENTICATED ? "AUTHENTICATED" : "UNAUTHENTICATED", net_ntostr(iabuf, sizeof(iabuf), sin)); manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ register_peer_exten(p, 1); @@ -5508,7 +5518,7 @@ ast_db_del("IAX/Registry", p->name); } /* Update the host */ - memcpy(&p->addr, sin, sizeof(p->addr)); + net_addr_cpy(p->addr, sin); /* Verify that the host is really there */ iax2_poke_peer(p, callno); } @@ -5517,13 +5527,13 @@ /* Setup the expirey */ if (p->expire > -1) ast_sched_del(sched, p->expire); - if (p->expirey && sin->sin_addr.s_addr) + if (p->expirey && !net_addr_ishostnull(sin)) p->expire = ast_sched_add(sched, (p->expirey + 10) * 1000, expire_registry, (void *)p); iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); - if (sin->sin_addr.s_addr) { + if (!net_addr_ishostnull(sin)) { iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expirey); - iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); + iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, p->addr); if (!ast_strlen_zero(p->mailbox)) { if (ast_test_flag(p, IAX_MESSAGEDETAIL)) { int new, old; @@ -5578,13 +5588,13 @@ return 0; } -static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin) +static int registry_rerequest(struct iax_ies *ies, int callno, net_sockaddr *sin) { struct iax2_registry *reg; /* Start pessimistic */ struct iax_ie_data ied; char peer[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char challenge[256] = ""; int res; int authmethods = 0; @@ -5597,8 +5607,8 @@ memset(&ied, 0, sizeof(ied)); reg = iaxs[callno]->reg; if (reg) { - if (inaddrcmp(®->addr, sin)) { - ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + if (net_addr_cmp(reg->addr, sin)) { + ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin)); return -1; } if (ast_strlen_zero(reg->secret)) { @@ -5782,7 +5792,7 @@ #if 0 ast_log(LOG_DEBUG, "Trunking %d calls in %d bytes, ts=%d\n", calls, fr->datalen, ntohl(mth->ts)); #endif - res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); + res = transmit_trunk(fr, tpeer->addr, tpeer->sockfd); calls = tpeer->calls; /* Reset transmit trunk side data */ tpeer->trunkdatalen = 0; @@ -5805,7 +5815,7 @@ { char buf[1024]; int res; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; int processed = 0; int totalcalls = 0; @@ -5852,7 +5862,7 @@ } else { res = send_trunk(tpeer, &now); if (iaxtrunkdebug) - ast_verbose("Processed trunk peer (%s:%d) with %d call(s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res); + ast_verbose("Processed trunk peer (%s) with %d call(s)\n", net_ntoa(iabuf, sizeof(iabuf), tpeer->addr), res); } totalcalls += res; res = 0; @@ -5865,10 +5875,12 @@ ast_mutex_lock(&drop->lock); /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, because by the time they could get tpeerlock, we've already grabbed it */ - ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), drop->addr.sin_addr), ntohs(drop->addr.sin_port)); + ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s'\n", net_ntostr(iabuf, sizeof(iabuf), drop->addr)); free(drop->trunkdata); ast_mutex_unlock(&drop->lock); ast_mutex_destroy(&drop->lock); + if (drop->addr) + net_addr_delete(drop->addr); free(drop); } @@ -6026,9 +6038,9 @@ } -static int iax2_provision(struct sockaddr_in *end, char *dest, const char *template, int force); +static int iax2_provision(net_sockaddr *end, char *dest, const char *template, int force); -static int check_provisioning(struct sockaddr_in *sin, char *si, unsigned int ver) +static int check_provisioning(net_sockaddr *sin, char *si, unsigned int ver) { unsigned int ourver; unsigned char rsi[80]; @@ -6084,12 +6096,11 @@ static int socket_read(int *id, int fd, short events, void *cbdata) { - struct sockaddr_in sin; + net_sockaddr *sin; int res; int updatehistory=1; int new = NEW_PREVENT; char buf[4096], *ptr; - int len = sizeof(sin); int dcallno = 0; struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf; struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf; @@ -6101,7 +6112,7 @@ char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */ struct iax_frame fr; struct iax_frame *cur; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct ast_frame f; struct ast_channel *c; struct iax2_dpcache *dp; @@ -6121,10 +6132,12 @@ struct ast_codec_pref pref,rpref; char *using_prefs = "mine"; + net_addr_alloca(&sin); + dblbuf[0] = 0; /* Keep GCC from whining */ fr.callno = 0; - res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len); + res = net_recvfrom(fd, buf, sizeof(buf), 0, sin); if (res < 0) { if (errno != ECONNREFUSED) ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); @@ -6142,7 +6155,7 @@ } if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { /* This is a video frame, get call number */ - fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); + fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, sin, new, 1, fd); minivid = 1; } else if (meta->zeros == 0) { unsigned char metatype; @@ -6158,9 +6171,9 @@ metatype = meta->cmddata; res -= (sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)); ptr = mth->data; - tpeer = find_tpeer(&sin, fd); + tpeer = find_tpeer(sin, fd); if (!tpeer) { - ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s': No matching peer\n", net_ntostr(iabuf, sizeof(iabuf), sin)); return 1; } if (!ts || (!tpeer->rxtrunktime.tv_sec && !tpeer->rxtrunktime.tv_usec)) { @@ -6189,13 +6202,13 @@ callno = ntohs(mte->callno); trunked_ts = 0; } else { - ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s': dropping\n", net_ntostr(iabuf, sizeof(iabuf), sin)); break; } /* Stop if we don't have enough data */ if (len > res) break; - fr.callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); + fr.callno = find_callno(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, 1, fd); if (fr.callno) { ast_mutex_lock(&iaxsl[fr.callno]); /* If it's a valid call, deliver the contents. If not, we @@ -6256,7 +6269,7 @@ } #ifdef DEBUG_SUPPORT if (iaxdebug) - iax_showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr)); + iax_showframe(NULL, fh, 1, sin, res - sizeof(struct ast_iax2_full_hdr)); #endif if (ntohs(mh->callno) & IAX_FLAG_FULL) { /* Get the destination call number */ @@ -6278,7 +6291,7 @@ } if (!fr.callno) - fr.callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); + fr.callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, sin, new, 1, fd); if (fr.callno > 0) ast_mutex_lock(&iaxsl[fr.callno]); @@ -6293,7 +6306,7 @@ (f.subclass != IAX_COMMAND_TXACC) && (f.subclass != IAX_COMMAND_FWDOWNL))|| (f.frametype != AST_FRAME_IAX)) - raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, + raw_hangup(sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, fd); } if (fr.callno > 0) @@ -6308,14 +6321,14 @@ } #ifdef DEBUG_SUPPORT else if (iaxdebug) - iax_showframe(NULL, fh, 1, &sin, res - sizeof(struct ast_iax2_full_hdr)); + iax_showframe(NULL, fh, 1, sin, res - sizeof(struct ast_iax2_full_hdr)); #endif } /* count this frame */ iaxs[fr.callno]->frames_received++; - if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && !minivid && + if (!net_addr_cmp(sin, iaxs[fr.callno]->addr) && !minivid && f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ iaxs[fr.callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); @@ -6395,7 +6408,7 @@ /* Handle implicit ACKing unless this is an INVAL, and only if this is from the real peer, not the transfer peer */ - if (!inaddrcmp(&sin, &iaxs[fr.callno]->addr) && + if (!net_addr_cmp(sin, iaxs[fr.callno]->addr) && (((f.subclass != IAX_COMMAND_INVAL)) || (f.frametype != AST_FRAME_IAX))) { unsigned char x; @@ -6438,7 +6451,7 @@ } else ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr.iseqno, iaxs[fr.callno]->rseqno, iaxs[fr.callno]->oseqno); } - if (inaddrcmp(&sin, &iaxs[fr.callno]->addr) && + if (net_addr_cmp(sin, iaxs[fr.callno]->addr) && ((f.frametype != AST_FRAME_IAX) || ((f.subclass != IAX_COMMAND_TXACC) && (f.subclass != IAX_COMMAND_TXCNT)))) { @@ -6450,7 +6463,7 @@ if (f.datalen) { if (f.frametype == AST_FRAME_IAX) { if (iax_parse_ies(&ies, buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { - ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); + ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin)); ast_mutex_unlock(&iaxsl[fr.callno]); return 1; } @@ -6553,16 +6566,16 @@ /* Ignore if it's already up */ if (iaxs[fr.callno]->state & (IAX_STATE_STARTED | IAX_STATE_TBD)) break; - if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) - check_provisioning(&sin, ies.serviceident, ies.provver); + if (ies.provverpres && ies.serviceident && !net_addr_ishostnull(sin)) + check_provisioning(sin, ies.serviceident, ies.provver); /* For security, always ack immediately */ if (delayreject) send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - if (check_access(fr.callno, &sin, &ies)) { + if (check_access(fr.callno, sin, &ies)) { /* They're not allowed on */ auth_fail(fr.callno, IAX_COMMAND_REJECT); if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); break; } /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ @@ -6583,7 +6596,7 @@ iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); } else { /* Select an appropriate format */ @@ -6625,9 +6638,9 @@ send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) { if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); else - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); } } else { /* Pick one... */ @@ -6665,7 +6678,7 @@ ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); ast_set_flag(iaxs[fr.callno], IAX_ALREADYGONE); break; } @@ -6685,7 +6698,7 @@ "%sactual format = %s,\n" "%shost prefs = %s,\n" "%spriority = %s\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), + net_ntoa(iabuf, sizeof(iabuf), sin), VERBOSE_PREFIX_4, ast_getformatname(iaxs[fr.callno]->peerformat), VERBOSE_PREFIX_4, @@ -6703,7 +6716,7 @@ iaxs[fr.callno]->state |= IAX_STATE_TBD; /* If this is a TBD call, we're ready but now what... */ if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); + ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", net_ntoa(iabuf, sizeof(iabuf), sin)); } } } @@ -6752,7 +6765,7 @@ } if (iaxs[fr.callno]->owner) { if (authdebug) - ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), ies.cause ? ies.cause : ""); + ast_log(LOG_WARNING, "Call rejected by %s: %s\n", net_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr), ies.cause ? ies.cause : ""); } ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno); /* Send ack immediately, before we destroy */ @@ -6797,14 +6810,14 @@ iaxs[fr.callno]->peerformat = iaxs[fr.callno]->capability; } if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), ast_getformatname(iaxs[fr.callno]->peerformat)); + ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", net_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr), ast_getformatname(iaxs[fr.callno]->peerformat)); if (!(iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability)) { memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); if (authdebug) - ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); } else { iaxs[fr.callno]->state |= IAX_STATE_STARTED; if (iaxs[fr.callno]->owner) { @@ -6932,7 +6945,7 @@ iaxs[fr.callno]->lag = ts - fr.ts; if (option_debug) ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->lag); + net_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr), iaxs[fr.callno]->lag); } #ifdef BRIDGE_OPTIMIZATION } @@ -6943,10 +6956,10 @@ ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); break; } - if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, &ies, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) { + if (authenticate_reply(iaxs[fr.callno], iaxs[fr.callno]->addr, &ies, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) { ast_log(LOG_WARNING, "I don't know how to authenticate %s to %s\n", - ies.username ? ies.username : "", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr)); + ies.username ? ies.username : "", net_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr)); } break; case IAX_COMMAND_AUTHREP: @@ -6960,7 +6973,7 @@ } if (authenticate_verify(iaxs[fr.callno], &ies)) { if (authdebug) - ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username); + ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", net_ntoa(iabuf, sizeof(iabuf), iaxs[fr.callno]->addr), iaxs[fr.callno]->username); memset(&ied0, 0, sizeof(ied0)); auth_fail(fr.callno, IAX_COMMAND_REJECT); break; @@ -6972,7 +6985,7 @@ exists = 0; if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) { if (authdebug) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); @@ -7015,9 +7028,9 @@ if (!format) { if (authdebug) { if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); else - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); } memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); @@ -7055,9 +7068,9 @@ ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability); if (authdebug) { if(ast_test_flag(iaxs[fr.callno], IAX_CODEC_NOCAP)) - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->capability); else - ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); + ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability); } memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); @@ -7080,7 +7093,7 @@ "%sactual format = %s,\n" "%shost prefs = %s,\n" "%spriority = %s\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), + net_ntoa(iabuf, sizeof(iabuf), sin), VERBOSE_PREFIX_4, ast_getformatname(iaxs[fr.callno]->peerformat), VERBOSE_PREFIX_4, @@ -7099,7 +7112,7 @@ iaxs[fr.callno]->state |= IAX_STATE_TBD; /* If this is a TBD call, we're ready but now what... */ if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); + ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", net_ntoa(iabuf, sizeof(iabuf), sin)); } } } @@ -7110,7 +7123,7 @@ strncpy(iaxs[fr.callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr.callno]->exten)-1); if (!ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->cid_num)) { if (authdebug) - ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); + ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->exten, iaxs[fr.callno]->context); memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); @@ -7118,7 +7131,7 @@ } else { iaxs[fr.callno]->state |= IAX_STATE_STARTED; if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr.callno]->peerformat); + ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", net_ntoa(iabuf, sizeof(iabuf), sin), iaxs[fr.callno]->peerformat); iaxs[fr.callno]->state |= IAX_STATE_STARTED; send_command(iaxs[fr.callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); if(!(c = ast_iax2_new(fr.callno, AST_STATE_RING, iaxs[fr.callno]->peerformat))) @@ -7143,24 +7156,24 @@ /* For security, always ack immediately */ if (delayreject) send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); - if (register_verify(fr.callno, &sin, &ies)) { + if (register_verify(fr.callno, sin, &ies)) { /* Send delayed failure */ auth_fail(fr.callno, IAX_COMMAND_REGREJ); break; } if ((ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) || (iaxs[fr.callno]->state & IAX_STATE_AUTHENTICATED)) { if (f.subclass == IAX_COMMAND_REGREL) - memset(&sin, 0, sizeof(sin)); - if (update_registry(iaxs[fr.callno]->peer, &sin, fr.callno, ies.devicetype, fd)) + net_addr_clr(sin); + if (update_registry(iaxs[fr.callno]->peer, sin, fr.callno, ies.devicetype, fd)) ast_log(LOG_WARNING, "Registry error\n"); - if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) - check_provisioning(&sin, ies.serviceident, ies.provver); + if (ies.provverpres && ies.serviceident && !net_addr_ishostnull(sin)) + check_provisioning(sin, ies.serviceident, ies.provver); break; } registry_authrequest(iaxs[fr.callno]->peer, fr.callno); break; case IAX_COMMAND_REGACK: - if (iax2_ack_registry(&ies, &sin, fr.callno)) + if (iax2_ack_registry(&ies, sin, fr.callno)) ast_log(LOG_WARNING, "Registration failure\n"); /* Send ack immediately, before we destroy */ send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); @@ -7180,7 +7193,7 @@ break; case IAX_COMMAND_REGAUTH: /* Authentication request */ - if (registry_rerequest(&ies, fr.callno, &sin)) { + if (registry_rerequest(&ies, fr.callno, sin)) { memset(&ied0, 0, sizeof(ied0)); iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); @@ -7191,7 +7204,10 @@ iaxs[fr.callno]->transferring = 0; if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : ""); - memset(&iaxs[fr.callno]->transfer, 0, sizeof(iaxs[fr.callno]->transfer)); + if (iaxs[fr.callno]->transfer) { + net_addr_delete(iaxs[fr.callno]->transfer); + iaxs[fr.callno]->transfer = NULL; + } if (iaxs[fr.callno]->bridgecallno) { if (iaxs[iaxs[fr.callno]->bridgecallno]->transferring) { iaxs[iaxs[fr.callno]->bridgecallno]->transferring = 0; @@ -7381,7 +7397,7 @@ if (!reg->callno) { if (option_debug) ast_log(LOG_DEBUG, "Allocate call number\n"); - reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); + reg->callno = find_callno(0, 0, reg->addr, NEW_FORCE, 1, defaultsockfd); if (reg->callno < 1) { ast_log(LOG_WARNING, "Unable to create call for registration\n"); return -1; @@ -7410,16 +7426,19 @@ return iax_prov_complete_template(line, word, pos, state); } -static int iax2_provision(struct sockaddr_in *end, char *dest, const char *template, int force) +static int iax2_provision(net_sockaddr *end, char *dest, const char *template, int force) { /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning is found for template */ struct iax_ie_data provdata; struct iax_ie_data ied; unsigned int sig; - struct sockaddr_in sin; + net_sockaddr *sin; int callno; int sockfd = defaultsockfd; + + net_addr_alloca(&sin); + if (option_debug) ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); if (iax_provision_build(&provdata, &sig, template, force)) { @@ -7427,16 +7446,16 @@ return 0; } if (end) - memcpy(&sin, end, sizeof(sin)); + net_addr_cpy(sin, end); else { - if (create_addr(&sin, NULL, NULL, NULL, dest, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL, 0, NULL, 0, &sockfd)) + if (create_addr(sin, NULL, NULL, NULL, dest, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL, 0, NULL, 0, &sockfd)) return -1; } /* Build the rest of the message */ memset(&ied, 0, sizeof(ied)); iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); - callno = find_callno(0, 0, &sin, NEW_FORCE, 1, sockfd); + callno = find_callno(0, 0, sin, NEW_FORCE, 1, sockfd); if (!callno) return -1; ast_mutex_lock(&iaxsl[callno]); @@ -7467,7 +7486,7 @@ char *opts; int force =0; unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt); - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (!data || ast_strlen_zero(data)) data = "default"; sdata = ast_strdupa(data); @@ -7479,14 +7498,14 @@ ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n"); return -1; } - if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) { + if (!callno || !iaxs[callno] || net_addr_ishostnull(iaxs[callno]->addr)) { ast_log(LOG_NOTICE, "Can't provision something with no IP?\n"); return -1; } - res = iax2_provision(&iaxs[callno]->addr, NULL, sdata, force); + res = iax2_provision(iaxs[callno]->addr, NULL, sdata, force); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr), + net_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr), sdata, res); return res; } @@ -7544,7 +7563,7 @@ static int iax2_poke_peer(struct iax2_peer *peer, int heldcall) { - if (!peer->maxms || !peer->addr.sin_addr.s_addr) { + if (!peer->maxms || net_addr_ishostnull(peer->addr)) { /* IF we have no IP, or this isn't to be monitored, return imeediately after clearing things out */ peer->lastms = 0; @@ -7558,7 +7577,7 @@ } if (heldcall) ast_mutex_unlock(&iaxsl[heldcall]); - peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); + peer->callno = find_callno(0, 0, peer->addr, NEW_FORCE, 0, peer->sockfd); if (heldcall) ast_mutex_lock(&iaxsl[heldcall]); if (peer->callno < 1) { @@ -7593,7 +7612,7 @@ int maxtime; int found = 0; int fmt, native; - struct sockaddr_in sin; + net_sockaddr *sin; char s[256]; char *st, *hostname; struct ast_channel *c; @@ -7606,6 +7625,8 @@ int usejitterbuf = ast_test_flag((&globalflags), IAX_USEJITTERBUF); int forcejitterbuf = ast_test_flag((&globalflags), IAX_FORCEJITTERBUF); + net_addr_alloca(&sin); + strncpy(s, (char *)data, sizeof(s)-1); /* FIXME The next two lines seem useless */ stringp=s; @@ -7627,14 +7648,14 @@ } /* Populate our address from the given */ - if (create_addr(&sin, &capability, &sendani, &maxtime, hostname, NULL, &trunk, ¬ransfer, &usejitterbuf, &forcejitterbuf, NULL, NULL, 0, NULL, 0, &found, NULL, NULL, 0, NULL, 0, &sockfd)) { + if (create_addr(sin, &capability, &sendani, &maxtime, hostname, NULL, &trunk, ¬ransfer, &usejitterbuf, &forcejitterbuf, NULL, NULL, 0, NULL, 0, &found, NULL, NULL, 0, NULL, 0, &sockfd)) { *cause = AST_CAUSE_UNREGISTERED; return NULL; } if (portno) { - sin.sin_port = htons(atoi(portno)); + net_addr_setport(sin, atoi(portno)); } - callno = find_callno(0, 0, &sin, NEW_FORCE, 1, sockfd); + callno = find_callno(0, 0, sin, NEW_FORCE, 1, sockfd); if (callno < 1) { ast_log(LOG_WARNING, "Unable to create call\n"); *cause = AST_CAUSE_CONGESTION; @@ -7800,6 +7821,10 @@ peer->expire = -1; peer->pokeexpire = -1; peer->sockfd = defaultsockfd; + + peer->addr = net_addr_new(); + peer->mask = net_addr_new(); + peer->defaddr = net_addr_new(); } } if (peer) { @@ -7808,7 +7833,7 @@ peer->secret[0] = '\0'; if (!found) { strncpy(peer->name, name, sizeof(peer->name)-1); - peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); + net_addr_setport(peer->addr, IAX_DEFAULT_PORTNO); peer->expirey = expirey; } peer->prefs = prefs; @@ -7851,11 +7876,11 @@ if (!found) { /* Initialize stuff iff we're not found, otherwise we keep going with what we had */ - memset(&peer->addr.sin_addr, 0, 4); - if (peer->addr.sin_port) { + net_addr_clrhost(peer->addr); + if (!net_addr_isportnull(peer->addr)) { /* If we've already got a port, make it the default rather than absolute */ - peer->defaddr.sin_port = peer->addr.sin_port; - peer->addr.sin_port = 0; + net_addr_cpyport(peer->defaddr, peer->addr); + net_addr_setport(peer->addr, 0); } } } else { @@ -7864,15 +7889,17 @@ ast_sched_del(sched, peer->expire); peer->expire = -1; ast_clear_flag(peer, IAX_DYNAMIC); - if (ast_get_ip(&peer->addr, v->value)) { + if (ast_get_ip(peer->addr, v->value)) { + /* FIXME free addr mask defaddr */ free(peer); return NULL; } } if (!maskfound) - inet_aton("255.255.255.255", &peer->mask); + net_aton("255.255.255.255", peer->mask); } else if (!strcasecmp(v->name, "defaultip")) { - if (ast_get_ip(&peer->defaddr, v->value)) { + if (ast_get_ip(peer->defaddr, v->value)) { + /* FIXME free addr mask defaddr */ free(peer); return NULL; } @@ -7881,7 +7908,7 @@ peer->ha = ast_append_ha(v->name, v->value, peer->ha); } else if (!strcasecmp(v->name, "mask")) { maskfound++; - inet_aton(v->value, &peer->mask); + net_aton(v->value, peer->mask); } else if (!strcasecmp(v->name, "context")) { if (ast_strlen_zero(peer->context)) strncpy(peer->context, v->value, sizeof(peer->context) - 1); @@ -7892,9 +7919,9 @@ strncpy(peer->peercontext, v->value, sizeof(peer->peercontext) - 1); } else if (!strcasecmp(v->name, "port")) { if (ast_test_flag(peer, IAX_DYNAMIC)) - peer->defaddr.sin_port = htons(atoi(v->value)); + net_addr_setport(peer->defaddr, atoi(v->value)); else - peer->addr.sin_port = htons(atoi(v->value)); + net_addr_setport(peer->addr, atoi(v->value)); } else if (!strcasecmp(v->name, "username")) { strncpy(peer->username, v->value, sizeof(peer->username)-1); } else if (!strcasecmp(v->name, "allow")) { @@ -7930,7 +7957,7 @@ peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; ast_clear_flag(peer, IAX_DELME); /* Make sure these are IPv4 addresses */ - peer->addr.sin_family = AF_INET; +/* peer->addr.sin_family = AF_INET; FIXME */ if (!found && ast_test_flag(peer, IAX_DYNAMIC) && !temponly) reg_source_db(peer); } @@ -8123,6 +8150,10 @@ } ast_mutex_unlock(&iaxsl[regl->callno]); } + if (regl->addr) + net_addr_delete(regl->addr); + if (regl->us) + net_addr_delete(regl->us); free(regl); } registrations = NULL; @@ -8183,6 +8214,12 @@ ast_sched_del(sched, peer->pokeexpire); if (peer->callno > 0) iax2_destroy(peer->callno); + if (peer->addr) + net_addr_delete(peer->addr); + if (peer->mask) + net_addr_delete(peer->mask); + if (peer->defaddr) + net_addr_delete(peer->defaddr); register_peer_exten(peer, 0); free(peer); } @@ -8481,7 +8518,7 @@ static int cache_get_callno_locked(const char *data) { - struct sockaddr_in sin; + net_sockaddr *sin; int x; int sockfd = defaultsockfd; char st[256], *s; @@ -8491,6 +8528,8 @@ char *context=NULL; int callno; struct iax_ie_data ied; + + net_addr_alloca(&sin); for (x=0;xaddr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && + if ((!net_addr_ishostnull(p->addr) || !net_addr_ishostnull(p->defaddr)) && (!p->maxms || ((p->lastms > -1) && (p->lastms <= p->maxms)))) { /* Peer is registred, or have default IP address and a valid registration */ @@ -8949,12 +8988,12 @@ char *config = "iax.conf"; int res = 0; int x; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct iax2_registry *reg; struct iax2_peer *peer; struct ast_netsock *ns; - struct sockaddr_in sin; + net_sockaddr *sin; iax_set_output(iax_debug_output); iax_set_error(iax_error_output); @@ -8965,9 +9004,9 @@ /* Seed random number generator */ srand(time(NULL)); - sin.sin_family = AF_INET; - sin.sin_port = htons(IAX_DEFAULT_PORTNO); - sin.sin_addr.s_addr = INADDR_ANY; + net_addr_alloca(&sin); + net_addr_init(sin, PF_INET, SOCK_DGRAM, 0); + net_addr_setport(sin, IAX_DEFAULT_PORTNO); #ifdef IAX_TRUNKING #ifdef ZT_TIMERACK @@ -9031,7 +9070,7 @@ ast_log(LOG_ERROR, "Unable to register IAX switch\n"); if (defaultsockfd < 0) { - if (!(ns = ast_netsock_bindaddr(&netsock, io, &sin, tos, socket_read, NULL))) { + if (!(ns = ast_netsock_bindaddr(&netsock, io, sin, tos, socket_read, NULL))) { ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); return -1; } else { @@ -9044,7 +9083,7 @@ if (!res) { res = start_network_thread(); if (option_verbose > 1) - ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening on %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening on %s port %d\n", net_ntoa(iabuf, sizeof(iabuf), sin), net_addr_getport(sin)); } else { ast_log(LOG_ERROR, "Unable to start network thread\n"); ast_netsock_release(&netsock); Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.700 diff -u -r1.700 chan_sip.c --- channels/chan_sip.c 30 Mar 2005 16:28:28 -0000 1.700 +++ channels/chan_sip.c 4 Apr 2005 20:50:19 -0000 @@ -230,12 +230,12 @@ static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263; static int noncodeccapability = AST_RTP_DTMF; -static struct in_addr __ourip; -static struct sockaddr_in outboundproxyip; +static net_sockaddr *__ourip; +//static net_sockaddr *outboundproxyip; static int ourport; static int sipdebug = 0; -static struct sockaddr_in debugaddr; +static net_sockaddr *debugaddr; static int tos = 0; @@ -387,12 +387,12 @@ int tag; /* Another random number */ int sessionid; /* SDP Session ID */ int sessionversion; /* SDP Session Version */ - struct sockaddr_in sa; /* Our peer */ - struct sockaddr_in redirip; /* Where our RTP should be going if not to us */ - struct sockaddr_in vredirip; /* Where our Video RTP should be going if not to us */ + net_sockaddr *sa; /* Our peer */ + net_sockaddr *redirip; /* Where our RTP should be going if not to us */ + net_sockaddr *vredirip; /* Where our Video RTP should be going if not to us */ int redircodecs; /* Redirect codecs */ - struct sockaddr_in recv; /* Received as */ - struct in_addr ourip; /* Our IP */ + net_sockaddr *recv; /* Received as */ + net_sockaddr *ourip; /* Our IP */ struct ast_channel *owner; /* Who owns us */ char exten[AST_MAX_EXTENSION]; /* Extension where to start */ char refer_to[AST_MAX_EXTENSION]; /* Place to store REFER-TO extension */ @@ -549,8 +549,8 @@ int rtpkeepalive; /* Send RTP packets for keepalive */ ast_group_t callgroup; /* Call group */ ast_group_t pickupgroup; /* Pickup group */ - struct sockaddr_in addr; /* IP address of peer */ - struct in_addr mask; + net_sockaddr *addr; /* IP address of peer */ + net_sockaddr *mask; /* */ /* Qualification */ struct sip_pvt *call; /* Call pointer */ @@ -559,7 +559,7 @@ int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ struct timeval ps; /* Ping send time */ - struct sockaddr_in defaddr; /* Default IP address, used until registration */ + net_sockaddr *defaddr; /* Default IP address, used until registration */ struct ast_ha *ha; /* Access control list */ struct ast_variable *chanvars; /* Variables to set for channel created by user */ int lastmsg; @@ -597,7 +597,7 @@ int callid_valid; /* 0 means we haven't chosen callid for this registry yet. */ char callid[80]; /* Global CallID for this registry */ unsigned int ocseq; /* Sequence number we got to for REGISTERs for this registry */ - struct sockaddr_in us; /* Who the server thinks we are */ +/* net_sockaddr *us; /\* Who the server thinks we are *\/ */ /* Saved headers */ char realm[256]; /* Authorization realm */ @@ -631,8 +631,8 @@ static int sipsock = -1; -static struct sockaddr_in bindaddr; -static struct sockaddr_in externip; +static net_sockaddr *bindaddr; +static net_sockaddr *externip; static char externhost[256] = ""; static time_t externexpire = 0; static int externrefresh = 10; @@ -707,7 +707,7 @@ }; /*--- find_sip_method: Find SIP method from header */ -int find_sip_method(char *msg) +static int find_sip_method(char *msg) { int i, res = 0; /* Strictly speaking, SIP methods are case SENSITIVE, but we don't check */ @@ -719,15 +719,16 @@ } /*--- sip_debug_test_addr: See if we pass debug IP filter */ -static inline int sip_debug_test_addr(struct sockaddr_in *addr) +static inline int sip_debug_test_addr(net_sockaddr *addr) { if (sipdebug == 0) return 0; - if (debugaddr.sin_addr.s_addr) { - if (((ntohs(debugaddr.sin_port) != 0) - && (debugaddr.sin_port != addr->sin_port)) - || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) + if (debugaddr) { + if ((!net_addr_isportnull(debugaddr) + && !net_addr_cmpport(debugaddr, addr)) + || net_addr_cmphost(debugaddr, addr)) { return 0; + } } return 1; } @@ -737,7 +738,7 @@ { if (sipdebug == 0) return 0; - return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? &p->recv : &p->sa)); + return sip_debug_test_addr(((ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) ? p->recv : p->sa)); } @@ -745,13 +746,13 @@ static int __sip_xmit(struct sip_pvt *p, char *data, int len) { int res; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) - res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); + res=net_sendto(sipsock, data, len, 0, p->recv); else - res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); + res=net_sendto(sipsock, data, len, 0, p->sa); if (res != len) { - ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), res, strerror(errno)); + ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, net_ntoa(iabuf, sizeof(iabuf), p->sa), res, strerror(errno)); } return res; } @@ -761,48 +762,49 @@ /*--- build_via: Build a Via header for a request ---*/ static void build_via(struct sip_pvt *p, char *buf, int len) { - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN+2]; /* max IPv6 + 2 brackets */ /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ if (ast_test_flag(p, SIP_NAT) != SIP_NAT_NEVER) - snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); + snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", net_ntourl(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); else /* Work around buggy UNIDEN UIP200 firmware */ - snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); + snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", net_ntourl(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); } /*--- ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---*/ /* Only used for outbound registrations */ -static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us) +static int ast_sip_ouraddrfor(net_sockaddr *them, net_sockaddr *us) { /* * Using the localaddr structure built up with localnet statements * apply it to their address to see if we need to substitute our * externip or can get away with our internal bindaddr */ - struct sockaddr_in theirs; - theirs.sin_addr = *them; - if (localaddr && externip.sin_addr.s_addr && - ast_apply_ha(localaddr, &theirs)) { - char iabuf[INET_ADDRSTRLEN]; + int res = 0; + net_sockaddr *theirs; + net_addr_alloca(&theirs); + net_addr_cpy(theirs, them); + if (localaddr && externip && + ast_apply_ha(localaddr, theirs)) { + char iabuf[NET_ADDRSTRLEN]; if (externexpire && (time(NULL) >= externexpire)) { - struct ast_hostent ahp; - struct hostent *hp; time(&externexpire); externexpire += externrefresh; - if ((hp = ast_gethostbyname(externhost, &ahp))) { - memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); + if (!net_addr_get(externip, externhost)) { } else ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); } - memcpy(us, &externip.sin_addr, sizeof(struct in_addr)); - ast_inet_ntoa(iabuf, sizeof(iabuf), *(struct in_addr *)&them->s_addr); + net_addr_cpyhost(us, externip); + net_ntoa(iabuf, sizeof(iabuf), them); ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf); } - else if (bindaddr.sin_addr.s_addr) - memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr)); + else if (!net_addr_ishostnull(bindaddr)) + net_addr_cpyhost(us, bindaddr); else - return ast_ouraddrfor(them, us); - return 0; + res = ast_ouraddrfor(them, us); + + //net_addr_delete(theirs); + return res; } /*--- append_history: Append to SIP dialog history */ @@ -843,15 +845,15 @@ { struct sip_pkt *pkt=data, *prev, *cur; int res = 0; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; ast_mutex_lock(&pkt->owner->lock); if (pkt->retrans < MAX_RETRANS) { pkt->retrans++; if (sip_debug_test_pvt(pkt->owner)) { if (ast_test_flag(pkt->owner, SIP_NAT) & SIP_NAT_ROUTE) - ast_verbose("Retransmitting #%d (NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port), pkt->data); + ast_verbose("Retransmitting #%d (NAT) to %s:\n%s\n---\n", pkt->retrans, net_ntostr(iabuf, sizeof(iabuf), pkt->owner->recv), pkt->data); else - ast_verbose("Retransmitting #%d (no NAT) to %s:%d:\n%s\n---\n", pkt->retrans, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port), pkt->data); + ast_verbose("Retransmitting #%d (no NAT) to %s:\n%s\n---\n", pkt->retrans, net_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa), pkt->data); } append_history(pkt->owner, "ReTx", pkt->data); __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); @@ -1062,14 +1064,14 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) { int res; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct sip_request tmp; char tmpmsg[80]; if (sip_debug_test_pvt(p)) { if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) - ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); + ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", net_ntostr(iabuf, sizeof(iabuf), p->recv), req->data); else - ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); + ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", net_ntostr(iabuf, sizeof(iabuf), p->sa), req->data); } if (reliable) { if (recordhistory) { @@ -1095,14 +1097,14 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, int reliable, int seqno) { int res; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct sip_request tmp; char tmpmsg[80]; if (sip_debug_test_pvt(p)) { if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) - ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port), req->data); + ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", net_ntostr(iabuf, sizeof(iabuf), p->recv), req->data); else - ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), req->data); + ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", net_ntostr(iabuf, sizeof(iabuf), p->sa), req->data); } if (reliable) { if (recordhistory) { @@ -1195,7 +1197,7 @@ } /*--- realtime_update_peer: Update peer object in realtime storage ---*/ -static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, int expirey) +static void realtime_update_peer(const char *peername, net_sockaddr *sin, const char *username, int expirey) { char port[10] = ""; char ipaddr[20] = ""; @@ -1206,8 +1208,8 @@ time(&nowtime); nowtime += expirey; snprintf(regseconds, sizeof(regseconds), "%ld", nowtime); /* Expiration time */ - ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr); - snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); + net_ntoa(ipaddr, sizeof(ipaddr), sin); + net_ntos(port, sizeof(port), sin); } ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL); } @@ -1253,6 +1255,13 @@ speerobjs--; clear_realm_authentication(peer->auth); peer->auth = (struct sip_auth *) NULL; + if (peer->addr) + net_addr_delete(peer->addr); + if (peer->mask) + net_addr_delete(peer->mask); + if (peer->defaddr) + net_addr_delete(peer->defaddr); + free(peer); } @@ -1264,14 +1273,14 @@ ast_test_flag(&(p->flags_page2), SIP_PAGE2_RTCACHEFRIENDS))) { if (p->expire == -1) expiry = 0; /* Unregister realtime peer */ - realtime_update_peer(p->name, &p->addr, p->username, expiry); + realtime_update_peer(p->name, p->addr, p->username, expiry); } } /*--- realtime_peer: Get peer from realtime storage ---*/ /* Checks the "sippeers" realtime family from extconfig.conf */ -static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin) +static struct sip_peer *realtime_peer(const char *peername, net_sockaddr *sin) { struct sip_peer *peer=NULL; struct ast_variable *var; @@ -1283,7 +1292,7 @@ if (newpeername) var = ast_load_realtime("sippeers", "name", peername, NULL); else if (sin) { /* Then check on IP address */ - ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); + net_ntoa(iabuf, sizeof(iabuf), sin); var = ast_load_realtime("sippeers", "ipaddr", iabuf, NULL); } else return NULL; @@ -1330,17 +1339,17 @@ } /*--- sip_addrcmp: Support routine for find_peer ---*/ -static int sip_addrcmp(char *name, struct sockaddr_in *sin) +static int sip_addrcmp(char *name, net_sockaddr *sin) { /* We know name is the first field, so we can cast */ struct sip_peer *p = (struct sip_peer *)name; - return !(!inaddrcmp(&p->addr, sin) || - (ast_test_flag(p, SIP_INSECURE) && - (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); + return !(!net_addr_cmp(p->addr, sin) || + (ast_test_flag(p, SIP_INSECURE) && + (!net_addr_cmphost(p->addr, sin)))); } /*--- find_peer: Locate peer by name or ip address */ -static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime) +static struct sip_peer *find_peer(const char *peer, net_sockaddr *sin, int realtime) { struct sip_peer *p = NULL; @@ -1430,28 +1439,43 @@ return(u); } +static int parse_host(const char *opeer, char *buf, int bufsize, + int *portno, int default_port) +{ + char *port; + char peer[256]=""; + + strncpy(peer, opeer, sizeof(peer) - 1); + port = strchr(peer, ':'); + if (port) { + *port = '\0'; + port++; + *portno = atoi(port); + } else { + *portno = DEFAULT_SIP_PORT; + } + strncpy(buf, peer, bufsize-1); + + return 0; +} + /*--- create_addr: create address structure from peer definition ---*/ /* Or, if peer not found, find it in the global DNS */ /* returns TRUE on failure, FALSE on success */ static int create_addr(struct sip_pvt *r, char *opeer) { - struct hostent *hp; - struct ast_hostent ahp; struct sip_peer *p; int found=0; - char *port; char *callhost; int portno; char host[256], *hostn; char peer[256]=""; - strncpy(peer, opeer, sizeof(peer) - 1); - port = strchr(peer, ':'); - if (port) { - *port = '\0'; - port++; + if (parse_host(opeer, peer, sizeof(peer), &portno, DEFAULT_SIP_PORT)) { + return -1; } - r->sa.sin_family = AF_INET; + + //r->sa.sin_family = AF_INET; p = find_peer(peer, NULL, 1); if (p) { @@ -1479,10 +1503,10 @@ } } if (ast_strlen_zero(r->tohost)) { - if (p->addr.sin_addr.s_addr) - ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->addr.sin_addr); + if (!net_addr_ishostnull(p->addr)) + net_ntoa(r->tohost, sizeof(r->tohost), p->addr); else - ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->defaddr.sin_addr); + net_ntoa(r->tohost, sizeof(r->tohost), p->defaddr); } if (!ast_strlen_zero(p->fromdomain)) strncpy(r->fromdomain, p->fromdomain, sizeof(r->fromdomain)-1); @@ -1496,26 +1520,21 @@ else r->noncodeccapability &= ~AST_RTP_DTMF; strncpy(r->context, p->context,sizeof(r->context)-1); - if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && + if ((!net_addr_ishostnull(p->addr) || + !net_addr_ishostnull(p->defaddr)) && (!p->maxms || ((p->lastms >= 0) && (p->lastms <= p->maxms)))) { - if (p->addr.sin_addr.s_addr) { - r->sa.sin_addr = p->addr.sin_addr; - r->sa.sin_port = p->addr.sin_port; + if (!net_addr_ishostnull(p->addr)) { + net_addr_cpy(r->sa, p->addr); } else { - r->sa.sin_addr = p->defaddr.sin_addr; - r->sa.sin_port = p->defaddr.sin_port; + net_addr_cpy(r->sa, p->defaddr); } - memcpy(&r->recv, &r->sa, sizeof(r->recv)); + net_addr_cpy(r->recv, r->sa); } else { ASTOBJ_UNREF(p,sip_destroy_peer); } } if (!p && !found) { hostn = peer; - if (port) - portno = atoi(port); - else - portno = DEFAULT_SIP_PORT; if (srvlookup) { char service[256]; int tportno; @@ -1527,12 +1546,10 @@ portno = tportno; } } - hp = ast_gethostbyname(hostn, &ahp); - if (hp) { + if (!net_addr_get(r->sa, hostn)) { strncpy(r->tohost, peer, sizeof(r->tohost) - 1); - memcpy(&r->sa.sin_addr, hp->h_addr, sizeof(r->sa.sin_addr)); - r->sa.sin_port = htons(portno); - memcpy(&r->recv, &r->sa, sizeof(r->recv)); + net_addr_setport(r->sa, portno); + net_addr_cpy(r->recv, r->sa); return 0; } else { ast_log(LOG_WARNING, "No such host: %s\n", peer); @@ -1703,6 +1720,26 @@ p->history = p->history->next; free(hist); } + if (p->sa) { + net_addr_delete(p->sa); + p->sa = NULL; + } + if (p->redirip) { + net_addr_delete(p->redirip); + p->redirip = NULL; + } + if (p->vredirip) { + net_addr_delete(p->vredirip); + p->vredirip = NULL; + } + if (p->recv) { + net_addr_delete(p->recv); + p->recv = NULL; + } + if (p->ourip) { + net_addr_delete(p->ourip); + p->ourip = NULL; + } cur = iflist; while(cur) { if (cur == p) { @@ -2205,10 +2242,34 @@ if (title) snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%04x", title, rand() & 0xffff); - else if (strchr(i->fromdomain,':')) - snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", strchr(i->fromdomain,':')+1, (int)(long)(i)); - else - snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long)(i)); + else { + char buf[256]; + char *ptr; + char *domain; + + buf[255]='\0'; + strncpy(buf, i->fromdomain, sizeof(buf)-1); + ptr = buf; + if (*ptr == '[') { + ptr++; + + domain = ptr; + ptr = strchr(ptr, ']'); + if (ptr) { + *ptr = '\0'; + ptr++; + } + } else { + domain = ptr; + } + + ptr = strchr(ptr, ':'); + if (ptr) { + *ptr = '\0'; + } + + snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", domain, (int)(long)(i)); + } tmp->type = channeltype; if (ast_test_flag(i, SIP_DTMF) == SIP_DTMF_INBAND) { @@ -2460,12 +2521,12 @@ } /*--- build_callid: Build SIP CALLID header ---*/ -static void build_callid(char *callid, int len, struct in_addr ourip, char *fromdomain) +static void build_callid(char *callid, int len, net_sockaddr *ourip, char *fromdomain) { int res; int val; int x; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; for (x=0;x<4;x++) { val = rand(); res = snprintf(callid, len, "%08x", val); @@ -2476,11 +2537,11 @@ snprintf(callid, len, "@%s", fromdomain); else /* It's not important that we really use our right IP here... */ - snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip)); + snprintf(callid, len, "@%s", net_ntoa(iabuf, sizeof(iabuf), ourip)); } /*--- sip_alloc: Allocate SIP_PVT structure and set defaults ---*/ -static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useglobal_nat) +static struct sip_pvt *sip_alloc(char *callid, net_sockaddr *sin, int useglobal_nat) { struct sip_pvt *p; @@ -2498,16 +2559,21 @@ #ifdef OSP_SUPPORT p->osphandle = -1; #endif + + p->sa = net_addr_new(); + p->recv = net_addr_new(); + p->ourip = net_addr_new(); + if (sin) { - memcpy(&p->sa, sin, sizeof(p->sa)); - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) - memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + net_addr_cpy(p->sa, sin); + if (ast_sip_ouraddrfor(p->sa,p->ourip)) + net_addr_cpy(p->ourip, __ourip); } else { - memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + net_addr_cpy(p->ourip, __ourip); } - p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); + p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr); if (videosupport) - p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); + p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr); p->branch = rand(); p->tag = rand(); @@ -2520,6 +2586,18 @@ ast_variables_destroy(p->chanvars); p->chanvars = NULL; } + if (p->sa) { + net_addr_delete(p->sa); + p->sa = NULL; + } + if (p->recv) { + net_addr_delete(p->recv); + p->recv = NULL; + } + if (p->ourip) { + net_addr_delete(p->ourip); + p->ourip = NULL; + } free(p); return NULL; } @@ -2529,7 +2607,7 @@ if (useglobal_nat && sin) { /* Setup NAT structure according to global settings if we have an address */ ast_copy_flags(p, &global_flags, SIP_NAT); - memcpy(&p->recv, sin, sizeof(p->recv)); + net_addr_cpy(p->recv, sin); ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); if (p->vrtp) ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)); @@ -2563,12 +2641,12 @@ /*--- find_call: Connect incoming SIP message to current call or create new call structure */ /* Called by handle_request ,sipsock_read */ -static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin) +static struct sip_pvt *find_call(struct sip_request *req, net_sockaddr *sin) { struct sip_pvt *p; char *callid; char tmp[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char *cmd; char *tag = "", *c; @@ -2603,7 +2681,7 @@ } if (ast_strlen_zero(callid)) { - ast_log(LOG_WARNING, "Call missing call ID from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_WARNING, "Call missing call ID from '%s'\n", net_ntoa(iabuf, sizeof(iabuf), sin)); return NULL; } ast_mutex_lock(&iflock); @@ -2819,22 +2897,21 @@ char *c; char *a; char host[258]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int len = -1; int portno = -1; int vportno = -1; int peercapability, peernoncodeccapability; int vpeercapability=0, vpeernoncodeccapability=0; - struct sockaddr_in sin; + net_sockaddr *sin; char *codecs; - struct hostent *hp; - struct ast_hostent ahp; int codec; int destiterator = 0; int iterator; int sendonly = 0; int x,y; int debug=sip_debug_test_pvt(p); + int ipver = 0; /* Update our last rtprx when we receive an SDP, too */ time(&p->lastrtprx); @@ -2852,13 +2929,15 @@ ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); return -1; } - if (sscanf(c, "IN IP4 %256s", host) != 1) { + if (sscanf(c, "IN IP%d %256s", &ipver, host) != 2 || + (ipver != 4 && ipver != 6)) { ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); return -1; } /* XXX This could block for a long time, and block the main thread! XXX */ - hp = ast_gethostbyname(host, &ahp); - if (!hp) { + net_addr_alloca(&sin); + net_addr_init(sin, ipver==4 ? PF_INET : PF_INET6, 0, 0); + if (net_addr_get(sin, host)) { ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); return -1; } @@ -2919,52 +2998,52 @@ if (pedanticsipchecking) { c = get_sdp_iterate(&destiterator, req, "c"); if (!ast_strlen_zero(c)) { - if (sscanf(c, "IN IP4 %256s", host) != 1) { + if (sscanf(c, "IN IP%d %256s", &ipver, host) != 2 || + (ipver != 4 && ipver != 6)) { ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); } else { /* XXX This could block for a long time, and block the main thread! XXX */ - hp = ast_gethostbyname(host, &ahp); - if (!hp) { + net_addr_init(sin, ipver==4 ? PF_INET : PF_INET6, 0, 0); + if (net_addr_get(sin, host)) { ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); } } } } /* RTP addresses and ports for audio and video */ - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); /* Setup audio port number */ - sin.sin_port = htons(portno); - if (p->rtp && sin.sin_port) { - ast_rtp_set_peer(p->rtp, &sin); + net_addr_setport(sin, portno); + if (p->rtp && !net_addr_isportnull(sin)) { + ast_rtp_set_peer(p->rtp, sin); if (debug) { - ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); - ast_log(LOG_DEBUG,"Peer audio RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + ast_verbose("Peer audio RTP is at port %s\n", net_ntostr(iabuf,sizeof(iabuf), sin)); + ast_log(LOG_DEBUG,"Peer audio RTP is at port %s\n",net_ntostr(iabuf, sizeof(iabuf), sin)); } } /* Check for Media-description-level-address for video */ if (pedanticsipchecking) { c = get_sdp_iterate(&destiterator, req, "c"); if (!ast_strlen_zero(c)) { - if (sscanf(c, "IN IP4 %256s", host) != 1) { + if (sscanf(c, "IN IP%d %256s", &ipver, host) != 2 || + (ipver != 4 && ipver != 6)) { ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); } else { /* XXX This could block for a long time, and block the main thread! XXX */ - hp = ast_gethostbyname(host, &ahp); - if (!hp) { + net_addr_init(sin, ipver==4 ? PF_INET : PF_INET6, 0, 0); + if (net_addr_get(sin, host)) { ast_log(LOG_WARNING, "Unable to lookup host in secondary c= line, '%s'\n", c); } } } } /* Setup video port number */ - sin.sin_port = htons(vportno); - if (p->vrtp && sin.sin_port) { - ast_rtp_set_peer(p->vrtp, &sin); + net_addr_setport(sin, vportno); + if (p->vrtp && !net_addr_isportnull(sin)) { + ast_rtp_set_peer(p->vrtp, sin); if (debug) { - ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); - ast_log(LOG_DEBUG,"Peer video RTP is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + ast_verbose("Peer video RTP is at port %s\n", net_ntostr(iabuf,sizeof(iabuf), sin)); + ast_log(LOG_DEBUG,"Peer video RTP is at port %s\n",net_ntostr(iabuf, sizeof(iabuf), sin)); } } @@ -3033,7 +3112,7 @@ } if (ast_bridged_channel(p->owner)) { /* Turn on/off music on hold if we are holding/unholding */ - if (sin.sin_addr.s_addr && !sendonly) { + if (!net_addr_ishostnull(sin) && !sendonly) { ast_moh_stop(ast_bridged_channel(p->owner)); if (callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) { manager_event(EVENT_FLAG_CALL, "Unhold", @@ -3182,7 +3261,7 @@ int start = 0; int copied = 0; char new[256]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; for (;;) { oh = __get_header(orig, field, &start); if (!ast_strlen_zero(oh)) { @@ -3200,7 +3279,7 @@ /* Whoo hoo! Now we can indicate port address translation too! Just another RFC (RFC3581). I'll leave the original comments in for posterity. */ - snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); + snprintf(new, sizeof(new), "%s;received=%s;rport=%d", tmp, net_ntoa(iabuf, sizeof(iabuf), p->recv), net_addr_getport(p->recv)); add_header(req, field, new); } else { /* Add what we're responding to */ @@ -3247,14 +3326,12 @@ static void set_destination(struct sip_pvt *p, char *uri) { char *h, *maddr, hostname[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int port, hn; - struct hostent *hp; - struct ast_hostent ahp; int debug=sip_debug_test_pvt(p); /* Parse uri to h (host) and port - uri is already just the part inside the <> */ - /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ + /* general form we are expecting is sip[s]:username[:password]@[\[]host[\]][:port][;...] */ if (debug) ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); @@ -3270,10 +3347,18 @@ else if (strncmp(h, "sips:", 5) == 0) h += 5; } - hn = strcspn(h, ":;>"); - if (hn > (sizeof(hostname) - 1)) hn = sizeof(hostname) - 1; - strncpy(hostname, h, hn); hostname[hn] = '\0'; /* safe */ - h+=hn; + if (*h == '[') { + h++; + hn = strcspn(h, "]"); + if (hn > (sizeof(hostname) - 1)) hn = sizeof(hostname) - 1; + strncpy(hostname, h, hn); hostname[hn] = '\0'; /* safe */ + h+=hn+1; + } else { + hn = strcspn(h, ":;>"); + if (hn > (sizeof(hostname) - 1)) hn = sizeof(hostname) - 1; + strncpy(hostname, h, hn); hostname[hn] = '\0'; /* safe */ + h+=hn; + } /* Is "port" present? if not default to 5060 */ if (*h == ':') { @@ -3292,17 +3377,15 @@ if (hn > (sizeof(hostname) - 1)) hn = sizeof(hostname) - 1; strncpy(hostname, maddr, hn); hostname[hn] = '\0'; /* safe */ } - - hp = ast_gethostbyname(hostname, &ahp); - if (hp == NULL) { + + net_addr_init(p->sa, PF_UNSPEC, SOCK_DGRAM, 0); + if (net_addr_get(p->sa, hostname)) { ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); return; } - p->sa.sin_family = AF_INET; - memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); - p->sa.sin_port = htons(port); + net_addr_setport(p->sa, port); if (debug) - ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), port); + ast_verbose("set_destination: set destination to %s, port %d\n", net_ntoa(iabuf, sizeof(iabuf), p->sa), port); } /*--- init_resp: Initialize SIP response, based on SIP request ---*/ @@ -3608,8 +3691,8 @@ int pref_codec = 0; int alreadysent = 0; char costr[80]; - struct sockaddr_in sin; - struct sockaddr_in vsin; + net_sockaddr *sin; + net_sockaddr *vsin; char v[256] = ""; char s[256] = ""; char o[256] = ""; @@ -3619,12 +3702,13 @@ char m2[256] = ""; char a[1024] = ""; char a2[1024] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int x = 0; int capability = 0 ; - struct sockaddr_in dest; - struct sockaddr_in vdest = { 0, }; + net_sockaddr *dest; + net_sockaddr *vdest; int debug=0; + int ipver; debug = sip_debug_test_pvt(p); @@ -3636,48 +3720,55 @@ return -1; } capability = p->capability; - + + net_addr_alloca(&sin); + net_addr_alloca(&vsin); + net_addr_alloca(&dest); + net_addr_alloca(&vdest); +/* net_addr_clr(vdest); */ + if (!p->sessionid) { p->sessionid = getpid(); p->sessionversion = p->sessionid; } else p->sessionversion++; - ast_rtp_get_us(p->rtp, &sin); + ast_rtp_get_us(p->rtp, sin); if (p->vrtp) - ast_rtp_get_us(p->vrtp, &vsin); + ast_rtp_get_us(p->vrtp, vsin); - if (p->redirip.sin_addr.s_addr) { - dest.sin_port = p->redirip.sin_port; - dest.sin_addr = p->redirip.sin_addr; + if (p->redirip) { + net_addr_cpy(dest, p->redirip); if (p->redircodecs) capability = p->redircodecs; } else { - dest.sin_addr = p->ourip; - dest.sin_port = sin.sin_port; + net_addr_cpy(dest, p->ourip); + net_addr_setport(dest, net_addr_getport(sin)); } + ipver = net_addr_getipver(dest); + /* Determine video destination */ if (p->vrtp) { - if (p->vredirip.sin_addr.s_addr) { - vdest.sin_port = p->vredirip.sin_port; - vdest.sin_addr = p->vredirip.sin_addr; + if (p->vredirip) { + net_addr_cpy(vdest, p->vredirip); } else { - vdest.sin_addr = p->ourip; - vdest.sin_port = vsin.sin_port; + net_addr_cpy(vdest, p->ourip); + net_addr_setport(vdest, net_addr_getport(vsin)); } } if (debug){ - ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(sin.sin_port)); + ast_verbose("We're at %s port %d\n", net_ntoa(iabuf, sizeof(iabuf), p->ourip), net_addr_getport(sin)); if (p->vrtp) - ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port)); + ast_verbose("Video is at %s port %d\n", net_ntoa(iabuf, sizeof(iabuf), p->ourip), net_addr_getport(vsin)); } snprintf(v, sizeof(v), "v=0\r\n"); - snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); + snprintf(o, sizeof(o), "o=root %d %d IN IP%d %s\r\n", p->sessionid, p->sessionversion, ipver, net_ntoa(iabuf, sizeof(iabuf), dest)); snprintf(s, sizeof(s), "s=session\r\n"); - snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); + snprintf(c, sizeof(c), "c=IN IP%d %s\r\n", ipver, net_ntoa(iabuf, sizeof(iabuf), dest)); snprintf(t, sizeof(t), "t=0 0\r\n"); - snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port)); - snprintf(m2, sizeof(m2), "m=video %d RTP/AVP", ntohs(vdest.sin_port)); + snprintf(m, sizeof(m), "m=audio %d RTP/AVP", net_addr_getport(dest)); + if (p->vrtp) + snprintf(m2, sizeof(m2), "m=video %d RTP/AVP", net_addr_getport(vdest)); /* Prefer the codec we were requested to use, first, no matter what */ if (capability & p->prefcodec) { if (debug) @@ -3787,6 +3878,10 @@ /* Update lastrtprx when we send our SDP */ time(&p->lastrtprx); time(&p->lastrtptx); +/* net_addr_delete(sin); */ +/* net_addr_delete(vsin); */ +/* net_addr_delete(dest); */ +/* net_addr_delete(vdest); */ return 0; } @@ -3936,13 +4031,13 @@ /*--- build_contact: Build contact header - the contact header we send out ---*/ static void build_contact(struct sip_pvt *p) { - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN+2]; /* max IPv6 addr + 2 brackets */ /* Construct Contact: header */ if (ourport != 5060) - snprintf(p->our_contact, sizeof(p->our_contact), "", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport); + snprintf(p->our_contact, sizeof(p->our_contact), "", p->exten, ast_strlen_zero(p->exten) ? "" : "@", net_ntourl(iabuf, sizeof(iabuf), p->ourip), ourport); else - snprintf(p->our_contact, sizeof(p->our_contact), "", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip)); + snprintf(p->our_contact, sizeof(p->our_contact), "", p->exten, ast_strlen_zero(p->exten) ? "" : "@", net_ntourl(iabuf, sizeof(iabuf), p->ourip)); } /*--- initreqprep: Initiate SIP request to peer/user ---*/ @@ -3952,7 +4047,7 @@ char from[256]; char to[256]; char tmp[80]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN+2]; char *l = default_callerid, *n=NULL; int x; char urioptions[256]=""; @@ -4011,9 +4106,9 @@ strncpy(p->fromname, n, sizeof(p->fromname) - 1); if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) - snprintf(from, sizeof(from), "\"%s\" ;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); + snprintf(from, sizeof(from), "\"%s\" ;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? net_ntourl(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); else - snprintf(from, sizeof(from), "\"%s\" ;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); + snprintf(from, sizeof(from), "\"%s\" ;tag=as%08x", n, l, ast_strlen_zero(p->fromdomain) ? net_ntourl(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); /* If we're calling a registred SIP peer, use the fullcontact to dial to the peer */ if (!ast_strlen_zero(p->fullcontact)) { @@ -4021,13 +4116,13 @@ strncpy(invite, p->fullcontact, sizeof(invite) - 1); /* Otherwise, use the username while waiting for registration */ } else if (!ast_strlen_zero(p->username)) { - if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) { - snprintf(invite, sizeof(invite), "sip:%s@%s:%d%s",p->username, p->tohost, ntohs(p->sa.sin_port), urioptions); + if (net_addr_getport(p->sa) != DEFAULT_SIP_PORT) { + snprintf(invite, sizeof(invite), "sip:%s@%s:%d%s",p->username, p->tohost, net_addr_getport(p->sa), urioptions); } else { snprintf(invite, sizeof(invite), "sip:%s@%s%s",p->username, p->tohost, urioptions); } - } else if (ntohs(p->sa.sin_port) != DEFAULT_SIP_PORT) { - snprintf(invite, sizeof(invite), "sip:%s:%d%s", p->tohost, ntohs(p->sa.sin_port), urioptions); + } else if (net_addr_getport(p->sa) != DEFAULT_SIP_PORT) { + snprintf(invite, sizeof(invite), "sip:%s:%d%s", p->tohost, net_addr_getport(p->sa), urioptions); } else { snprintf(invite, sizeof(invite), "sip:%s%s", p->tohost, urioptions); } @@ -4486,7 +4581,7 @@ /* Copy back Call-ID in case create_addr changed it */ strncpy(r->callid, p->callid, sizeof(r->callid) - 1); if (r->portno) - p->sa.sin_port = htons(r->portno); + net_addr_setport(p->sa, htons(r->portno)); ast_set_flag(p, SIP_OUTGOING); /* Registration is outgoing call */ r->call=p; /* Save pointer to SIP packet */ p->registry=ASTOBJ_REF(r); /* Add pointer to registry in packet */ @@ -4516,8 +4611,8 @@ based on whether the remote host is on the external or internal network so we can register through nat */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) - memcpy(&p->ourip, &bindaddr.sin_addr, sizeof(p->ourip)); + if (ast_sip_ouraddrfor(p->sa, p->ourip)) + net_addr_cpyhost(p->ourip, bindaddr); build_contact(p); } @@ -4696,7 +4791,7 @@ static int expire_register(void *data) { struct sip_peer *p = data; - memset(&p->addr, 0, sizeof(p->addr)); + net_addr_clr(p->addr); ast_db_del("SIP/Registry", p->name); manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name); register_peer_exten(p, 0); @@ -4723,16 +4818,18 @@ static void reg_source_db(struct sip_peer *p) { char data[256]; - char iabuf[INET_ADDRSTRLEN]; - struct in_addr in; + char iabuf[NET_ADDRSTRLEN]; char *c, *d, *u, *e; int expiry; if (!ast_db_get("SIP/Registry", p->name, data, sizeof(data))) { c = strchr(data, ':'); if (c) { + net_sockaddr *sin; + *c = '\0'; c++; - if (inet_aton(data, &in)) { + sin = net_addr_new(); + if (net_aton(data, sin)) { d = strchr(c, ':'); if (d) { *d = '\0'; @@ -4752,12 +4849,15 @@ } if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peers from Astdb: '%s' at %s@%s:%d for %d\n", p->name, - p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); + p->username, net_ntoa(iabuf, sizeof(iabuf), sin), atoi(c), atoi(d)); expiry = atoi(d); - memset(&p->addr, 0, sizeof(p->addr)); - p->addr.sin_family = AF_INET; - p->addr.sin_addr = in; - p->addr.sin_port = htons(atoi(c)); + + if (p->addr) + net_addr_delete(p->addr); + p->addr = sin; + sin = NULL; + + net_addr_setport(p->addr, atoi(c)); if (sipsock < 0) { /* SIP isn't up yet, so schedule a poke only, pretty soon */ if (p->pokeexpire > -1) @@ -4781,10 +4881,8 @@ { char contact[250]= ""; char *c, *n, *pt; + char *host; int port; - struct hostent *hp; - struct ast_hostent ahp; - struct sockaddr_in oldsin; /* Look for brackets */ strncpy(contact, get_header(req, "Contact"), sizeof(contact) - 1); @@ -4825,7 +4923,22 @@ *n = '\0'; n++; } - pt = strchr(n, ':'); + if (*n == '[') { + n++; + host = n; + n = strchr(host, ']'); + + if (n) { + *n = '\0'; + n++; + pt = strchr(n, ':'); + } else { + pt = NULL; + } + } else { + host = n; + pt = strchr(n, ':'); + } if (pt) { *pt = '\0'; pt++; @@ -4833,23 +4946,21 @@ } else port = DEFAULT_SIP_PORT; - memcpy(&oldsin, &pvt->sa, sizeof(oldsin)); + //net_addr_cpy(oldsin, pvt->sa); if (!(ast_test_flag(pvt, SIP_NAT) & SIP_NAT_ROUTE)) { /* XXX This could block for a long time XXX */ /* We should only do this if it's a name, not an IP */ - hp = ast_gethostbyname(n, &ahp); - if (!hp) { - ast_log(LOG_WARNING, "Invalid host '%s'\n", n); + net_addr_init(pvt->sa, PF_UNSPEC, SOCK_DGRAM, 0); + if (net_addr_get(pvt->sa, host)) { + ast_log(LOG_WARNING, "Invalid host '%s'\n", host); return -1; } - pvt->sa.sin_family = AF_INET; - memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); - pvt->sa.sin_port = htons(port); + net_addr_setport(pvt->sa, port); } else { /* Don't trust the contact field. Just use what they came to us with. */ - memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa)); + net_addr_cpy(pvt->sa, pvt->recv); } return 0; } @@ -4860,15 +4971,13 @@ { char contact[80]= ""; char data[256]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char *expires = get_header(req, "Expires"); int expiry = atoi(expires); char *c, *n, *pt; int port; char *useragent; - struct hostent *hp; - struct ast_hostent ahp; - struct sockaddr_in oldsin; + net_sockaddr *oldsin; if (ast_strlen_zero(expires)) { /* No expires header */ expires = strstr(get_header(req, "Contact"), "expires="); @@ -4893,7 +5002,7 @@ } if (!strcasecmp(c, "*") || !expiry) { /* Unregister this peer */ /* This means remove all registrations and return OK */ - memset(&p->addr, 0, sizeof(p->addr)); + net_addr_clr(p->addr); if (p->expire > -1) ast_sched_del(sched, p->expire); p->expire = -1; @@ -4930,28 +5039,42 @@ *n = '\0'; n++; } - pt = strchr(n, ':'); + + /* Parse IPv6 addresses */ + if (*n == '[') { + n++; + pt = strchr(n, ']'); + if (pt) { + *pt = '\0'; + pt++; + if (*pt != ':') { + pt = NULL; + } + } + } else { + pt = strchr(n, ':'); + } + if (pt) { *pt = '\0'; pt++; port = atoi(pt); } else port = DEFAULT_SIP_PORT; - memcpy(&oldsin, &p->addr, sizeof(oldsin)); + net_addr_alloca(&oldsin); + net_addr_cpy(oldsin, p->addr); if (!(ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE)) { /* XXX This could block for a long time XXX */ - hp = ast_gethostbyname(n, &ahp); - if (!hp) { + net_addr_setfamily(p->addr, PF_UNSPEC); + if (net_addr_get(p->addr, n)) { ast_log(LOG_WARNING, "Invalid host '%s'\n", n); return -1; } - p->addr.sin_family = AF_INET; - memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr)); - p->addr.sin_port = htons(port); + net_addr_setport(p->addr, port); } else { /* Don't trust the contact field. Just use what they came to us with */ - memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); + net_addr_cpy(p->addr, pvt->recv); } if (c) /* Overwrite the default username from config at registration */ @@ -4968,13 +5091,13 @@ else p->expire = -1; pvt->expiry = expiry; - snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry, p->username, p->fullcontact); + snprintf(data, sizeof(data), "%s:%d:%s:%s", net_ntostr(iabuf, sizeof(iabuf), p->addr), expiry, p->username, p->fullcontact); ast_db_put("SIP/Registry", p->name, data); manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", p->name); - if (inaddrcmp(&p->addr, &oldsin)) { + if (net_addr_cmp(p->addr, oldsin)) { sip_poke_peer(p); if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", p->name, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr), ntohs(p->addr.sin_port), expiry); + ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s expires %d\n", p->name, net_ntostr(iabuf, sizeof(iabuf), p->addr), expiry); register_peer_exten(p, 1); } @@ -4986,6 +5109,7 @@ ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name); } } +/* net_addr_delete(oldsin); */ return 0; } @@ -5276,12 +5400,12 @@ } /*--- register_verify: Verify registration of user */ -static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore) +static int register_verify(struct sip_pvt *p, net_sockaddr *sin, struct sip_request *req, char *uri, int ignore) { int res = -1; struct sip_peer *peer; char tmp[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char *name, *c; char *t; /* Terminate URI */ @@ -5301,7 +5425,7 @@ name = c + 4; } else { name = c; - ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, net_ntoa(iabuf, sizeof(iabuf), sin)); } /* Strip off the domain name */ c = strchr(name, '@'); @@ -5686,10 +5810,9 @@ static int check_via(struct sip_pvt *p, struct sip_request *req) { char via[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char *c, *pt; - struct hostent *hp; - struct ast_hostent ahp; + char *host; memset(via, 0, sizeof(via)); strncpy(via, get_header(req, "Via"), sizeof(via) - 1); @@ -5706,28 +5829,39 @@ ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); return -1; } + if (*c == '[') { + c++; + host = c; + c = strchr(c, ']'); + if (!c) { + ast_log(LOG_WARNING, "'%s' is not a valid IPv6 ip number\n", c); + return -1; + } + + *c = '\0'; + c++; + } else { + host = c; + } pt = strchr(c, ':'); if (pt) { *pt = '\0'; pt++; } - hp = ast_gethostbyname(c, &ahp); - if (!hp) { + net_addr_clr(p->sa); + if (net_addr_get(p->sa, host)) { ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); return -1; } - memset(&p->sa, 0, sizeof(p->sa)); - p->sa.sin_family = AF_INET; - memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); - p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); + net_addr_setport(p->sa, pt ? atoi(pt) : DEFAULT_SIP_PORT); c = strstr(via, ";rport"); if (c && (c[6] != '=')) ast_set_flag(p, SIP_NAT_ROUTE); if (sip_debug_test_pvt(p)) { if (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE) - ast_verbose("Sending to %s : %d (NAT)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port)); + ast_verbose("Sending to %s (NAT)\n", net_ntoa(iabuf, sizeof(iabuf), p->sa)); else - ast_verbose("Sending to %s : %d (non-NAT)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port)); + ast_verbose("Sending to %s (non-NAT)\n", net_ntoa(iabuf, sizeof(iabuf), p->sa)); } } return 0; @@ -5811,13 +5945,13 @@ /*--- check_user: Check if matching user or peer is defined ---*/ -static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen) +static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, net_sockaddr *sin, int ignore, char *mailbox, int mailboxlen) { struct sip_user *user; struct sip_peer *peer; char *of, from[256] = "", *c; char *rpid,rpid_num[50]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int res = 0; char *t; char calleridname[50]; @@ -5944,7 +6078,7 @@ /* If peer is registred from this IP address or have this as a default IP address, this call is from the peer */ - peer = find_peer(NULL, &p->recv, 1); + peer = find_peer(NULL, p->recv, 1); if (peer) { if (debug) ast_verbose("Found peer '%s'\n", peer->name); @@ -6024,7 +6158,7 @@ ASTOBJ_UNREF(peer,sip_destroy_peer); } else { if (debug) - ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); + ast_verbose("Found no matching peer or user for '%s'\n", net_ntoa(iabuf, sizeof(iabuf), p->recv)); /* do we allow guests? */ if (!global_allowguest) @@ -6045,7 +6179,7 @@ } /*--- check_user: Find user ---*/ -static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore) +static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, net_sockaddr *sin, int ignore) { return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0); } @@ -6266,7 +6400,7 @@ #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-15.15s %-8d %-10s\n" char name[256] = ""; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int total_peers = 0; int peers_online = 0; int peers_offline = 0; @@ -6305,7 +6439,7 @@ continue; } - ast_inet_ntoa(nm, sizeof(nm), iterator->mask); + net_ntoa(nm, sizeof(nm), iterator->mask); if (!ast_strlen_zero(iterator->username) && !s) snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); else @@ -6322,7 +6456,7 @@ peers_online++; } else { /* Checking if port is 0 */ - if ( ntohs(iterator->addr.sin_port) == 0 ) { + if ( net_addr_getport(iterator->addr) == 0 ) { peers_offline++; } else { peers_online++; @@ -6332,7 +6466,7 @@ } else { strncpy(status, "Unmonitored", sizeof(status) - 1); /* Checking if port is 0 */ - if ( ntohs(iterator->addr.sin_port) == 0 ) { + if ( net_addr_getport(iterator->addr) == 0 ) { peers_offline++; } else { peers_online++; @@ -6340,20 +6474,20 @@ } snprintf(srch, sizeof(srch), FORMAT, name, - iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", + !net_addr_ishostnull(iterator->addr) ? net_ntoa(iabuf, sizeof(iabuf), iterator->addr) : "(Unspecified)", ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ iterator->ha ? " A " : " ", /* permit/deny */ - nm, ntohs(iterator->addr.sin_port), status); + nm, net_addr_getport(iterator->addr), status); if (!s) {/* Normal CLI list */ ast_cli(fd, FORMAT, name, - iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)", + !net_addr_ishostnull(iterator->addr) ? net_ntoa(iabuf, sizeof(iabuf), iterator->addr) : "(Unspecified)", ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ iterator->ha ? " A " : " ", /* permit/deny */ nm, - ntohs(iterator->addr.sin_port), status); + net_addr_getport(iterator->addr), status); } else { /* Manager format */ /* The names here need to be the same as other channels */ ast_mutex_lock(&s->lock); @@ -6370,8 +6504,8 @@ "Status: %s\r\n\r\n", idtext, iterator->name, - iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-", - ntohs(iterator->addr.sin_port), + !net_addr_ishostnull(iterator->addr) ? net_ntoa(iabuf, sizeof(iabuf), iterator->addr) : "-none-", + net_addr_getport(iterator->addr), ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ iterator->ha ? "yes" : "no", /* permit/deny */ @@ -6524,7 +6658,7 @@ { char status[30] = ""; char cbuf[256]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; struct sip_peer *peer; char codec_buf[512]; struct ast_codec_pref *pref; @@ -6592,8 +6726,8 @@ ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); ast_cli(fd, " ToHost : %s\n", peer->tohost); - ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); - ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); + ast_cli(fd, " Addr->IP : %s Port %d\n", !net_addr_ishostnull(peer->addr) ? net_ntoa(iabuf, sizeof(iabuf), peer->addr) : "(Unspecified)", net_addr_getport(peer->addr)); + ast_cli(fd, " Defaddr->IP : %s Port %d\n", net_ntoa(iabuf, sizeof(iabuf), peer->defaddr), net_addr_getport(peer->defaddr)); ast_cli(fd, " Def. Username: %s\n", peer->username); ast_cli(fd, " Codecs : "); ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); @@ -6675,8 +6809,8 @@ ast_cli(fd, "SIP-DTMFmode %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF))); ast_cli(fd, "SIPLastMsg: %d\r\n", peer->lastmsg); ast_cli(fd, "ToHost: %s\r\n", peer->tohost); - ast_cli(fd, "Address-IP: %s\r\nAddress-Port: %d\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port)); - ast_cli(fd, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); + ast_cli(fd, "Address-IP: %s\r\nAddress-Port: %d\r\n", !net_addr_ishostnull(peer->addr) ? net_ntoa(iabuf, sizeof(iabuf), peer->addr) : "", net_addr_getport(peer->addr)); + ast_cli(fd, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", net_ntoa(iabuf, sizeof(iabuf), peer->defaddr), net_addr_getport(peer->defaddr)); ast_cli(fd, "Default-Username: %s\r\n", peer->username); ast_cli(fd, "Codecs: "); ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); @@ -6829,7 +6963,7 @@ #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %s %s\n" #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-6.6s%s %s\n" struct sip_pvt *cur; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int numchans = 0; if (argc != 3) return RESULT_SHOWUSAGE; @@ -6841,7 +6975,7 @@ ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "URI"); while (cur) { if (!cur->subscribed && !subscriptions) { - ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), + ast_cli(fd, FORMAT, net_ntoa(iabuf, sizeof(iabuf), cur->sa), ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, cur->callid, cur->ocseq, cur->icseq, @@ -6851,7 +6985,7 @@ numchans++; } if (cur->subscribed && subscriptions) { - ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), + ast_cli(fd, FORMAT3, net_ntoa(iabuf, sizeof(iabuf), cur->sa), ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username, cur->callid, cur->uri); @@ -6991,7 +7125,7 @@ static int sip_show_channel(int fd, int argc, char *argv[]) { struct sip_pvt *cur; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; size_t len; int found = 0; @@ -7014,8 +7148,8 @@ ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); - ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); - ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); + ast_cli(fd, " Theoretical Address: %s\n", net_ntostr(iabuf, sizeof(iabuf), cur->sa)); + ast_cli(fd, " Received Address: %s\n", net_ntostr(iabuf, sizeof(iabuf), cur->recv)); ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(cur, SIP_NAT))); ast_cli(fd, " Our Tag: %08d\n", cur->tag); ast_cli(fd, " Their Tag: %s\n", cur->theirtag); @@ -7170,9 +7304,7 @@ /*--- sip_do_debug: Enable SIP Debugging in CLI ---*/ static int sip_do_debug_ip(int fd, int argc, char *argv[]) { - struct hostent *hp; - struct ast_hostent ahp; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int port = 0; char *p, *arg; @@ -7185,17 +7317,18 @@ p++; port = atoi(p); } - hp = ast_gethostbyname(arg, &ahp); - if (hp == NULL) { + if (!debugaddr) + debugaddr = net_addr_new(); + if (net_addr_get(debugaddr, arg)) { + net_addr_delete(debugaddr); + debugaddr = NULL; return RESULT_SHOWUSAGE; } - debugaddr.sin_family = AF_INET; - memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); - debugaddr.sin_port = htons(port); + net_addr_setport(debugaddr, port); if (port == 0) - ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr)); + ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", net_ntoa(iabuf, sizeof(iabuf), debugaddr)); else - ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), port); + ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", net_ntostr(iabuf, sizeof(iabuf), debugaddr)); sipdebug = 1; return RESULT_SUCCESS; } @@ -7203,16 +7336,17 @@ static int sip_do_debug_peer(int fd, int argc, char *argv[]) { struct sip_peer *peer; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (argc != 4) return RESULT_SHOWUSAGE; peer = find_peer(argv[3], NULL, 1); if (peer) { - if (peer->addr.sin_addr.s_addr) { - debugaddr.sin_family = AF_INET; - memcpy(&debugaddr.sin_addr, &peer->addr.sin_addr, sizeof(debugaddr.sin_addr)); - debugaddr.sin_port = peer->addr.sin_port; - ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), debugaddr.sin_addr), ntohs(debugaddr.sin_port)); + if (!net_addr_ishostnull(peer->addr)) { + if (!debugaddr) + debugaddr = net_addr_new(); + net_addr_cpy(debugaddr, peer->addr); + net_addr_setport(debugaddr, net_addr_getport(peer->addr)); + ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", net_ntostr(iabuf, sizeof(iabuf), debugaddr)); sipdebug = 1; } else ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[3]); @@ -7234,7 +7368,10 @@ else return RESULT_SHOWUSAGE; } sipdebug = 1; - memset(&debugaddr, 0, sizeof(debugaddr)); + if (debugaddr) { + net_addr_delete(debugaddr); + debugaddr = NULL; + } ast_cli(fd, "SIP Debugging Enabled\n"); return RESULT_SUCCESS; } @@ -7284,8 +7421,8 @@ add_blank_header(&req); /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) - memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + if (ast_sip_ouraddrfor(p->sa, p->ourip)) + net_addr_cpy(p->ourip, __ourip); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); @@ -7481,7 +7618,7 @@ char resp_hash[256]; char uri[256] = ""; char cnonce[80]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; char *username; char *secret; char *md5secret; @@ -7492,7 +7629,7 @@ else if (!ast_strlen_zero(p->uri)) strncpy(uri, p->uri, sizeof(uri) - 1); else - snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); + snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, net_ntoa(iabuf, sizeof(iabuf), p->sa)); snprintf(cnonce, sizeof(cnonce), "%08x", rand()); @@ -7721,7 +7858,7 @@ struct sip_peer *peer; int pingtime; struct timeval tv; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int sipmethod; c = get_header(req, "Cseq"); @@ -7991,8 +8128,8 @@ } } else if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { if (ast_strlen_zero(p->authname)) - ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", - msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); + ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", + msg, net_ntostr(iabuf, sizeof(iabuf), p->recv)); if ((p->authtries > 1) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); ast_set_flag(p, SIP_NEEDDESTROY); @@ -8011,12 +8148,12 @@ if (p->owner) ast_queue_control(p->owner, AST_CONTROL_CONGESTION); } else - ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), msg); + ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", net_ntoa(iabuf, sizeof(iabuf), p->sa), msg); break; default: if ((resp >= 300) && (resp < 700)) { if ((option_verbose > 2) && (resp != 487)) - ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); + ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, net_ntoa(iabuf, sizeof(iabuf), p->sa)); ast_set_flag(p, SIP_ALREADYGONE); if (p->rtp) { /* Immediately stop RTP */ @@ -8091,7 +8228,7 @@ } } } else - ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); + ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : net_ntoa(iabuf, sizeof(iabuf), p->sa)); } } else { if (sip_debug_test_pvt(p)) @@ -8105,8 +8242,8 @@ case 407: if (sipmethod == SIP_BYE || sipmethod == SIP_REFER) { if (ast_strlen_zero(p->authname)) - ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", - msg, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); + ast_log(LOG_WARNING, "Asked to authenticate %s, to %s but we have no matching peer!\n", + msg, net_ntostr(iabuf, sizeof(iabuf), p->recv)); if ((p->authtries > 1) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); ast_set_flag(p, SIP_NEEDDESTROY); @@ -8308,7 +8445,7 @@ } /*--- handle_request_invite: Handle incoming INVITE request */ -static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e) +static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, net_sockaddr *sin, int *recount, char *e) { int res = 1; struct ast_channel *c=NULL; @@ -8614,7 +8751,7 @@ struct ast_channel *c=NULL; int res; struct ast_channel *bridged_to; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; copy_request(&p->initreq, req); check_via(p, req); @@ -8629,7 +8766,7 @@ } if (!ast_strlen_zero(get_header(req, "Also"))) { ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); + net_ntoa(iabuf, sizeof(iabuf), p->recv)); if (ast_strlen_zero(p->context)) strncpy(p->context, default_context, sizeof(p->context) - 1); res = get_also_info(p, req); @@ -8645,7 +8782,7 @@ ast_queue_hangup(p->owner); } } else { - ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr)); + ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", net_ntoa(iabuf, sizeof(iabuf), p->recv)); ast_queue_hangup(p->owner); } } else if (p->owner) @@ -8674,7 +8811,7 @@ return 1; } /*--- handle_request_subscribe: Handle incoming SUBSCRIBE request ---*/ -static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, int seqno, char *e) +static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, net_sockaddr *sin, int seqno, char *e) { int gotdest; int res = 0; @@ -8786,10 +8923,10 @@ } /*--- handle_request_register: Handle incoming REGISTER request ---*/ -static int handle_request_register(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, struct sockaddr_in *sin, char *e) +static int handle_request_register(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, net_sockaddr *sin, char *e) { int res = 0; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; /* Use this as the basis */ if (debug) @@ -8797,7 +8934,7 @@ copy_request(&p->initreq, req); check_via(p, req); if ((res = register_verify(p, sin, req, e, ignore)) < 0) - ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s'\n", get_header(req, "To"), ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); + ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s'\n", get_header(req, "To"), net_ntoa(iabuf, sizeof(iabuf), sin)); if (res < 1) { /* Go ahead and free RTP port */ if (p->rtp) { @@ -8816,7 +8953,7 @@ } /*--- handle_request: Handle SIP requests (methods) ---*/ /* this is where all incoming requests go first */ -static int handle_request(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) +static int handle_request(struct sip_pvt *p, struct sip_request *req, net_sockaddr *sin, int *recount, int *nounlock) { /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things relatively static */ @@ -8830,7 +8967,7 @@ int ignore=0; int respid; int res = 0; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; int debug = sip_debug_test_pvt(p); char *e; @@ -8987,7 +9124,7 @@ default: transmit_response_with_allow(p, "405 Method Not Allowed", req, 0); ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", - cmd, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr)); + cmd, net_ntoa(iabuf, sizeof(iabuf), p->sa)); /* If this is some new method, and we don't have a call, destroy it now */ if (!p->initreq.headers) ast_set_flag(p, SIP_NEEDDESTROY); @@ -9001,18 +9138,18 @@ static int sipsock_read(int *id, int fd, short events, void *ignore) { struct sip_request req; - struct sockaddr_in sin = { 0, }; + net_sockaddr *sin; struct sip_pvt *p; int res; - int len; int nounlock; int recount = 0; int debug; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; + + net_addr_alloca(&sin); - len = sizeof(sin); memset(&req, 0, sizeof(req)); - res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); + res = net_recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, sin); if (res < 0) { #if !defined(__FreeBSD__) if (errno == EAGAIN) @@ -9021,15 +9158,16 @@ #endif if (errno != ECONNREFUSED) ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); +/* net_addr_delete(sin); */ return 1; } req.data[res] = '\0'; req.len = res; - debug = sip_debug_test_addr(&sin); + debug = sip_debug_test_addr(sin); if (pedanticsipchecking) req.len = lws2sws(req.data, req.len); if (debug) - ast_verbose("\n<-- SIP read from %s:%d: \n%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), req.data); + ast_verbose("\n<-- SIP read from %s: \n%s\n", net_ntostr(iabuf, sizeof(iabuf), sin), req.data); parse(&req); if (debug) { ast_verbose("--- (%d headers %d lines)", req.headers, req.lines); @@ -9040,12 +9178,13 @@ if (req.headers < 2) { /* Must have at least two headers */ +/* net_addr_delete(sin); */ return 1; } /* Process request, with netlock held */ retrylock: ast_mutex_lock(&netlock); - p = find_call(&req, &sin); + p = find_call(&req, sin); if (p) { /* Go ahead and lock the owner if it has one -- we may need it */ if (p->owner && ast_mutex_trylock(&p->owner->lock)) { @@ -9056,7 +9195,7 @@ usleep(1); goto retrylock; } - memcpy(&p->recv, &sin, sizeof(p->recv)); + net_addr_cpy(p->recv, sin); if (recordhistory) { char tmp[80] = ""; /* This is a response, note what it was for */ @@ -9064,7 +9203,7 @@ append_history(p, "Rx", tmp); } nounlock = 0; - handle_request(p, &req, &sin, &recount, &nounlock); + handle_request(p, &req, sin, &recount, &nounlock); if (p->owner && !nounlock) ast_mutex_unlock(&p->owner->lock); ast_mutex_unlock(&p->lock); @@ -9073,6 +9212,7 @@ if (recount) ast_update_use_count(); +/* net_addr_delete(sin); */ return 1; } @@ -9107,8 +9247,8 @@ return 0; } /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) - memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + if (ast_sip_ouraddrfor(p->sa,p->ourip)) + net_addr_cpy(p->ourip, __ourip); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); /* Send MWI */ @@ -9155,7 +9295,7 @@ sip = iflist; while(sip) { ast_mutex_lock(&sip->lock); - if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip.sin_addr.s_addr) { + if (sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) && !sip->redirip) { if (sip->lastrtptx && sip->rtpkeepalive && t > sip->lastrtptx + sip->rtpkeepalive) { /* Need to send an empty RTP packet */ time(&sip->lastrtptx); @@ -9163,9 +9303,10 @@ } if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) && t > sip->lastrtprx + sip->rtptimeout) { /* Might be a timeout now -- see if we're on hold */ - struct sockaddr_in sin; - ast_rtp_get_peer(sip->rtp, &sin); - if (sin.sin_addr.s_addr || + net_sockaddr *sin; + net_addr_alloca(&sin); + ast_rtp_get_peer(sip->rtp, sin); + if (!net_addr_ishostnull(sin) || (sip->rtpholdtimeout && (t > sip->lastrtprx + sip->rtpholdtimeout))) { /* Needs a hangup */ @@ -9183,6 +9324,7 @@ } } } +/* net_addr_delete(sin); */ } } if (ast_test_flag(sip, SIP_NEEDDESTROY) && !sip->packets && !sip->owner) { @@ -9305,7 +9447,7 @@ static int sip_poke_peer(struct sip_peer *peer) { struct sip_pvt *p; - if (!peer->maxms || !peer->addr.sin_addr.s_addr) { + if (!peer->maxms || net_addr_ishostnull(peer->addr)) { /* IF we have no IP, or this isn't to be monitored, return imeediately after clearing things out */ if (peer->pokeexpire > -1) @@ -9324,8 +9466,8 @@ ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); return -1; } - memcpy(&p->sa, &peer->addr, sizeof(p->sa)); - memcpy(&p->recv, &peer->addr, sizeof(p->sa)); + net_addr_cpy(p->sa, peer->addr); + net_addr_cpy(p->recv, peer->addr); /* Send options to peer's fullcontact */ if (!ast_strlen_zero(peer->fullcontact)) { @@ -9335,11 +9477,11 @@ if (!ast_strlen_zero(peer->tohost)) strncpy(p->tohost, peer->tohost, sizeof(p->tohost) - 1); else - ast_inet_ntoa(p->tohost, sizeof(p->tohost), peer->addr.sin_addr); + net_ntoa(p->tohost, sizeof(p->tohost), peer->addr); /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) - memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + if (ast_sip_ouraddrfor(p->sa,p->ourip)) + net_addr_cpy(p->ourip, __ourip); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); @@ -9388,7 +9530,7 @@ if (p) { found++; res = AST_DEVICE_UNAVAILABLE; - if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && + if ((!net_addr_ishostnull(p->addr) || !net_addr_ishostnull(p->defaddr)) && (!p->maxms || ((p->lastms > -1) && (p->lastms <= p->maxms)))) { /* peer found and valid */ res = AST_DEVICE_UNKNOWN; @@ -9457,8 +9599,8 @@ if (ast_strlen_zero(p->peername) && ext) strncpy(p->peername, ext, sizeof(p->peername) - 1); /* Recalculate our side, and recalculate Call ID */ - if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) - memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); + if (ast_sip_ouraddrfor(p->sa,p->ourip)) + net_addr_cpy(p->ourip, __ourip); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); @@ -9791,8 +9933,9 @@ strncpy(peer->context, default_context, sizeof(peer->context)-1); strncpy(peer->language, default_language, sizeof(peer->language)-1); strncpy(peer->musicclass, global_musicclass, sizeof(peer->musicclass)-1); - peer->addr.sin_port = htons(DEFAULT_SIP_PORT); - peer->addr.sin_family = AF_INET; + peer->addr = net_addr_new(); + net_addr_init(peer->addr, PF_UNSPEC, SOCK_DGRAM, 0); + net_addr_setport(peer->addr, DEFAULT_SIP_PORT); peer->expiry = expiry; peer->capability = global_capability; peer->rtptimeout = global_rtptimeout; @@ -9847,9 +9990,13 @@ if (!found) { if (name) strncpy(peer->name, name, sizeof(peer->name)-1); - peer->addr.sin_port = htons(DEFAULT_SIP_PORT); - peer->addr.sin_family = AF_INET; - peer->defaddr.sin_family = AF_INET; + peer->addr = net_addr_new(); + net_addr_init(peer->addr, PF_UNSPEC, SOCK_DGRAM, 0); + net_addr_setport(peer->addr, DEFAULT_SIP_PORT); + peer->mask = net_addr_new(); + peer->defaddr = net_addr_new(); + net_addr_init(peer->defaddr, PF_UNSPEC, + SOCK_DGRAM, 0); peer->expiry = expiry; } /* If we have channel variables, remove them (reload) */ @@ -9876,7 +10023,6 @@ peer->prefs = prefs; oldha = peer->ha; peer->ha = NULL; - peer->addr.sin_family = AF_INET; ast_copy_flags(peer, &global_flags, SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_DTMF | SIP_REINVITE | SIP_INSECURE | SIP_PROG_INBAND | SIP_OSPAUTH); peer->capability = global_capability; peer->rtptimeout = global_rtptimeout; @@ -9891,7 +10037,7 @@ if (sscanf(v->value, "%li", ®seconds) != 1) regseconds = 0; } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { - inet_aton(v->value, &(peer->addr.sin_addr)); + net_aton(v->value, peer->addr); } else if (realtime && !strcasecmp(v->name, "name")) strncpy(peer->name, v->value, sizeof(peer->name)-1); else if (!strcasecmp(v->name, "secret")) @@ -9920,11 +10066,11 @@ if (!found) { /* Initialize stuff iff we're not found, otherwise we keep going with what we had */ - memset(&peer->addr.sin_addr, 0, 4); - if (peer->addr.sin_port) { + net_addr_clrhost(peer->addr); + if (!net_addr_isportnull(peer->addr)) { /* If we've already got a port, make it the default rather than absolute */ - peer->defaddr.sin_port = peer->addr.sin_port; - peer->addr.sin_port = 0; + net_addr_cpyport(peer->defaddr, peer->addr); + net_addr_setport(peer->addr, 0); } } } @@ -9935,7 +10081,7 @@ peer->expire = -1; ast_clear_flag(peer, SIP_DYNAMIC); if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { - if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) { + if (ast_get_ip_or_srv(peer->addr, v->value, "_sip._udp")) { ASTOBJ_UNREF(peer, sip_destroy_peer); return NULL; } @@ -9946,9 +10092,9 @@ strncpy(peer->tohost, v->value, sizeof(peer->tohost) - 1); } if (!maskfound) - inet_aton("255.255.255.255", &peer->mask); + net_aton("255.255.255.255", peer->mask); } else if (!strcasecmp(v->name, "defaultip")) { - if (ast_get_ip(&peer->defaddr, v->value)) { + if (ast_get_ip(peer->defaddr, v->value)) { ASTOBJ_UNREF(peer, sip_destroy_peer); return NULL; } @@ -9957,12 +10103,12 @@ peer->ha = ast_append_ha(v->name, v->value, peer->ha); } else if (!strcasecmp(v->name, "mask")) { maskfound++; - inet_aton(v->value, &peer->mask); + net_aton(v->value, peer->mask); } else if (!strcasecmp(v->name, "port")) { if (!realtime && ast_test_flag(peer, SIP_DYNAMIC)) - peer->defaddr.sin_port = htons(atoi(v->value)); + net_addr_setport(peer->defaddr, atoi(v->value)); else - peer->addr.sin_port = htons(atoi(v->value)); + net_addr_setport(peer->addr, atoi(v->value)); } else if (!strcasecmp(v->name, "callingpres")) { peer->callingpres = ast_parse_caller_presentation(v->value); if (peer->callingpres == -1) @@ -10048,7 +10194,7 @@ time(&nowtime); if ((nowtime - regseconds) > 0) { - memset(&peer->addr, 0, sizeof(peer->addr)); + net_addr_clr(peer->addr); if (option_debug) ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime); } @@ -10074,13 +10220,11 @@ struct ast_variable *v; struct sip_peer *peer; struct sip_user *user; - struct ast_hostent ahp; char *cat; char *utype; - struct hostent *hp; int format; - int oldport = ntohs(bindaddr.sin_port); - char iabuf[INET_ADDRSTRLEN]; + int oldport = 0; + char iabuf[NET_ADDRSTRLEN]; struct ast_flags dummy; cfg = ast_config_load(config); @@ -10093,9 +10237,19 @@ /* Reset IP addresses */ - memset(&bindaddr, 0, sizeof(bindaddr)); + if (!bindaddr) + bindaddr = net_addr_new(); + else + oldport = net_addr_getport(bindaddr); + net_addr_init(bindaddr, PF_UNSPEC, SOCK_DGRAM, 0); memset(&localaddr, 0, sizeof(localaddr)); - memset(&externip, 0, sizeof(externip)); +/* if (!externip) */ +/* externip = net_addr_new(); */ +/* net_addr_clr(externip); */ + + if (!__ourip) + __ourip = net_addr_new(); + memset(&prefs, 0 , sizeof(struct ast_codec_pref)); /* Initialize some reasonable defaults at SIP reload */ @@ -10111,9 +10265,8 @@ strncpy(global_realm, DEFAULT_REALM, sizeof(global_realm) - 1); strncpy(global_musicclass, "default", sizeof(global_musicclass) - 1); strncpy(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid) - 1); - memset(&outboundproxyip, 0, sizeof(outboundproxyip)); - outboundproxyip.sin_port = htons(DEFAULT_SIP_PORT); - outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ +/* net_addr_clr(outboundproxyip); */ +/* net_addr_setport(outboundproxyip, DEFAULT_SIP_PORT); */ videosupport = 0; compactheaders = 0; relaxdtmf = 0; @@ -10208,13 +10361,13 @@ strncpy(default_callerid, v->value, sizeof(default_callerid)-1); } else if (!strcasecmp(v->name, "fromdomain")) { strncpy(default_fromdomain, v->value, sizeof(default_fromdomain)-1); - } else if (!strcasecmp(v->name, "outboundproxy")) { - if (ast_get_ip_or_srv(&outboundproxyip, v->value, "_sip._udp") < 0) - ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); - } else if (!strcasecmp(v->name, "outboundproxyport")) { - /* Port needs to be after IP */ - sscanf(v->value, "%i", &format); - outboundproxyip.sin_port = htons(format); +/* } else if (!strcasecmp(v->name, "outboundproxy")) { */ +/* if (ast_get_ip_or_srv(outboundproxyip, v->value, "_sip._udp") < 0) */ +/* ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); */ +/* } else if (!strcasecmp(v->name, "outboundproxyport")) { */ +/* /\* Port needs to be after IP *\/ */ +/* sscanf(v->value, "%i", &format); */ +/* net_addr_setport(outboundproxyip, format); */ } else if (!strcasecmp(v->name, "autocreatepeer")) { autocreatepeer = ast_true(v->value); } else if (!strcasecmp(v->name, "srvlookup")) { @@ -10234,10 +10387,8 @@ if (global_reg_timeout < 1) global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; } else if (!strcasecmp(v->name, "bindaddr")) { - if (!(hp = ast_gethostbyname(v->value, &ahp))) { + if (net_addr_get(bindaddr, v->value)) { ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); - } else { - memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); } } else if (!strcasecmp(v->name, "localnet")) { struct ast_ha *na; @@ -10248,17 +10399,19 @@ } else if (!strcasecmp(v->name, "localmask")) { ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); } else if (!strcasecmp(v->name, "externip")) { - if (!(hp = ast_gethostbyname(v->value, &ahp))) + if (!externip) + externip = net_addr_new(); + if (net_addr_get(externip, v->value)) ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); - else - memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); + externexpire = 0; } else if (!strcasecmp(v->name, "externhost")) { strncpy(externhost, v->value, sizeof(externhost) - 1); - if (!(hp = ast_gethostbyname(externhost, &ahp))) + if (!externip) + externip = net_addr_new(); + if (net_addr_get(externip, externhost)) ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); - else - memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); + time(&externexpire); } else if (!strcasecmp(v->name, "externrefresh")) { if (sscanf(v->value, "%i", &externrefresh) != 1) { @@ -10290,7 +10443,7 @@ ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); } else if (!strcasecmp(v->name, "bindport")) { if (sscanf(v->value, "%i", &ourport) == 1) { - bindaddr.sin_port = htons(ourport); + net_addr_setport(bindaddr, ourport); } else { ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); } @@ -10350,20 +10503,19 @@ } cat = ast_category_browse(cfg, cat); } - if (ast_find_ourip(&__ourip, bindaddr)) { + if (ast_find_ourip(__ourip, bindaddr)) { ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); return 0; } - if (!ntohs(bindaddr.sin_port)) - bindaddr.sin_port = ntohs(DEFAULT_SIP_PORT); - bindaddr.sin_family = AF_INET; + if (net_addr_isportnull(bindaddr)) + net_addr_setport(bindaddr, DEFAULT_SIP_PORT); ast_mutex_lock(&netlock); - if ((sipsock > -1) && (ntohs(bindaddr.sin_port) != oldport)) { + if ((sipsock > -1) && (net_addr_getport(bindaddr) != oldport)) { close(sipsock); sipsock = -1; } if (sipsock < 0) { - sipsock = socket(AF_INET, SOCK_DGRAM, 0); + sipsock = net_socket(bindaddr); if (sipsock < 0) { ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); } else { @@ -10373,16 +10525,16 @@ (const char*)&reuseFlag, sizeof reuseFlag); - if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { - ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), + if (net_bind(sipsock, bindaddr) < 0) { + ast_log(LOG_WARNING, "Failed to bind to %s: %s\n", + net_ntostr(iabuf, sizeof(iabuf), bindaddr), strerror(errno)); close(sipsock); sipsock = -1; } else { if (option_verbose > 1) { - ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", - ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); + ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s\n", + net_ntostr(iabuf, sizeof(iabuf), bindaddr)); ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); } if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) @@ -10439,14 +10591,24 @@ p = chan->tech_pvt; if (p) { ast_mutex_lock(&p->lock); - if (rtp) - ast_rtp_get_peer(rtp, &p->redirip); - else - memset(&p->redirip, 0, sizeof(p->redirip)); - if (vrtp) - ast_rtp_get_peer(vrtp, &p->vredirip); - else - memset(&p->vredirip, 0, sizeof(p->vredirip)); + if (rtp) { + if (!p->redirip) + p->redirip = net_addr_new(); + ast_rtp_get_peer(rtp, p->redirip); + } else { + if (p->redirip) + net_addr_delete(p->redirip); + p->redirip = NULL; + } + if (vrtp) { + if (!p->vredirip) + p->vredirip = net_addr_new(); + ast_rtp_get_peer(vrtp, p->vredirip); + } else { + if (p->vredirip) + net_addr_delete(p->redirip); + p->vredirip = NULL; + } p->redircodecs = codecs; if (!ast_test_flag(p, SIP_GOTREFER)) { if (!p->pendinginvite) @@ -10937,6 +11099,7 @@ pl->chanvars = NULL; } free(pl); + /* Ok to call __sip_destroy? FIXME */ } iflist = NULL; ast_mutex_unlock(&iflock); Index: channels/iax2-parser.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/iax2-parser.c,v retrieving revision 1.39 diff -u -r1.39 iax2-parser.c --- channels/iax2-parser.c 29 Mar 2005 04:49:24 -0000 1.39 +++ channels/iax2-parser.c 4 Apr 2005 20:50:19 -0000 @@ -46,11 +46,12 @@ static void dump_addr(char *output, int maxlen, void *value, int len) { - struct sockaddr_in sin; - char iabuf[INET_ADDRSTRLEN]; - if (len == (int)sizeof(sin)) { - memcpy(&sin, value, len); - snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + net_sockaddr *sin; + char iabuf[NET_ADDRSTRLEN]; + + net_addr_alloca(&sin); + if (!net_addr_initfromaddr(sin, (struct sockaddr *)value, len)) { + snprintf(output, maxlen, "IPV4 %s", net_ntostr(iabuf, sizeof(iabuf), sin)); } else { snprintf(output, maxlen, "Invalid Address"); } @@ -349,7 +350,7 @@ outputf("\n"); } -void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) +void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, net_sockaddr *sin, int datalen) { char *frames[] = { "(0?)", @@ -419,7 +420,7 @@ char *class; char *subclass; char tmp[256]; - char iabuf[INET_ADDRSTRLEN]; + char iabuf[NET_ADDRSTRLEN]; if (f) { fh = f->data; snprintf(retries, (int)sizeof(retries), "%03d", f->retries); @@ -467,10 +468,10 @@ retries, fh->oseqno, fh->iseqno, class, subclass); outputf(tmp); snprintf(tmp, (int)sizeof(tmp), -" Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n", +" Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s]\n", (unsigned long)ntohl(fh->ts), ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, - ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port)); + net_ntostr(iabuf, sizeof(iabuf), sin)); outputf(tmp); if (fh->type == AST_FRAME_IAX) dump_ies(fh->iedata, datalen); @@ -491,9 +492,15 @@ return 0; } -int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin) +int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, net_sockaddr *sin) { - return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in)); + struct sockaddr_storage storage; + socklen_t len = sizeof(storage); + + if (net_addr_toaddr(sin, (struct sockaddr*)&storage, &len) < 0) + return -1; + + return iax_ie_append_raw(ied, ie, (struct sockaddr *)&storage, len); } int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value) @@ -648,7 +655,12 @@ ies->rsa_result = data + 2; break; case IAX_IE_APPARENT_ADDR: - ies->apparent_addr = ((struct sockaddr_in *)(data + 2)); + if (!ies->apparent_addr) { + ies->apparent_addr = net_addr_new(); + } + net_addr_initfromaddr(ies->apparent_addr, + (struct sockaddr *)data + 2, + len); break; case IAX_IE_REFRESH: if (len != (int)sizeof(unsigned short)) { Index: channels/iax2-parser.h =================================================================== RCS file: /usr/cvsroot/asterisk/channels/iax2-parser.h,v retrieving revision 1.16 diff -u -r1.16 iax2-parser.h --- channels/iax2-parser.h 12 Feb 2005 18:52:14 -0000 1.16 +++ channels/iax2-parser.h 4 Apr 2005 20:50:19 -0000 @@ -14,6 +14,8 @@ #ifndef _IAX2_PARSER_H #define _IAX2_PARSER_H +#include + struct iax_ies { char *called_number; char *calling_number; @@ -38,7 +40,7 @@ char *challenge; char *md5_result; char *rsa_result; - struct sockaddr_in *apparent_addr; + net_sockaddr *apparent_addr; /* FIXME */ unsigned short refresh; unsigned short dpstatus; unsigned short callno; @@ -128,12 +130,12 @@ extern void iax_set_output(void (*output)(const char *data)); /* Choose a different function for errors */ extern void iax_set_error(void (*output)(const char *data)); -extern void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen); +extern void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, net_sockaddr *sin, int datalen); extern const char *iax_ie2str(int ie); extern int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, void *data, int datalen); -extern int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin); +extern int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, net_sockaddr *sin); extern int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value); extern int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value); extern int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, unsigned char *str); Index: include/asterisk/acl.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/acl.h,v retrieving revision 1.11 diff -u -r1.11 acl.h --- include/asterisk/acl.h 9 Mar 2005 05:48:11 -0000 1.11 +++ include/asterisk/acl.h 4 Apr 2005 20:50:19 -0000 @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define AST_SENSE_DENY 0 #define AST_SENSE_ALLOW 1 @@ -38,27 +40,26 @@ extern void ast_free_ha(struct ast_ha *ha); extern struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path); -extern int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin); -extern int ast_get_ip(struct sockaddr_in *sin, const char *value); -extern int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service); -extern int ast_ouraddrfor(struct in_addr *them, struct in_addr *us); +extern int ast_apply_ha(struct ast_ha *ha, net_sockaddr *sin); +extern int ast_get_ip(net_sockaddr *sin, const char *value); +extern int ast_get_ip_or_srv(net_sockaddr *sin, const char *value, const char *service); +extern int ast_ouraddrfor(net_sockaddr *them, net_sockaddr *us); extern int ast_lookup_iface(char *iface, struct in_addr *address); extern struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original); extern int ast_netsock_init(struct ast_netsock_list *list); extern struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, ast_io_cb callback, void *data); -extern struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct sockaddr_in *bindaddr, int tos, ast_io_cb callback, void *data); +extern struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, net_sockaddr *bindaddr, int tos, ast_io_cb callback, void *data); extern int ast_netsock_free(struct ast_netsock_list *list, struct ast_netsock *netsock); extern int ast_netsock_release(struct ast_netsock_list *list); extern int ast_netsock_sockfd(struct ast_netsock *ns); -extern const struct sockaddr_in *ast_netsock_boundaddr(struct ast_netsock *ns); +extern const net_sockaddr *ast_netsock_boundaddr(struct ast_netsock *ns); extern void *ast_netsock_data(struct ast_netsock *ns); -extern int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr); +extern int ast_find_ourip(net_sockaddr *ourip, net_sockaddr *bindaddr); -/*! Compares the source address and port of two sockaddr_in */ -static inline int inaddrcmp(struct sockaddr_in *sin1, struct sockaddr_in *sin2) +/* ! Compares the source address and port of two ast_sockaddr */ +static inline int inaddrcmp(net_sockaddr *sin1, net_sockaddr *sin2) { - return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr ) - || (sin1->sin_port != sin2->sin_port)); + return net_addr_cmp(sin1, sin2); } #if defined(__cplusplus) || defined(c_plusplus) Index: include/asterisk/manager.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/manager.h,v retrieving revision 1.13 diff -u -r1.13 manager.h --- include/asterisk/manager.h 22 Mar 2005 19:09:12 -0000 1.13 +++ include/asterisk/manager.h 4 Apr 2005 20:50:19 -0000 @@ -24,6 +24,7 @@ #include #include +#include /*! \file manager.h @@ -63,7 +64,7 @@ /*! Thread lock */ ast_mutex_t lock; /*! socket address */ - struct sockaddr_in sin; + net_sockaddr *sin; /*! TCP socket */ int fd; int blocking; Index: include/asterisk/rtp.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/rtp.h,v retrieving revision 1.20 diff -u -r1.20 rtp.h --- include/asterisk/rtp.h 4 Mar 2005 06:47:24 -0000 1.20 +++ include/asterisk/rtp.h 4 Apr 2005 20:50:20 -0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -53,13 +54,13 @@ struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode); -struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in); +struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, net_sockaddr *in); -void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them); +void ast_rtp_set_peer(struct ast_rtp *rtp, net_sockaddr *them); -void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them); +void ast_rtp_get_peer(struct ast_rtp *rtp, net_sockaddr *them); -void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us); +void ast_rtp_get_us(struct ast_rtp *rtp, net_sockaddr *us); void ast_rtp_destroy(struct ast_rtp *rtp); Index: pbx/Makefile =================================================================== RCS file: /usr/cvsroot/asterisk/pbx/Makefile,v retrieving revision 1.16 diff -u -r1.16 Makefile --- pbx/Makefile 27 Mar 2005 22:39:17 -0000 1.16 +++ pbx/Makefile 4 Apr 2005 20:50:20 -0000 @@ -13,7 +13,9 @@ -PBX_LIBS=pbx_config.so pbx_spool.so pbx_dundi.so pbx_loopback.so pbx_realtime.so +#PBX_LIBS=pbx_config.so pbx_spool.so pbx_dundi.so pbx_loopback.so pbx_realtime.so +PBX_LIBS=pbx_config.so pbx_spool.so pbx_loopback.so pbx_realtime.so +#PBX_LIBS=pbx_config.so # Add GTK console if appropriate #PBX_LIBS+=$(shell $(CROSS_COMPILE_BIN)gtk-config --cflags >/dev/null 2>/dev/null && echo "pbx_gtkconsole.so") --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ net.c 2005-04-04 21:08:43.000000000 +0200 @@ -0,0 +1,960 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Network functions + * + * Copyright (C) 2005 Mikael Magnusson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct tag_net_sockaddr { + struct sockaddr_storage addr; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t addrlen; +}; + +static inline sa_family_t my_get_ss_family(net_sockaddr *ia, const char *func) +{ + return (ia->addrlen < sizeof(sa_family_t)) ? -1 : ia->addr.ss_family; +// return ia->addr.ss_family; +} + +#define get_ss_family(ia) my_get_ss_family(ia, __FUNCTION__) + +/* Update ai_protocol from ai_family and ai_socktype */ +static int update_proto_from_type(net_sockaddr *sa) +{ + int res = -1; + + switch (sa->ai_family) { + case AF_INET: + case AF_INET6: + switch (sa->ai_socktype) { + case SOCK_STREAM: + sa->ai_protocol = IPPROTO_TCP; + break; + case SOCK_DGRAM: + sa->ai_protocol = IPPROTO_UDP; + break; + default: + sa->ai_protocol = 0; + break; + } + res = 0; + } + + return res; +} + +/* Update ai_family from address family */ +static int update_family_from_addr(net_sockaddr *sa) +{ + int res = -1; + + switch (get_ss_family(sa)) { + case AF_INET: + sa->ai_family = PF_INET; + res = 0; + break; + case AF_INET6: + sa->ai_family = PF_INET6; + res = 0; + break; + } + return res; +} + +/* Updates ai_socktype from socket */ +static int update_type_from_socket(int sock, net_sockaddr *sa) +{ + int opt = -1; + int optlen = sizeof(opt); + int res; + + res = getsockopt(sock, SOL_SOCKET, SO_TYPE, &opt, &optlen); + + if (optlen != sizeof(opt)) { + res = -1; + } + + if (res < 0) { + return res; + } + + sa->ai_socktype = opt; + return res; +} + +/* Update ai_family, ai_socktype and ai_protocol from socket */ +static int update_from_socket_addr(int socket, net_sockaddr *sa) +{ + int res; + + if ((res = update_type_from_socket(socket, sa)) < 0) + return res; + if ((res = update_family_from_addr(sa)) < 0) + return res; + if ((res = update_proto_from_type(sa)) < 0) + return res; + + return res; +} + +/* + Returns 1 if it's an IPv4 mapped IPv6 address and 0 if not. + Returns -1 it not an IPv6 address. +*/ +static int net_addr_isv4mapped(net_sockaddr *sa) +{ + int res = -1; + + switch (get_ss_family(sa)) { + case AF_INET6: { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&sa->addr; + + res = IN6_IS_ADDR_V4MAPPED(&ia->sin6_addr); + break; + } + } + + return res; +} + +/* Return v4 of v6 mapped v4 in_addr */ +static struct in_addr *get_in4_addr(net_sockaddr *sa) +{ + struct in_addr *ia = NULL; + + switch (get_ss_family(sa)) { + case AF_INET: { + struct sockaddr_in *in = + (struct sockaddr_in *)&sa->addr; + ia = &in->sin_addr; + break; + } + case AF_INET6: { + struct sockaddr_in6 *in = + (struct sockaddr_in6 *)&sa->addr; + + if (IN6_IS_ADDR_V4MAPPED(&in->sin6_addr)) { + ia = (struct in_addr*)&in->sin6_addr.s6_addr32[3]; + } + break; + } + } + return ia; +} + +/* + Convert the address to a string, + (IPv4 mapped addresses are converted as native IPv4) +*/ +const char *net_ntoa(char *buf, int bufsiz, net_sockaddr *ia) +{ + int v4mapped = 0; + int error; + struct sockaddr_in6 *in6 = + (struct sockaddr_in6 *)&ia->addr; + + if (get_ss_family(ia) == AF_INET6) { + v4mapped = IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr); + } + + if (v4mapped) { + struct in_addr ina; + + ina.s_addr = in6->sin6_addr.s6_addr32[3]; + error = !inet_ntop(AF_INET, &ina, buf, bufsiz); + } else { + error = getnameinfo((struct sockaddr *)&ia->addr, ia->addrlen, + buf, bufsiz, + NULL, 0, + NI_NUMERICHOST); + } + + if (error) { + char str[256]; + inet_ntop(AF_INET6, &ia->addr, str, sizeof(str)); + fprintf(stderr, "getnameinfo failed %d %s\n", errno, + str); + return NULL; + } + + return buf; +} + +/* + Convert the address including service (port) to a string. +*/ +const char *net_ntostr(char *buf, int bufsize, net_sockaddr *ia) +{ + char host[NET_ADDRSTRLEN]; + char serv[10]; + int error = getnameinfo((struct sockaddr *)&ia->addr, ia->addrlen, + host, sizeof(host), + serv, sizeof(serv), + NI_NUMERICHOST | NI_NUMERICSERV); + + if (error) { + return NULL; + } + + snprintf(buf, bufsize, "%s;%s", host, serv); + return buf; +} + +/* Convert the service (port) to a string */ +const char *net_ntos(char *buf, int bufsize, net_sockaddr *ia) +{ + int error = getnameinfo((struct sockaddr *)&ia->addr, sizeof(ia->addr), + NULL, 0, + buf, bufsize, + NI_NUMERICSERV); + + return error ? NULL : buf; +} + +/* + String representation of network address suitable for use in URLs. + With IPv6 addresses within brackets. + */ +const char *net_ntourl(char *buf, int bufsize, net_sockaddr *ia) +{ + int brackets = net_addr_getipver(ia) == 6; + char host[NET_ADDRSTRLEN]; + int error = !net_ntoa(host, sizeof(host), ia); + + if (error) { + return NULL; + } + + snprintf(buf, bufsize, "%s%s%s", brackets?"[":"", + host, brackets?"]":""); + return buf; +} + +/* + Lookup host/address and service(port) + Returns 1 if success and 0 if error +*/ +int net_aston(const char *cp, const char *serv, net_sockaddr *ia) +{ + int error; + struct addrinfo *hinfo = NULL; + struct addrinfo hints; + char *buf = ast_strdupa(cp); + char *ptr = buf; + char *host; + int len = strlen(buf); + + if (ptr[0] == '[' && ptr[len-1] == ']') { + host = ptr + 1; + ptr[len-1] = '\0'; + } else { + host = ptr; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = ia->ai_family; + hints.ai_socktype = ia->ai_socktype; + hints.ai_protocol = ia->ai_protocol; + + error = getaddrinfo(host, serv, &hints, &hinfo); + + if (error) { + return 0; + } + + memcpy(&ia->addr, hinfo->ai_addr, hinfo->ai_addrlen); + ia->addrlen = hinfo->ai_addrlen; + ia->ai_family = hinfo->ai_family; + ia->ai_socktype = hinfo->ai_socktype; + ia->ai_protocol = hinfo->ai_protocol; + + return 1; +} + +int net_aton(const char *cp, net_sockaddr *ia) +{ + return net_aston(cp, NULL, ia); +} + +/* Returns length of net_sockaddr struct, to be used by net_addr_alloc */ +size_t net_addr_sizeof() { + return sizeof(net_sockaddr); +} + +net_sockaddr *net_addr_new(void) +{ + net_sockaddr *sa = malloc(sizeof(net_sockaddr)); + net_addr_clr(sa); + return sa; +} + +int net_addr_delete(net_sockaddr *sa) +{ + free(sa); + return 0; +} + +int net_addr_clr(net_sockaddr *sa) +{ + memset(sa, 0, sizeof(net_sockaddr)); + sa->ai_family = PF_UNSPEC; + return 0; +} + +int net_addr_clrhost(net_sockaddr *sa) +{ + int res = 0; + + switch(get_ss_family(sa)) { + case AF_INET: { + struct sockaddr_in *ia = + (struct sockaddr_in *)&sa->addr; + ia->sin_addr.s_addr = 0; + break; + } + case AF_INET6: { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&sa->addr; + memset(ia, 0, sizeof(struct sockaddr_in6)); + break; + } + default: + res = -1; + } + + return res; +} + +int net_addr_init(net_sockaddr *sa, int family, int socktype, + int protocol) +{ + net_addr_clr(sa); + sa->ai_family = family; + sa->ai_socktype = socktype; + sa->ai_protocol = protocol; + + switch (sa->ai_family) { + case PF_INET: + sa->addr.ss_family = AF_INET; + sa->addrlen = sizeof(struct sockaddr_in); + break; + case PF_INET6: + sa->addr.ss_family = AF_INET6; + sa->addrlen = sizeof(struct sockaddr_in6); + break; + default: + sa->addr.ss_family = AF_UNSPEC; + sa->addrlen = sizeof(sa_family_t); + break; + } + + return 0; +} + +int net_addr_ishostnull(net_sockaddr *sa) +{ + int res = 0; + + switch(get_ss_family(sa)) { + case AF_INET: { + struct sockaddr_in *in = + (struct sockaddr_in *)&sa->addr; + res = in->sin_addr.s_addr == 0; + break; + } + case AF_INET6: { + struct sockaddr_in6 *in = + (struct sockaddr_in6 *)&sa->addr; + int i; + res = 1; + + for (i=0; i<4; i++) { + if (in->sin6_addr.s6_addr32[i] != 0) { + res = 0; + break; + } + } + break; + } + default: + res = -1; + } + + return res; +} + +int net_addr_isportnull(net_sockaddr *sa) +{ + return net_addr_getport(sa) == 0; +} + +/* Return 0 if same, -1 if error and 1 if different */ +int net_addr_cmphost(net_sockaddr *sa1, net_sockaddr *sa2) +{ + int res = -1; + int family1 = get_ss_family(sa1); + int family2 = get_ss_family(sa2); + struct in_addr *in1; + struct in_addr *in2; + + if ((family1 < 0) || (family2 < 0)) { + ast_log(LOG_DEBUG, "Invalid address families\n"); + return -1; + } + + in1 = get_in4_addr(sa1); + in2 = get_in4_addr(sa2); + + if (!(in1 && in2) && family1 != family2) { + ast_log(LOG_DEBUG, "Can't compare different families %p %p\n", + in1, in2); + return -1; + } + + if (in1 && in2) { + ast_log(LOG_DEBUG, "Compare v4 %08lx %08lx\n", + (unsigned long)in1->s_addr, + (unsigned long)in2->s_addr); + return in1->s_addr != in2->s_addr; + } + + switch(family1) { + case AF_INET6: { + struct sockaddr_in6 *in1 = + (struct sockaddr_in6 *)&sa1->addr; + struct sockaddr_in6 *in2 = + (struct sockaddr_in6 *)&sa2->addr; + res = 0; + int i; + + for (i=0; i<4; i++) { + if (in1->sin6_addr.s6_addr32[i] != + in2->sin6_addr.s6_addr32[i]) { + res = 1; + break; + } + } + + break; + } + } + + return res; +} + +/* Return 0 if same, -1 if error and 1 if different */ +int net_addr_cmp(net_sockaddr *sa1, net_sockaddr *sa2) +{ + int res = net_addr_cmpport(sa1, sa2); + + if (res) { + return res; + } + + return net_addr_cmphost(sa1, sa2); +} + +int net_addr_cpyhost(net_sockaddr *dst, + net_sockaddr *src) +{ +/* TODO support difference dst and src families? */ + int res = 0; + sa_family_t dstfamily = get_ss_family(dst); + + if (dstfamily != get_ss_family(src)) { + return -1; + } + + switch (dstfamily) { + case AF_INET: { + struct sockaddr_in *ia_dst = + (struct sockaddr_in *)&dst->addr; + struct sockaddr_in *ia_src = + (struct sockaddr_in *)&src->addr; + ia_dst->sin_addr.s_addr = ia_src->sin_addr.s_addr; + break; + } + case AF_INET6: { + struct sockaddr_in6 *ia_dst = + (struct sockaddr_in6 *)&dst->addr; + struct sockaddr_in6 *ia_src = + (struct sockaddr_in6 *)&src->addr; + int i; + for (i = 0; i < 4; i++) { + ia_dst->sin6_addr.s6_addr32[i] = + ia_src->sin6_addr.s6_addr32[i]; + } + break; + } + default: + res = -1; + } + + dst->addrlen = src->addrlen; + + return res; +} + +int net_addr_cpy(net_sockaddr *dst, net_sockaddr *src) +{ + memcpy(dst, src, sizeof(net_sockaddr)); + return 0; +} + +/* Returns 0 if success and 1 if error */ +int net_addr_get(net_sockaddr *sa, const char *host) +{ + return !net_aston(host, NULL, sa); +} + +int net_addr_getport(net_sockaddr *sa) +{ + switch(get_ss_family(sa)) { + case AF_INET: { + struct sockaddr_in *in = + (struct sockaddr_in *)&sa->addr; + return ntohs(in->sin_port); + } + case AF_INET6: { + struct sockaddr_in6 *in = + (struct sockaddr_in6 *)&sa->addr; + return ntohs(in->sin6_port); + } + default: + return -1; + } +} + +int net_addr_setport(net_sockaddr *sa, int port) +{ + int res = 0; + + switch(get_ss_family(sa)) { + case AF_INET: { + struct sockaddr_in *in = + (struct sockaddr_in *)&sa->addr; + in->sin_port = htons(port); + break; + } + case AF_INET6: { + struct sockaddr_in6 *in = + (struct sockaddr_in6 *)&sa->addr; + in->sin6_port = htons(port); + break; + } + default: + res = -1; + } + + return res; +} + +int net_addr_cpyport(net_sockaddr *dst, + net_sockaddr *src) +{ + int port = net_addr_getport(src); + + if (port < 0) { + return port; + } + + return net_addr_setport(dst, port); +} + +/* Return 0 if same, -1 if error and 1 if different */ +int net_addr_cmpport(net_sockaddr *sa1, + net_sockaddr *sa2) +{ + int port1 = net_addr_getport(sa1); + int port2 = net_addr_getport(sa2); + + if ((port1 < 0) || (port2 < 0)) { + return -1; + } + + return port1 != port2; +} + +int net_addr_getfamily(net_sockaddr *sa) +{ + return sa->ai_family; +} + +int net_addr_setfamily(net_sockaddr *sa, int family) +{ + sa->ai_family = family; + return 0; +} + +int net_addr_getsocktype(net_sockaddr *sa) +{ + return sa->ai_socktype; +} + +int net_addr_setsocktype(net_sockaddr *sa, int socktype) +{ + sa->ai_socktype = socktype; + return 0; +} + +int net_addr_getprotocol(net_sockaddr *sa) +{ + return sa->ai_protocol; +} + +int net_addr_setprotocol(net_sockaddr *sa, int protocol) +{ + sa->ai_protocol = protocol; + return 0; +} + +/* Init mask from nm string with family of sa */ +int net_addr_initmask(net_sockaddr *mask, net_sockaddr *sa, + const char *nm) +{ + int x; + int res = 0; + + if (sscanf(nm, "%i", &x) != 1) { + return -1; + } + + switch (get_ss_family(sa)) { + case AF_INET: { + unsigned int y; + int z; + if ((x >= 0) && (x <= 32)) { + struct sockaddr_in *ia = + (struct sockaddr_in *)&mask->addr; + y = 0; + for (z=0;z>= 1; + y |= 0x80000000; + } + ia->sin_addr.s_addr = htonl(y); + ia->sin_family = AF_INET; + mask->addrlen = sizeof(struct sockaddr_in); + mask->ai_family = PF_INET; + } + break; + } + case AF_INET6: { + unsigned int y; + int z; + int b; + if ((x >= 0) && (x <= 128)) { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&mask->addr; + memset(ia, 0, sizeof(struct sockaddr_in6)); + + for (b=0;bsin6_addr.s6_addr[b] = 0xff; + } + + y = 0; + for (z=0;z<(x-b*8);z++) { + y >>= 1; + y |= 0x80; + } + ia->sin6_addr.s6_addr[b] = y; + ia->sin6_family = AF_INET6; + mask->addrlen = sizeof(struct sockaddr_in6); + mask->ai_family = PF_INET6; + } + break; + } + default: + res = -1; + } + + return res; +} + +/* Apply mask to sa */ +int net_addr_andmask(net_sockaddr *sa, net_sockaddr *mask) +{ + int res = 0; + sa_family_t safamily = get_ss_family(sa); + + if (safamily != get_ss_family(mask)) { + return -1; + } + + switch (safamily) { + case AF_INET: { + struct sockaddr_in *ia = + (struct sockaddr_in *)&sa->addr; + struct sockaddr_in *imask = + (struct sockaddr_in *)&mask->addr; + ia->sin_addr.s_addr &= imask->sin_addr.s_addr; + break; + } + case AF_INET6: { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&sa->addr; + struct sockaddr_in6 *imask = + (struct sockaddr_in6 *)&mask->addr; + int i; + for (i=0; i<16; i++) { + ia->sin6_addr.s6_addr[i] &= + imask->sin6_addr.s6_addr[i]; + } + break; + } + default: + res = -1; + break; + } + + return res; +} + +int net_addr_checkmask(net_sockaddr *sa, + net_sockaddr *addr, + net_sockaddr *mask) +{ + int res = 0; + int v4mapped = 0; + sa_family_t addrfam = get_ss_family(addr); + + if (addrfam != get_ss_family(mask)) { + return -1; + } + + if (get_ss_family(sa) != addrfam) { + if (addrfam == AF_INET && + net_addr_isv4mapped(sa)) { + v4mapped = 1; + } else { + return -1; + } + } + + switch (addrfam) { + case AF_INET: { + struct sockaddr_in *iaddr = + (struct sockaddr_in *)&addr->addr; + struct sockaddr_in *imask = + (struct sockaddr_in *)&mask->addr; + unsigned long s_addr; + + if (v4mapped) { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&sa->addr; + s_addr = ia->sin6_addr.s6_addr32[3]; + } else { + struct sockaddr_in *ia = + (struct sockaddr_in *)&sa->addr; + s_addr = ia->sin_addr.s_addr; + } + + if ((s_addr & imask->sin_addr.s_addr) == + (iaddr->sin_addr.s_addr)) { + res = 1; + } else { + res = 0; + } + break; + } + case AF_INET6: { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&sa->addr; + struct sockaddr_in6 *iaddr = + (struct sockaddr_in6 *)&addr->addr; + struct sockaddr_in6 *imask = + (struct sockaddr_in6 *)&mask->addr; + + int i; + res = 1; + for (i=0; i<4; i++) { + if ((ia->sin6_addr.s6_addr32[i] & + imask->sin6_addr.s6_addr32[i]) != + (iaddr->sin6_addr.s6_addr32[i])) { + res = 0; + break; + } + } + break; + } + default: + res = -1; + break; + } + + return res; +} + +int net_addr_getipver(net_sockaddr *sa) +{ + int res = -1; + + switch (get_ss_family(sa)) { + case AF_INET: + res = 4; + break; + case AF_INET6: { + struct sockaddr_in6 *ia = + (struct sockaddr_in6 *)&sa->addr; + + res = IN6_IS_ADDR_V4MAPPED(&ia->sin6_addr) ? 4 : 6; + break; + } + } + + return res; +} + +int net_socket(net_sockaddr *sa) +{ + return socket(sa->ai_family, sa->ai_socktype, sa->ai_protocol); +} + +int net_getsockname(int socket, net_sockaddr *sa) +{ + int res; + + sa->addrlen = sizeof(sa->addr); + res = getsockname(socket, (struct sockaddr *)&sa->addr, &sa->addrlen); + + if (res < 0) { + return res; + } + + update_from_socket_addr(socket, sa); + return res; +} + +int net_bind(int socket, net_sockaddr *sa) +{ + return bind(socket, (struct sockaddr*)&sa->addr, sa->addrlen); +} + +int net_accept(int socket, net_sockaddr *sa) +{ + int res; + + sa->addrlen = sizeof(sa->addr); + res = accept(socket, (struct sockaddr *)&sa->addr, &sa->addrlen); + + if (res < 0) { + return res; + } + + update_from_socket_addr(socket, sa); + return res; +} + +int net_connect(int socket, net_sockaddr *sa) +{ + return connect(socket, (struct sockaddr *)&sa->addr, sa->addrlen); +} + +int net_addr_initfromaddr(net_sockaddr *dst, struct sockaddr *src, + socklen_t len) +{ + int res; + + if (len > sizeof(dst->addr)) + return -1; + + memcpy(&dst->addr, src, len); + + if ((res = update_family_from_addr(dst)) < 0) + return res; + + return res; +} + +int net_addr_toaddr(net_sockaddr *sin, + struct sockaddr *storage, socklen_t *len) +{ + if (*len < sin->addrlen) { + return -1; + } + + memcpy(storage, &sin->addr, sin->addrlen); + *len = sin->addrlen; + return 0; +} + +int net_recvfrom(int socket, void *buf, size_t len, int flags, + net_sockaddr *sa) +{ + int res; + sa->addrlen = sizeof(sa->addr); + res = recvfrom(socket, buf, len, 0, (struct sockaddr *)&sa->addr, + &sa->addrlen); + + if (res < 0) { + return res; + } + + update_from_socket_addr(socket, sa); + return res; +} + +int net_sendto(int socket, void *buf, size_t len, int flags, + net_sockaddr *sa) +{ + int res; + res = sendto(socket, buf, len, flags, (struct sockaddr *)&sa->addr, + sa->addrlen); + return res; +} + +int net_setnochecksums(int s, int nochecksums) +{ + int res = -1; + net_sockaddr *sa; + int ipver; + +#ifdef SO_NO_CHECK + + net_addr_alloca(&sa); + net_getsockname(s, sa); + ipver = net_addr_getipver(sa); + + if (ipver != 6) { + res = setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); + } else { +/* char buf[256]; */ +/* ast_log(LOG_NOTICE, "Doesn't disable checksums for IPv6 %s\n", */ +/* net_ntostr(buf, sizeof(buf), sa)); */ + } +#endif + return res; +} + --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ include/asterisk/net.h 2005-04-03 19:27:56.000000000 +0200 @@ -0,0 +1,90 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Network functions + * + * Copyright (C) 2005 Mikael Magnusson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASTERISK_NET_H +#define _ASTERISK_NET_H + +#include +#include +#include +#include +#include +#include + +#define NET_ADDRSTRLEN INET6_ADDRSTRLEN + +#define net_addr_alloca(ptr) \ + do { assert(ptr); *ptr = alloca(net_addr_sizeof()); net_addr_clr(*ptr); } while(0); + +typedef struct tag_net_sockaddr net_sockaddr; + +extern const char *net_ntoa(char *buf, int bufsiz, net_sockaddr *ia); +extern const char *net_ntostr(char *buf, int bufsiz, net_sockaddr *ia); +extern const char *net_ntos(char *buf, int bufsize, net_sockaddr *ia); +extern const char *net_ntourl(char *buf, int bufsize, net_sockaddr *ia); +extern int net_aston(const char *cp, const char *serv, net_sockaddr *ia); +extern int net_aton(const char *cp, net_sockaddr *ia); +extern size_t net_addr_sizeof(void); +extern net_sockaddr *net_addr_new(void); +extern int net_addr_delete(net_sockaddr *sa); +extern int net_addr_cmp(net_sockaddr *sa1, net_sockaddr *sa2); +extern int net_addr_ishostnull(net_sockaddr *sa); +extern int net_addr_isportnull(net_sockaddr *sa); +extern int net_addr_cmphost(net_sockaddr *sa1, net_sockaddr *sa2); +extern int net_addr_cmpport(net_sockaddr *sa1, net_sockaddr *sa2); +extern int net_addr_cpyhost(net_sockaddr *dst, net_sockaddr *src); +extern int net_addr_cpyport(net_sockaddr *dst, net_sockaddr *src); +extern int net_addr_cpy(net_sockaddr *dst, net_sockaddr *src); +extern int net_addr_get(net_sockaddr *sa, const char *host); +extern int net_addr_getport(net_sockaddr *sa); +extern int net_addr_setport(net_sockaddr *sa, int port); +extern int net_addr_getfamily(net_sockaddr *sa); +extern int net_addr_setfamily(net_sockaddr *sa, int family); +extern int net_addr_getsocktype(net_sockaddr *sa); +extern int net_addr_setsocktype(net_sockaddr *sa, int socktype); +extern int net_addr_getprotocol(net_sockaddr *sa); +extern int net_addr_setprotocol(net_sockaddr *sa, int protocol); +extern int net_addr_clr(net_sockaddr *sa); +extern int net_addr_clrhost(net_sockaddr *sa); +extern int net_addr_init(net_sockaddr *sa, int family, int socktype, + int protocol); +extern int net_addr_initfromaddr(net_sockaddr *dst, + struct sockaddr *src, socklen_t len); +extern int net_addr_toaddr(net_sockaddr *sin, + struct sockaddr *storage, socklen_t *len); +extern int net_addr_initmask(net_sockaddr *mask, net_sockaddr *sa, + const char *nm); +extern int net_addr_andmask(net_sockaddr *sa, net_sockaddr *mask); +extern int net_addr_checkmask(net_sockaddr *sa, net_sockaddr *addr, + net_sockaddr *mask); +extern int net_addr_getipver(net_sockaddr *sa); +extern int net_socket(net_sockaddr *sa); +extern int net_getsockname(int fd, net_sockaddr *sa); +extern int net_bind(int fd, net_sockaddr *sa); +extern int net_accept(int fd, net_sockaddr *sa); +extern int net_connect(int fd, net_sockaddr *sa); +extern int net_recvfrom(int fd, void *buf, size_t len, int flags, + net_sockaddr *sa); +extern int net_sendto(int fd, void *buf, size_t len, int flags, + net_sockaddr *sa); +extern int net_setnochecksums(int s, int nochecksums); +#endif /* _ASTERISK_NET_H */