Asterisk - The Open Source Telephony Project GIT-master-f36a736
netsock.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Kevin P. Fleming <kpfleming@digium.com>
7 * Mark Spencer <markster@digium.com>
8 *
9 * See http://www.asterisk.org for more information about
10 * the Asterisk project. Please do not directly contact
11 * any of the maintainers of this project for assistance;
12 * the project provides a web site, mailing lists and IRC
13 * channels for your use.
14 *
15 * This program is free software, distributed under the terms of
16 * the GNU General Public License Version 2. See the LICENSE file
17 * at the top of the source tree.
18 */
19
20/*! \file
21 *
22 * \brief Network socket handling
23 *
24 * \author Kevin P. Fleming <kpfleming@digium.com>
25 * \author Mark Spencer <markster@digium.com>
26 */
27
28/*** MODULEINFO
29 <support_level>core</support_level>
30 ***/
31
32#include "asterisk.h"
33
34#if !defined (__linux__) && !defined (__GNU__)
35#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__) || defined(__GLIBC__)
36#include <net/if_dl.h>
37#endif
38#endif
39
40#if defined (SOLARIS)
41#include <sys/sockio.h>
42#elif defined(HAVE_GETIFADDRS)
43#include <ifaddrs.h>
44#endif
45
46#include "include/netsock.h"
47#include "asterisk/netsock2.h"
48#include "asterisk/utils.h"
49#include "include/astobj.h"
50
54 int sockfd;
55 int *ioref;
56 struct io_context *ioc;
57 void *data;
58};
59
62 struct io_context *ioc;
63};
64
66{
68 close(netsock->sockfd);
70}
71
73{
74 return ast_calloc(1, sizeof(struct ast_netsock_list));
75}
76
78{
79 memset(list, 0, sizeof(*list));
81
82 return 0;
83}
84
86{
89 ast_free(list);
90
91 return 0;
92}
93
94struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, struct ast_sockaddr *addr)
95{
96 struct ast_netsock *sock = NULL;
97
98 ASTOBJ_CONTAINER_TRAVERSE(list, !sock, {
99 ASTOBJ_RDLOCK(iterator);
100 if (!ast_sockaddr_cmp(&iterator->bindaddr, addr)) {
101 sock = iterator;
102 }
103 ASTOBJ_UNLOCK(iterator);
104 });
105
106 return sock;
107}
108
109struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data)
110{
111 int netsocket = -1;
112 int *ioref;
113
114 struct ast_netsock *ns;
115 const int reuseFlag = 1;
116
117 /* Make a UDP socket */
118 netsocket = socket(ast_sockaddr_is_ipv6(bindaddr) ? AST_AF_INET6 : AST_AF_INET, SOCK_DGRAM, IPPROTO_IP);
119
120 if (netsocket < 0) {
121 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
122 return NULL;
123 }
124 if (setsockopt(netsocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) {
125 ast_log(LOG_WARNING, "Error setting SO_REUSEADDR on sockfd '%d'\n", netsocket);
126 }
129 "Unable to bind to %s: %s\n",
131 strerror(errno));
132 close(netsocket);
133 return NULL;
134 }
135
136 ast_set_qos(netsocket, tos, cos, "IAX2");
137
139
140 if (!(ns = ast_calloc(1, sizeof(*ns)))) {
141 close(netsocket);
142 return NULL;
143 }
144
145 /* Establish I/O callback for socket read */
146 if (!(ioref = ast_io_add(ioc, netsocket, callback, AST_IO_IN, ns))) {
147 close(netsocket);
148 ast_free(ns);
149 return NULL;
150 }
151 ASTOBJ_INIT(ns);
152 ns->ioref = ioref;
153 ns->ioc = ioc;
154 ns->sockfd = netsocket;
155 ns->data = data;
157 ASTOBJ_CONTAINER_LINK(list, ns);
158
159 return ns;
160}
161
162int ast_netsock_set_qos(int sockfd, int tos, int cos, const char *desc)
163{
164 return ast_set_qos(sockfd, tos, cos, desc);
165}
166
167struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data)
168{
169 struct ast_sockaddr addr;
170
171 if (ast_sockaddr_parse(&addr, bindinfo, 0)) {
172
173 if (!ast_sockaddr_port(&addr)) {
174 ast_sockaddr_set_port(&addr, defaultport);
175 }
176
177 return ast_netsock_bindaddr(list, ioc, &addr, tos, cos, callback, data);
178 }
179
180 return NULL;
181}
182
183int ast_netsock_sockfd(const struct ast_netsock *ns)
184{
185 return ns ? ns-> sockfd : -1;
186}
187
188const struct ast_sockaddr *ast_netsock_boundaddr(const struct ast_netsock *ns)
189{
190 return &ns->bindaddr;
191}
192
193void *ast_netsock_data(const struct ast_netsock *ns)
194{
195 return ns->data;
196}
197
199{
201}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
Object Model for Asterisk.
#define ASTOBJ_COMPONENTS(type)
Add ASTOBJ components to a struct (with locking support).
Definition: astobj.h:175
#define ASTOBJ_CONTAINER_DESTROY(container)
Destroy a container.
Definition: astobj.h:767
#define ASTOBJ_CONTAINER_DESTROYALL(container, destructor)
Empty a container.
Definition: astobj.h:455
#define ASTOBJ_CONTAINER_LINK(container, newobj)
Add an object to a container.
Definition: astobj.h:778
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:378
#define ASTOBJ_CONTAINER_INIT(container)
Initialize a container.
Definition: astobj.h:754
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:102
#define ASTOBJ_INIT(object)
Initialize an object.
Definition: astobj.h:266
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:111
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:220
static const char desc[]
Definition: cdr_radius.c:84
unsigned int tos
Definition: chan_iax2.c:355
static struct ast_netsock_list * netsock
Definition: chan_iax2.c:366
unsigned int cos
Definition: chan_iax2.c:356
struct ast_sockaddr bindaddr
Definition: chan_ooh323.c:353
#define LOG_ERROR
#define LOG_WARNING
#define AST_IO_IN
Definition: io.h:34
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition: io.c:162
int(* ast_io_cb)(int *id, int fd, short events, void *cbdata)
Definition: io.h:72
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:245
int errno
Network socket handling.
@ AST_AF_INET6
Definition: netsock2.h:56
@ AST_AF_INET
Definition: netsock2.h:55
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
static void ast_netsock_destroy(struct ast_netsock *netsock)
Definition: netsock.c:65
int ast_netsock_release(struct ast_netsock_list *list)
Definition: netsock.c:85
struct ast_netsock_list * ast_netsock_list_alloc(void)
Definition: netsock.c:72
int ast_netsock_set_qos(int sockfd, int tos, int cos, const char *desc)
Definition: netsock.c:162
struct ast_netsock * ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data)
Definition: netsock.c:167
void ast_netsock_unref(struct ast_netsock *ns)
Definition: netsock.c:198
int ast_netsock_sockfd(const struct ast_netsock *ns)
Definition: netsock.c:183
void * ast_netsock_data(const struct ast_netsock *ns)
Definition: netsock.c:193
struct ast_netsock * ast_netsock_find(struct ast_netsock_list *list, struct ast_sockaddr *addr)
Definition: netsock.c:94
const struct ast_sockaddr * ast_netsock_boundaddr(const struct ast_netsock *ns)
Definition: netsock.c:188
int ast_netsock_init(struct ast_netsock_list *list)
Definition: netsock.c:77
struct ast_netsock * ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data)
Definition: netsock.c:109
Network socket handling.
static int netsocket
Definition: pbx_dundi.c:186
#define NULL
Definition: resample.c:96
ASTOBJ_CONTAINER_COMPONENTS(struct ast_netsock)
struct io_context * ioc
Definition: netsock.c:62
int * ioref
Definition: netsock.c:55
void * data
Definition: netsock.c:57
struct ast_sockaddr bindaddr
Definition: netsock.c:53
struct io_context * ioc
Definition: netsock.c:56
int sockfd
Definition: netsock.c:54
Socket address structure.
Definition: netsock2.h:97
Global IO variables are now in a struct in order to be made threadsafe.
Definition: io.c:71
Utility functions.
void ast_enable_packet_fragmentation(int sock)
Disable PMTU discovery on a socket.
Definition: utils.c:2469