mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 04:11:08 +00:00
Allow multiple bindaddrs so asterisk uses the same interface for tx as rx
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4756 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
117
acl.c
117
acl.c
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user