diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-01-11 17:08:52 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-01-11 17:08:52 +0000 |
commit | 44a872aadc7c89bf0c1846917ad73036b37db916 (patch) | |
tree | 25280d83230df46e9de3ec9bd94121b35825911c /acl.c | |
parent | 04f9f836ba5b14dc85e65ba958c301be6715ba5e (diff) |
Allow multiple bindaddrs so asterisk uses the same interface for tx as rx
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4756 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'acl.c')
-rwxr-xr-x | acl.c | 117 |
1 files changed, 114 insertions, 3 deletions
@@ -21,6 +21,7 @@ #include <asterisk/acl.h> #include <asterisk/logger.h> #include <asterisk/channel.h> +#include <asterisk/options.h> #include <asterisk/utils.h> #include <asterisk/lock.h> #include <asterisk/srv.h> @@ -42,6 +43,13 @@ AST_MUTEX_DEFINE_STATIC(routeseq_lock); #include <sys/sockio.h> #endif +struct ast_netsock { + ASTOBJ_COMPONENTS(struct ast_netsock); + struct sockaddr_in bindaddr; + int sockfd; + int *ioref; + struct io_context *ioc; +}; struct ast_ha { @@ -222,7 +230,8 @@ int ast_get_ip(struct sockaddr_in *sin, const char *value) } /* iface is the interface (e.g. eth0); address is the return value */ -int ast_lookup_iface(char *iface, struct in_addr *address) { +int ast_lookup_iface(char *iface, struct in_addr *address) +{ int mysock, res = 0; struct my_ifreq ifreq; @@ -254,8 +263,8 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us) ast_log(LOG_WARNING, "Cannot create socket\n"); return -1; } - sin.sin_family = AF_INET; - sin.sin_port = 5060; + sin.sin_family = AF_INET; + sin.sin_port = 5060; sin.sin_addr = *them; if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) { ast_log(LOG_WARNING, "Cannot connect\n"); @@ -272,3 +281,105 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us) *us = sin.sin_addr; return 0; } + +int ast_netsock_sockfd(struct ast_netsock *ns) +{ + if (ns) + return ns->sockfd; + 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) +{ + int netsocket = -1; + int *ioref; + char iabuf[INET_ADDRSTRLEN]; + + struct ast_netsock *ns; + + /* Make a UDP socket */ + netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + + if (netsocket < 0) { + ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); + 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)); + close(netsocket); + return NULL; + } + if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); + + if (setsockopt(netsocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) + ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); + + /* Establish I/O callback for socket read */ + ioref = ast_io_add(ioc, netsocket, callback, AST_IO_IN, data); + if (!ioref) { + ast_log(LOG_WARNING, "Out of memory!\n"); + close(netsocket); + return NULL; + } + + ns = malloc(sizeof(struct ast_netsock)); + if (ns) { + ASTOBJ_INIT(ns); + ns->ioref = ioref; + ns->ioc = ioc; + ns->sockfd = netsocket; + memcpy(&ns->bindaddr, bindaddr, sizeof(ns->bindaddr)); + ASTOBJ_CONTAINER_LINK(list, ns); + } else { + ast_log(LOG_WARNING, "Out of memory!\n"); + ast_io_remove(ioc, ioref); + close(netsocket); + } + return ns; +} + +static void ast_netsock_destroy(struct ast_netsock *netsock) +{ + ast_io_remove(netsock->ioc, netsock->ioref); + close(netsock->sockfd); + free(netsock); +} + +int ast_netsock_init(struct ast_netsock_list *list) +{ + memset(list, 0, sizeof(struct ast_netsock_list)); + ASTOBJ_CONTAINER_INIT(list); + return 0; +} + +int ast_netsock_release(struct ast_netsock_list *list) +{ + ASTOBJ_CONTAINER_DESTROYALL(list, ast_netsock_destroy); + ASTOBJ_CONTAINER_DESTROY(list); + return 0; +} + +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; + char *tmp; + char *port; + int portno; + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(defaultport); + tmp = ast_strdupa(bindinfo); + if (tmp) { + port = strchr(tmp, ':'); + if (port) { + *port = '\0'; + port++; + if ((portno = atoi(port)) > 0) + sin.sin_port = htons(portno); + } + return ast_netsock_bindaddr(list, ioc, &sin, tos, callback, data); + } else + ast_log(LOG_WARNING, "Out of memory!\n"); + return NULL; +} |