From 4dd44282048116871c708d8079e0fc3af137b311 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Tue, 19 Jul 2005 23:17:02 +0000 Subject: split acl and netsock code into separate files, in preparation for new netsock implementation various minor cleanups git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6165 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- Makefile | 3 +- acl.c | 143 +------------------------------ channels/chan_iax2.c | 22 +++-- include/asterisk/acl.h | 28 +------ include/asterisk/netsock.h | 57 +++++++++++++ include/asterisk/utils.h | 12 ++- netsock.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 292 insertions(+), 178 deletions(-) create mode 100755 include/asterisk/netsock.h create mode 100755 netsock.c diff --git a/Makefile b/Makefile index 5879768ee..2efea26d0 100755 --- a/Makefile +++ b/Makefile @@ -275,7 +275,8 @@ OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \ cdr.o tdd.o acl.o rtp.o manager.o asterisk.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 dnsmgr.o devicestate.o + utils.o config_old.o plc.o jitterbuf.o dnsmgr.o devicestate.o \ + netsock.o ifeq (${OSARCH},Darwin) OBJS+=poll.o dlfcn.o ASTLINK=-Wl,-dynamic diff --git a/acl.c b/acl.c index cf695474f..f1da0f7bb 100755 --- a/acl.c +++ b/acl.c @@ -3,9 +3,9 @@ * * Various sorts of access control * - * Copyright (C) 1999, Mark Spencer + * Copyright (C) 1999-2005, Digium, Inc. * - * Mark Spencer + * Mark Spencer * * This program is free software, distributed under the terms of * the GNU General Public License @@ -52,16 +52,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") AST_MUTEX_DEFINE_STATIC(routeseq_lock); #endif -struct ast_netsock { - ASTOBJ_COMPONENTS(struct ast_netsock); - struct sockaddr_in bindaddr; - int sockfd; - int *ioref; - struct io_context *ioc; - void *data; -}; - - struct ast_ha { /* Host access rule */ struct in_addr netaddr; @@ -294,135 +284,6 @@ int ast_ouraddrfor(struct in_addr *them, struct in_addr *us) 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); - - ns = malloc(sizeof(struct ast_netsock)); - if (ns) { - /* Establish I/O callback for socket read */ - ioref = ast_io_add(ioc, netsocket, callback, AST_IO_IN, ns); - if (!ioref) { - ast_log(LOG_WARNING, "Out of memory!\n"); - close(netsocket); - free(ns); - return NULL; - } - ASTOBJ_INIT(ns); - ns->ioref = ioref; - ns->ioc = ioc; - ns->sockfd = netsocket; - ns->data = data; - memcpy(&ns->bindaddr, bindaddr, sizeof(ns->bindaddr)); - ASTOBJ_CONTAINER_LINK(list, ns); - } else { - ast_log(LOG_WARNING, "Out of memory!\n"); - 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_find(struct ast_netsock_list *list, - struct sockaddr_in *sa) -{ - struct ast_netsock *sock = NULL; - - ASTOBJ_CONTAINER_TRAVERSE(list, !sock, { - ASTOBJ_RDLOCK(iterator); - if (!inaddrcmp(&iterator->bindaddr, sa)) - sock = iterator; - ASTOBJ_UNLOCK(iterator); - }); - - return sock; -} - - -const struct sockaddr_in *ast_netsock_boundaddr(struct ast_netsock *ns) -{ - return &(ns->bindaddr); -} - -void *ast_netsock_data(struct ast_netsock *ns) -{ - return ns->data; -} - -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); - } - inet_aton(tmp, &sin.sin_addr); - 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) { char ourhost[MAXHOSTNAMELEN]=""; diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 22a6e03c1..2062b9f38 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -43,6 +43,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/aes.h" #include "asterisk/dnsmgr.h" #include "asterisk/devicestate.h" +#include "asterisk/netsock.h" #include #include @@ -156,7 +157,7 @@ static int expirey = IAX_DEFAULT_REG_EXPIRE; static int timingfd = -1; /* Timing file descriptor */ -static struct ast_netsock_list netsock; +static struct ast_netsock_list *netsock; static int defaultsockfd = -1; static int usecnt; @@ -7864,7 +7865,7 @@ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr) if (res == 0) { /* ip address valid. */ sin.sin_port = htons(port); - sock = ast_netsock_find(&netsock, &sin); + sock = ast_netsock_find(netsock, &sin); if (sock) { sockfd = ast_netsock_sockfd(sock); nonlocal = 0; @@ -8423,7 +8424,7 @@ static int set_config(char *config_file, int reload) if (reload) { ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); } else { - if (!(ns = ast_netsock_bind(&netsock, io, v->value, portno, tos, socket_read, NULL))) { + if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); } else { if (option_verbose > 1) { @@ -9247,7 +9248,7 @@ static int __unload_module(void) pthread_cancel(netthreadid); pthread_join(netthreadid, NULL); } - ast_netsock_release(&netsock); + ast_netsock_release(netsock); for (x=0;xnext) diff --git a/include/asterisk/acl.h b/include/asterisk/acl.h index 3baa45e5c..dc3e3a4c0 100755 --- a/include/asterisk/acl.h +++ b/include/asterisk/acl.h @@ -3,9 +3,9 @@ * * Access Control of various sorts * - * Copyright (C) 1999, Mark Spencer + * Copyright (C) 1999-2005, Digium, Inc. * - * Mark Spencer + * Mark Spencer * * This program is free software, distributed under the terms of * the GNU General Public License @@ -21,7 +21,6 @@ extern "C" { #include #include "asterisk/io.h" -#include "asterisk/astobj.h" #define AST_SENSE_DENY 0 #define AST_SENSE_ALLOW 1 @@ -29,12 +28,6 @@ extern "C" { /* Host based access control */ struct ast_ha; -struct ast_netsock; - -struct ast_netsock_list { - ASTOBJ_CONTAINER_COMPONENTS(struct ast_netsock); - struct io_context *ioc; -}; extern void ast_free_ha(struct ast_ha *ha); extern struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path); @@ -44,25 +37,8 @@ extern int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const c extern int ast_ouraddrfor(struct in_addr *them, struct in_addr *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 int ast_netsock_free(struct ast_netsock_list *list, struct ast_netsock *netsock); -extern int ast_netsock_release(struct ast_netsock_list *list); -extern struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, - struct sockaddr_in *sa); -extern int ast_netsock_sockfd(struct ast_netsock *ns); -extern const struct sockaddr_in *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); -/*! Compares the source address and port of two sockaddr_in */ -static inline int inaddrcmp(struct sockaddr_in *sin1, struct sockaddr_in *sin2) -{ - return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr ) - || (sin1->sin_port != sin2->sin_port)); -} - #if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/include/asterisk/netsock.h b/include/asterisk/netsock.h new file mode 100755 index 000000000..2215e3d67 --- /dev/null +++ b/include/asterisk/netsock.h @@ -0,0 +1,57 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Network socket handling + * + * Copyright (C) 2004-2005, Digium, Inc. + * + * Mark Spencer + * Kevin P. Fleming + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#ifndef _ASTERISK_NETSOCK_H +#define _ASTERISK_NETSOCK_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include "asterisk/io.h" +#include "asterisk/astobj.h" + +struct ast_netsock; + +struct ast_netsock_list; + +struct ast_netsock_list *ast_netsock_list_alloc(void); + +int ast_netsock_init(struct ast_netsock_list *list); + +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 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 ast_netsock_free(struct ast_netsock_list *list, struct ast_netsock *netsock); + +int ast_netsock_release(struct ast_netsock_list *list); + +struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, + struct sockaddr_in *sa); + +int ast_netsock_sockfd(const struct ast_netsock *ns); + +const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns); + +void *ast_netsock_data(const struct ast_netsock *ns); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index 246da5e76..1d398fa10 100755 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -136,14 +136,22 @@ extern int ast_base64decode(unsigned char *dst, char *src, int max); extern int test_for_thread_safety(void); extern const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia); -extern int ast_utils_init(void); -extern int ast_wait_for_input(int fd, int ms); #ifdef inet_ntoa #undef inet_ntoa #endif #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__ +extern int ast_utils_init(void); +extern int ast_wait_for_input(int fd, int ms); + +/*! Compares the source address and port of two sockaddr_in */ +static inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2) +{ + return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) + || (sin1->sin_port != sin2->sin_port)); +} + #define AST_STACKSIZE 256 * 1024 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0) extern int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize); diff --git a/netsock.c b/netsock.c new file mode 100755 index 000000000..0219427cf --- /dev/null +++ b/netsock.c @@ -0,0 +1,205 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Network socket handling + * + * Copyright (C) 2004-2005, Digium, Inc. + * + * Mark Spencer + * Kevin P. Fleming + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) +#include +#include +#endif + +#if defined (SOLARIS) +#include +#endif + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/netsock.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" + +struct ast_netsock { + ASTOBJ_COMPONENTS(struct ast_netsock); + struct sockaddr_in bindaddr; + int sockfd; + int *ioref; + struct io_context *ioc; + void *data; +}; + +struct ast_netsock_list { + ASTOBJ_CONTAINER_COMPONENTS(struct ast_netsock); + struct io_context *ioc; +}; + +static void ast_netsock_destroy(struct ast_netsock *netsock) +{ + ast_io_remove(netsock->ioc, netsock->ioref); + close(netsock->sockfd); + free(netsock); +} + +struct ast_netsock_list *ast_netsock_list_alloc(void) +{ + struct ast_netsock_list *res; + + res = calloc(1, sizeof(*res)); + + return res; +} + +int ast_netsock_init(struct ast_netsock_list *list) +{ + memset(list, 0, sizeof(*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_find(struct ast_netsock_list *list, + struct sockaddr_in *sa) +{ + struct ast_netsock *sock = NULL; + + ASTOBJ_CONTAINER_TRAVERSE(list, !sock, { + ASTOBJ_RDLOCK(iterator); + if (!inaddrcmp(&iterator->bindaddr, sa)) + sock = iterator; + ASTOBJ_UNLOCK(iterator); + }); + + return sock; +} + +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); + + ns = malloc(sizeof(struct ast_netsock)); + if (ns) { + /* Establish I/O callback for socket read */ + ioref = ast_io_add(ioc, netsocket, callback, AST_IO_IN, ns); + if (!ioref) { + ast_log(LOG_WARNING, "Out of memory!\n"); + close(netsocket); + free(ns); + return NULL; + } + ASTOBJ_INIT(ns); + ns->ioref = ioref; + ns->ioc = ioc; + ns->sockfd = netsocket; + ns->data = data; + memcpy(&ns->bindaddr, bindaddr, sizeof(ns->bindaddr)); + ASTOBJ_CONTAINER_LINK(list, ns); + } else { + ast_log(LOG_WARNING, "Out of memory!\n"); + close(netsocket); + } + + return ns; +} + +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 *host; + 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) { + ast_log(LOG_WARNING, "Out of memory!\n"); + return NULL; + } + + host = strsep(&tmp, ":"); + port = tmp; + + if (port && ((portno = atoi(port)) > 0)) + sin.sin_port = htons(portno); + + inet_aton(host, &sin.sin_addr); + + return ast_netsock_bindaddr(list, ioc, &sin, tos, callback, data); +} + +int ast_netsock_sockfd(const struct ast_netsock *ns) +{ + return ns ? ns-> sockfd : -1; +} + +const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns) +{ + return &(ns->bindaddr); +} + +void *ast_netsock_data(const struct ast_netsock *ns) +{ + return ns->data; +} -- cgit v1.2.3