[asterisk-commits] simon.perreault: branch group/v6 r82317 - in /team/group/v6/trunk: ./ channel...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Sep 13 10:09:11 CDT 2007
Author: simon.perreault
Date: Thu Sep 13 10:09:11 2007
New Revision: 82317
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82317
Log:
Applying IPv6 patchset to trunk-tracking branch.
Modified:
team/group/v6/trunk/channels/chan_mgcp.c
team/group/v6/trunk/channels/chan_sip.c
team/group/v6/trunk/channels/chan_skinny.c
team/group/v6/trunk/configs/sip.conf.sample
team/group/v6/trunk/configure
team/group/v6/trunk/configure.ac
team/group/v6/trunk/include/asterisk/acl.h
team/group/v6/trunk/include/asterisk/astobj.h
team/group/v6/trunk/include/asterisk/autoconfig.h.in
team/group/v6/trunk/include/asterisk/config.h
team/group/v6/trunk/include/asterisk/netsock.h
team/group/v6/trunk/include/asterisk/rtp.h
team/group/v6/trunk/include/asterisk/udptl.h
team/group/v6/trunk/main/acl.c
team/group/v6/trunk/main/config.c
team/group/v6/trunk/main/netsock.c
team/group/v6/trunk/main/rtp.c
team/group/v6/trunk/main/udptl.c
Modified: team/group/v6/trunk/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/channels/chan_mgcp.c?view=diff&rev=82317&r1=82316&r2=82317
==============================================================================
--- team/group/v6/trunk/channels/chan_mgcp.c (original)
+++ team/group/v6/trunk/channels/chan_mgcp.c Thu Sep 13 10:09:11 2007
@@ -1856,7 +1856,7 @@
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
sin.sin_port = htons(portno);
- ast_rtp_set_peer(sub->rtp, &sin);
+ ast_rtp_set_peer(sub->rtp, (struct sockaddr*)&sin, sin.sin_addr.s_addr ? sizeof(sin) : 0);
#if 0
printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
#endif
@@ -2031,6 +2031,7 @@
int codec;
char costr[80];
struct sockaddr_in sin;
+ socklen_t dummy;
char v[256];
char s[256];
char o[256];
@@ -2048,9 +2049,9 @@
ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
return -1;
}
- ast_rtp_get_us(sub->rtp, &sin);
+ ast_rtp_get_us(sub->rtp, (struct sockaddr*)&sin, &dummy);
if (rtp) {
- ast_rtp_get_peer(rtp, &dest);
+ ast_rtp_get_peer(rtp, (struct sockaddr*)&dest, &dummy);
} else {
if (sub->tmpdest.sin_addr.s_addr) {
dest.sin_addr = sub->tmpdest.sin_addr;
@@ -2126,6 +2127,7 @@
int x;
int capability;
struct mgcp_endpoint *p = sub->parent;
+ socklen_t dummy;
capability = p->capability;
if (codecs)
@@ -2133,7 +2135,7 @@
if (ast_strlen_zero(sub->cxident) && rtp) {
/* We don't have a CXident yet, store the destination and
wait a bit */
- ast_rtp_get_peer(rtp, &sub->tmpdest);
+ ast_rtp_get_peer(rtp, (struct sockaddr*)&sub->tmpdest, &dummy);
return 0;
}
snprintf(local, sizeof(local), "p:20");
@@ -2591,7 +2593,7 @@
sub->rtp = NULL;
}
/* Allocate the RTP now */
- sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+ sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, (struct sockaddr*)&bindaddr, bindaddr.sin_addr.s_addr ? sizeof(bindaddr) : 0);
if (sub->rtp && sub->owner)
ast_channel_set_fd(sub->owner, 0, ast_rtp_fd(sub->rtp));
if (sub->rtp)
Modified: team/group/v6/trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/v6/trunk/channels/chan_sip.c?view=diff&rev=82317&r1=82316&r2=82317
==============================================================================
--- team/group/v6/trunk/channels/chan_sip.c (original)
+++ team/group/v6/trunk/channels/chan_sip.c Thu Sep 13 10:09:11 2007
@@ -80,6 +80,14 @@
* \par Hanging up
* The PBX issues a hangup on both incoming and outgoing calls through
* the sip_hangup() function
+ *
+ * \par IPv6 support:
+ * uses the updated netsock library which provides ip version independant
+ * routines for sockets.
+ * currently handles one socket per address family (one v4 socket, one v6 socket)
+ * see more info in README.ipv6
+ * \author Marc Blanchet <marc.blanchet at viagenie.ca>
+ * \author Frederick Lefebvre <frederick.lefebvre at viagenie.ca>
*/
@@ -139,6 +147,7 @@
#include "asterisk/netsock.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
+#include "asterisk/netsock.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
@@ -389,8 +398,10 @@
* a pointer and should *not* be de-allocated.
*/
struct sip_proxy {
- char name[MAXHOSTNAMELEN]; /*!< DNS name of domain/host or IP */
- struct sockaddr_in ip; /*!< Currently used IP address and port */
+ char name[NI_MAXHOST]; /*!< DNS name of domain/host or IP */
+ char serv[NI_MAXSERV]; /*!< Name of service or port number */
+ struct sockaddr_storage ip; /*!< Currently used IP address and port */
+ socklen_t ip_len;
time_t last_dnsupdate; /*!< When this was resolved */
int force; /*!< If it's an outbound proxy, Force use of this outbound proxy for all outbound requests */
/* Room for a SRV record chain based on the name */
@@ -655,7 +666,6 @@
static struct sched_context *sched; /*!< The scheduling context */
static struct io_context *io; /*!< The IO context */
-static int *sipsock_read_id; /*!< ID of IO entry for sipsock FD */
#define DEC_CALL_LIMIT 0
#define INC_CALL_LIMIT 1
@@ -1066,8 +1076,9 @@
int maxcallbitrate; /*!< Maximum Call Bitrate for Video Calls */
struct sip_proxy *outboundproxy; /*!< Outbound proxy for this dialog */
struct t38properties t38; /*!< T38 settings */
- struct sockaddr_in udptlredirip; /*!< Where our T.38 UDPTL should be going if not to us */
- struct ast_udptl *udptl; /*!< T.38 UDPTL session */
+ struct sockaddr_storage udptlredirip; /*!< Where our T.38 UDPTL should be going if not to us */
+ socklen_t udptlredirip_len;
+ struct ast_viudptl *udptl; /*!< T.38 UDPTL session */
int callingpres; /*!< Calling presentation */
int authtries; /*!< Times we've tried to authenticate */
int expiry; /*!< How long we take to expire */
@@ -1075,15 +1086,21 @@
char tag[11]; /*!< Our tag for this session */
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 */
- struct sockaddr_in tredirip; /*!< Where our Text RTP should be going if not to us */
+ struct sockaddr_storage sa; /*!< Our peer */
+ socklen_t sa_len;
+ struct sockaddr_storage redirip; /*!< Where our RTP should be going if not to us */
+ socklen_t redirip_len;
+ struct sockaddr_storage vredirip; /*!< Where our Video RTP should be going if not to us */
+ socklen_t vredirip_len;
+ struct sockaddr_storage tredirip; /*!< Where our Text RTP should be going if not to us */
+ socklen_t tredirip_len;
time_t lastrtprx; /*!< Last RTP received */
time_t lastrtptx; /*!< Last RTP sent */
int rtptimeout; /*!< RTP timeout time */
- struct sockaddr_in recv; /*!< Received as */
- struct sockaddr_in ourip; /*!< Our IP (as seen from the outside) */
+ struct sockaddr_storage recv; /*!< Received as */
+ socklen_t recv_len;
+ struct sockaddr_storage ourip; /*!< Our IP */
+ socklen_t ourip_len;
struct ast_channel *owner; /*!< Who owns us (if we have an owner) */
struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */
int route_persistant; /*!< Is this the "real" route? */
@@ -1123,6 +1140,7 @@
before strolling to the Grokyzpå
(A bit unsure of this, please correct if
you know more) */
+ struct ast_vinetsock *netsock;
};
/*! Max entires in the history list for a sip_pvt */
@@ -1300,7 +1318,8 @@
ast_group_t pickupgroup; /*!< Pickup group */
struct sip_proxy *outboundproxy; /*!< Outbound proxy for this peer */
struct ast_dnsmgr_entry *dnsmgr;/*!< DNS refresh manager for peer */
- struct sockaddr_in addr; /*!< IP address of peer */
+ struct sockaddr_storage addr; /*!< IP address of peer */
+ socklen_t addr_len;
int maxcallbitrate; /*!< Maximum Bitrate for a video call */
/* Qualification */
@@ -1309,7 +1328,8 @@
int lastms; /*!< How long last response took (in ms), or -1 for no response */
int maxms; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
struct timeval ps; /*!< Time for sending SIP OPTION in sip_pke_peer() */
- struct sockaddr_in defaddr; /*!< Default IP address, used until registration */
+ struct sockaddr_storage defaddr;/*!< Default IP address, used until registration */
+ socklen_t defaddr_len;
struct ast_ha *ha; /*!< Access control list */
struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
struct sip_pvt *mwipvt; /*!< Subscription for MWI */
@@ -1360,7 +1380,8 @@
struct timeval regtime; /*!< Last successful registration time */
int callid_valid; /*!< 0 means we haven't chosen callid for this registry yet. */
unsigned int ocseq; /*!< Sequence number we got to for REGISTERs for this registry */
- struct sockaddr_in us; /*!< Who the server thinks we are */
+ struct sockaddr_storage us; /*!< Who the server thinks we are */
+ socklen_t us_len;
int noncecount; /*!< Nonce-count */
char lastmsg[256]; /*!< Last Message sent/received */
};
@@ -1396,22 +1417,7 @@
/* --- Sockets and networking --------------*/
-/*! \brief Main socket for SIP communication.
- * sipsock is shared between the manager thread (which handles reload
- * requests), the io handler (sipsock_read()) and the user routines that
- * issue writes (using __sip_xmit()).
- * The socket is -1 only when opening fails (this is a permanent condition),
- * or when we are handling a reload() that changes its address (this is
- * a transient situation during which we might have a harmless race, see
- * below). Because the conditions for the race to be possible are extremely
- * rare, we don't want to pay the cost of locking on every I/O.
- * Rather, we remember that when the race may occur, communication is
- * bound to fail anyways, so we just live with this event and let
- * the protocol handle this above us.
- */
-static int sipsock = -1;
-
-static struct sockaddr_in bindaddr; /*!< The address we bind to */
+static struct ast_vinetsock_list *netsocks = NULL;
/*! \brief our (internal) default address/port to put in SIP/SDP messages
* internip is initialized picking a suitable address from one of the
@@ -1419,7 +1425,8 @@
* default address/port in SIP messages, and as the default address
* (but not port) in SDP messages.
*/
-static struct sockaddr_in internip;
+static struct sockaddr_storage internip;
+static socklen_t internip_len = 0;
/*! \brief our external IP address/port for SIP sessions.
* externip.sin_addr is only set when we know we might be behind
@@ -1439,12 +1446,14 @@
* Other variables (externhost, externexpire, externrefresh) are used
* to support the above functions.
*/
-static struct sockaddr_in externip; /*!< External IP address if we are behind NAT */
-
-static char externhost[MAXHOSTNAMELEN]; /*!< External host name */
+static struct sockaddr_storage externip; /*!< External IP address if we are behind NAT */
+static socklen_t externip_len = 0;
+
+static char externhost[NI_MAXHOST]; /*!< External host name */
static time_t externexpire; /*!< Expiration counter for re-resolving external host name in dynamic DNS */
static int externrefresh = 10;
-static struct sockaddr_in stunaddr; /*!< stun server address */
+static struct sockaddr_storage stunaddr; /*!< stun server address */
+static socklen_t stunaddr_len;
/*! \brief List of local networks
* We store "localnet" addresses from the config file into an access list,
@@ -1454,7 +1463,9 @@
*/
static struct ast_ha *localaddr; /*!< List of local networks, on the same side of NAT as this Asterisk */
-static struct sockaddr_in debugaddr;
+static int defport = STANDARD_SIP_PORT;
+static struct sockaddr_storage debugaddr;
+static socklen_t debugaddr_len;
static struct ast_config *notify_types; /*!< The list of manual NOTIFY types we know how to send */
@@ -1485,7 +1496,7 @@
static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
static int retrans_pkt(void *data);
static int transmit_sip_request(struct sip_pvt *p, struct sip_request *req);
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg);
+static int transmit_response_using_temp(ast_string_field callid, struct sockaddr *sa, socklen_t sa_len, struct ast_vinetsock *ns, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg);
static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req);
static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_request *req);
static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req);
@@ -1513,8 +1524,12 @@
static int sip_send_mwi_to_peer(struct sip_peer *peer, const struct ast_event *event, int cache_only);
/*--- Dialog management */
-static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
+static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr *sa,
+ socklen_t sa_len, struct ast_vinetsock *ns,
int useglobal_nat, const int intended_method);
+static struct sip_pvt *sip_alloc_fromhost(ast_string_field callid, const char *hoststr,
+ struct sip_peer *peer_param,
+ int useglobal_nat, const int intended_method);
static int __sip_autodestruct(void *data);
static void sip_scheddestroy(struct sip_pvt *p, int ms);
static void sip_cancel_destroy(struct sip_pvt *p);
@@ -1527,12 +1542,14 @@
static int update_call_counter(struct sip_pvt *fup, int event);
static int hangup_sip2cause(int cause);
static const char *hangup_cause2sip(int cause);
-static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *sin, const int intended_method);
+static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr *sa,
+ socklen_t sa_len, struct ast_vinetsock* ns,
+ const int intended_method);
static void free_old_route(struct sip_route *route);
static void list_route(struct sip_route *route);
static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards);
-static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr_in *sin,
- struct sip_request *req, char *uri);
+static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr *sa,
+ socklen_t sa_len, struct sip_request *req, char *uri);
static struct sip_pvt *get_sip_pvt_byid_locked(const char *callid, const char *totag, const char *fromtag);
static void check_pendings(struct sip_pvt *p);
static void *sip_park_thread(void *stuff);
@@ -1554,6 +1571,8 @@
static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p);
static void do_setnat(struct sip_pvt *p, int natflags);
static void stop_media_flows(struct sip_pvt *p);
+static const char *ast_sip_sdp_sa2addrtype(struct sockaddr* sa);
+static int ast_sip_sdp_addrtype2af(const char* addrtype);
/*--- Authentication stuff */
static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len);
@@ -1563,8 +1582,8 @@
char *uri, enum xmittype reliable, int ignore);
static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_request *req,
int sipmethod, char *uri, enum xmittype reliable,
- struct sockaddr_in *sin, struct sip_peer **authpeer);
-static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin);
+ struct sockaddr *sa, socklen_t sa_len, struct sip_peer **authpeer);
+static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr *sa, socklen_t sa_len);
/*--- Domain handling */
static int check_sip_domain(const char *domain, char *context, size_t len); /* Check if domain is one of our local domains */
@@ -1582,7 +1601,7 @@
static int expire_register(void *data);
static void *do_monitor(void *data);
static int restart_monitor(void);
-static int sip_addrcmp(char *name, struct sockaddr_in *sin); /* Support for peer matching */
+static int sip_addrcmp(char *name, struct sockaddr *sin, socklen_t *sinlen); /* Support for peer matching */
static int sip_refer_allocate(struct sip_pvt *p);
static void ast_quiet_chan(struct ast_channel *chan);
static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
@@ -1649,7 +1668,8 @@
a SIP dialog
*/
static void sip_dump_history(struct sip_pvt *dialog); /* Dump history to LOG_DEBUG at end of dialog, before destroying data */
-static inline int sip_debug_test_addr(const struct sockaddr_in *addr);
+ static inline int sip_debug_test_addr(const struct sockaddr *addr,
+ socklen_t addrlen);
static inline int sip_debug_test_pvt(struct sip_pvt *p);
static void append_history_full(struct sip_pvt *p, const char *fmt, ...);
static void sip_dump_history(struct sip_pvt *dialog);
@@ -1665,7 +1685,7 @@
static void set_peer_defaults(struct sip_peer *peer);
static struct sip_peer *temp_peer(const char *name);
static void register_peer_exten(struct sip_peer *peer, int onoff);
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime);
+static struct sip_peer *find_peer(const char *peer, struct sockaddr *sa, socklen_t sa_len, int realtime);
static struct sip_user *find_user(const char *name, int realtime);
static int sip_poke_peer_s(void *data);
static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
@@ -1675,16 +1695,19 @@
static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
/* Realtime device support */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
+static void realtime_update_peer(const char *peername, struct sockaddr *sin,
+ socklen_t sinlen, const char *username, const char *fullcontact,
+ int expirey);
static struct sip_user *realtime_user(const char *username);
static void update_peer(struct sip_peer *p, int expiry);
static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config);
static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername);
-static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
+static struct sip_peer *realtime_peer(const char *peername, struct sockaddr *sa, socklen_t sa_len);
static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
/*--- Internal UA client handling (outbound registrations) */
-static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us);
+static int ast_sip_ouraddrfor(struct sockaddr *them, socklen_t them_len,
+ struct sockaddr *us, socklen_t *us_len);
static void sip_registry_destroy(struct sip_registry *reg);
static int sip_register(char *value, int lineno);
static const char *regstate2str(enum sipregistrystate regstate) attribute_const;
@@ -1715,7 +1738,7 @@
static int get_also_info(struct sip_pvt *p, struct sip_request *oreq);
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req);
static int set_address_from_contact(struct sip_pvt *pvt);
-static void check_via(struct sip_pvt *p, struct sip_request *req);
+ static void check_via(struct sip_pvt *p, struct sip_request *req, int af);
static char *get_calleridname(const char *input, char *output, size_t outputsize);
static int get_rpid_num(const char *input, char *output, int maxlen);
static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq);
@@ -1730,13 +1753,11 @@
static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod);
static int init_resp(struct sip_request *resp, const char *msg);
static int respprep(struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req);
-static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
+static const struct sockaddr *sip_real_dst(const struct sip_pvt *p, socklen_t *sa_len);
static void build_via(struct sip_pvt *p);
-static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer);
-static int create_addr(struct sip_pvt *dialog, const char *opeer);
static char *generate_random_string(char *buf, size_t size);
static void build_callid_pvt(struct sip_pvt *pvt);
-static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
+static void build_callid_registry(struct sip_registry *reg, struct sockaddr_storage* ourip, socklen_t ourip_len, const char *fromdomain);
static void make_our_tag(char *tagbuf, size_t len);
static int add_header(struct sip_request *req, const char *var, const char *value);
static int add_header_contentLength(struct sip_request *req, int len);
@@ -1754,18 +1775,18 @@
static void build_rpid(struct sip_pvt *p);
/*------Request handling functions */
-static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock);
-static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock);
+static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct sockaddr *sa, socklen_t sa_len, int *recount, int *nounlock);
+static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr *sa, socklen_t sa_len, int *recount, char *e, int *nounlock);
static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, int *nounlock);
-static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e);
-static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
+static int handle_request_bye(struct sip_pvt *p, struct sip_request *req, struct sockaddr* sa, socklen_t sa_len);
+static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct sockaddr *sa, socklen_t sa_len, char *e);
+static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req, struct sockaddr *sa, socklen_t sa_len);
static int handle_request_message(struct sip_pvt *p, struct sip_request *req);
-static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e);
+static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct sockaddr *sa, socklen_t sa_len, int seqno, char *e);
static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
static int handle_request_options(struct sip_pvt *p, struct sip_request *req);
-static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin);
-static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e);
+static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr *sa, socklen_t sa_len);
+static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, struct sockaddr *sa, socklen_t sal_len, int seqno, char *e);
static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno);
/*------Response handling functions */
@@ -1785,8 +1806,8 @@
/*------ T38 Support --------- */
static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_pvt *pvt, int reinvite);
static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
-static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
-static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
+static struct ast_viudptl *sip_get_viudptl_peer(struct ast_channel *chan);
+static int sip_set_viudptl_peer(struct ast_channel *chan, struct ast_viudptl *udptl);
/*! \brief Definition of this channel for PBX channel registration */
static const struct ast_channel_tech sip_tech = {
@@ -1904,10 +1925,10 @@
}
/*! \brief Interface structure with callbacks used to connect to UDPTL module*/
-static struct ast_udptl_protocol sip_udptl = {
+static struct ast_viudptl_protocol sip_udptl = {
type: "SIP",
- get_udptl_info: sip_get_udptl_peer,
- set_udptl_peer: sip_set_udptl_peer,
+ get_udptl_info: sip_get_viudptl_peer,
+ set_udptl_peer: sip_set_viudptl_peer,
};
/*! \brief Append to SIP dialog history
@@ -1950,16 +1971,16 @@
/*! Resolve DNS srv name or host name in a sip_proxy structure */
static int proxy_update(struct sip_proxy *proxy)
{
- /* if it's actually an IP address and not a name,
- there's no need for a managed lookup */
- if (!inet_aton(proxy->name, &proxy->ip.sin_addr)) {
- /* Ok, not an IP address, then let's check if it's a domain or host */
- /* XXX Todo - if we have proxy port, don't do SRV */
- if (ast_get_ip_or_srv(&proxy->ip, proxy->name, global_srvlookup ? "_sip._udp" : NULL) < 0) {
- ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
- return FALSE;
- }
- }
+ int port;
+
+ /* XXX Todo - if we have proxy port, don't do SRV */
+ if (ast_viget_ip_or_srv((struct sockaddr*)&proxy->ip, &proxy->ip_len,
+ proxy->name, global_srvlookup ? "_sip._udp" : NULL) < 0) {
+ ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
+ return FALSE;
+ }
+ port = ast_vinetsock_str2port( proxy->serv );
+ ast_vinetsock_sa_setport( (struct sockaddr*) &proxy->ip, port ? port : STANDARD_SIP_PORT );
proxy->last_dnsupdate = time(NULL);
return TRUE;
}
@@ -1973,7 +1994,9 @@
return NULL;
proxy->force = force;
ast_copy_string(proxy->name, name, sizeof(proxy->name));
- proxy->ip.sin_port = htons((!ast_strlen_zero(port) ? atoi(port) : STANDARD_SIP_PORT));
+ ast_vinetsock_sa_setport( (struct sockaddr*) &proxy->ip,
+ !ast_strlen_zero(port) ? atoi(port) : STANDARD_SIP_PORT
+ );
proxy_update(proxy);
return proxy;
}
@@ -2072,26 +2095,32 @@
}
/*! \brief See if we pass debug IP filter */
-static inline int sip_debug_test_addr(const struct sockaddr_in *addr)
+static inline int sip_debug_test_addr(const struct sockaddr *addr, socklen_t addrlen)
{
if (!sipdebug)
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_len) {
+ if (((ast_vinetsock_sa_getport((struct sockaddr*)&debugaddr, debugaddr_len) != 0)
+ && ast_vinetsock_sacmp_port((struct sockaddr*)&debugaddr, debugaddr_len, addr, addrlen))
+ || ast_vinetsock_sacmp((struct sockaddr*)&debugaddr, debugaddr_len, addr, addrlen,1))
return 0;
}
return 1;
}
/*! \brief The real destination address for a write */
-static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p)
+static const struct sockaddr *sip_real_dst(const struct sip_pvt *p, socklen_t *sa_len)
{
if (p->outboundproxy)
- return &p->outboundproxy->ip;
-
- return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
+ return (struct sockaddr*)&p->outboundproxy->ip;
+
+ if (ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE) {
+ *sa_len = p->recv_len;
+ return (struct sockaddr*)&p->recv;
+ } else {
+ *sa_len = p->sa_len;
+ return (struct sockaddr*)&p->sa;
+ }
}
/*! \brief Display SIP nat mode */
@@ -2103,17 +2132,28 @@
/*! \brief Test PVT for debugging output */
static inline int sip_debug_test_pvt(struct sip_pvt *p)
{
+ socklen_t sa_len = 0;
if (!sipdebug)
return 0;
- return sip_debug_test_addr(sip_real_dst(p));
+ return sip_debug_test_addr(sip_real_dst(p, &sa_len), sa_len);
}
/*! \brief Transmit SIP message */
static int __sip_xmit(struct sip_pvt *p, char *data, int len)
{
int res;
- const struct sockaddr_in *dst = sip_real_dst(p);
- res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
+ char hostport[NI_MAXHOST];
+ socklen_t dstlen = 0;
+ int sockfd = 0;
+ const struct sockaddr *dst = sip_real_dst(p, &dstlen);
+
+ ast_vinetsock_sa_get_hostport(dst, dstlen, hostport, sizeof(hostport));
+ sockfd = ast_vinetsock_list_getsockfd(netsocks, dst->sa_family);
+ if (!sockfd) {
+ ast_log(LOG_WARNING, "sip_xmit : Tried to transmit a SIP msg to %s but no opened socket\n", hostport);
+ return -1;
+ }
+ res=sendto(sockfd, data, len, 0, dst, dstlen);
if (res == -1) {
switch (errno) {
@@ -2125,7 +2165,7 @@
}
}
if (res != len)
- ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
+ ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s returned %d: %s\n", data, len, hostport, res, strerror(errno));
return res;
}
@@ -2133,13 +2173,16 @@
/*! \brief Build a Via header for a request */
static void build_via(struct sip_pvt *p)
{
+ char hostport[NI_MAXHOST];
+
/* Work around buggy UNIDEN UIP200 firmware */
const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
+ ast_vinetsock_sa_get_hostport((struct sockaddr*)&p->ourip, p->ourip_len, hostport, sizeof(hostport));
+
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
- ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
- ast_inet_ntoa(p->ourip.sin_addr),
- ntohs(p->ourip.sin_port), p->branch, rport);
+ ast_string_field_build(p, via, "SIP/2.0/UDP %s;branch=z9hG4bK%08x%s",
+ hostport, p->branch, rport);
}
/*! \brief NAT fix - decide which IP address to use for Asterisk server?
@@ -2149,52 +2192,50 @@
* externip or can get away with our internal bindaddr
* 'us' is always overwritten.
*/
-static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us)
-{
- struct sockaddr_in theirs;
- /* Set want_remap to non-zero if we want to remap 'us' to an externally
- * reachable IP address and port. This is done if:
- * 1. we have a localaddr list (containing 'internal' addresses marked
- * as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
- * and AST_SENSE_ALLOW on 'external' ones);
- * 2. either stunaddr or externip is set, so we know what to use as the
- * externally visible address;
- * 3. the remote address, 'them', is external;
- * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
- * when passed to ast_apply_ha() so it does need to be remapped.
- * This fourth condition is checked later.
- */
- int want_remap = localaddr &&
- (externip.sin_addr.s_addr || stunaddr.sin_addr.s_addr) &&
- ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
-
- *us = internip; /* starting guess for the internal address */
- /* now ask the system what would it use to talk to 'them' */
- ast_ouraddrfor(them, &us->sin_addr);
- theirs.sin_addr = *them;
-
- if (want_remap &&
- (!global_matchexterniplocally || !ast_apply_ha(localaddr, us)) ) {
- /* if we used externhost or stun, see if it is time to refresh the info */
+static enum sip_result ast_sip_ouraddrfor(struct sockaddr *them, socklen_t them_len, struct sockaddr *us, socklen_t *us_len)
+{
+ struct ast_vinetsock* ns = NULL;
+ int portno = 0;
+ char iabuf[NI_MAXHOST];
+ char sbuf[NI_MAXSERV];
+
+ /* Sanity check */
+ if (!them || !them_len)
+ return AST_FAILURE;
+
+ /* Get our local information */
+ if(ast_vinetsock_sa_getsrc(them, them_len, us, us_len, SOCK_DGRAM))
+ return AST_FAILURE;
+
+ ns = ast_vinetsock_find_best(netsocks, them, them_len, AF_UNSPEC);
+ portno = ns ? ast_vinetsock_getport(ns) : defport;
+ ast_vinetsock_sa_setport((struct sockaddr*)us, portno);
+ ast_vinetsock_free(ns);
+ ns = NULL;
+
+ /* If we are not on IPv4, we can return here as
+ * NATs are specific to IPv4 */
+ if (!ast_vinetsock_sa_is_ipv4(them))
+ return AST_SUCCESS;
+
+ if (localaddr && externip_len &&
+ (!ast_vinetsock_sa_is_ipv4(them) ||
+ ast_apply_ha(localaddr, (struct sockaddr_in*)them)) &&
+ (!ast_vinetsock_sa_is_ipv4(us) || !global_matchexterniplocally ||
+ !ast_apply_ha(localaddr, (struct sockaddr_in*)us))) {
if (externexpire && time(NULL) >= externexpire) {
- if (stunaddr.sin_addr.s_addr) {
- ast_stun_request(sipsock, &stunaddr, NULL, &externip);
- } else {
- if (ast_parse_arg(externhost, PARSE_INADDR, &externip))
- ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
- }
externexpire = time(NULL) + externrefresh;
- }
- if (externip.sin_addr.s_addr)
- *us = externip;
- else
- ast_log(LOG_WARNING, "stun failed\n");
- ast_debug(1, "Target address %s is not local, substituting externip\n",
- ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
- } else if (bindaddr.sin_addr.s_addr) {
- /* no remapping, but we bind to a specific address, so use it. */
- *us = bindaddr;
- }
+ if (ast_vinetsock_sa_fromstr(externhost, sbuf, (struct sockaddr*)&externip, &externip_len, AF_INET, 0))
+ ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
+ }
+ memcpy(us, &externip, sizeof(externip));
+ *us_len = externip_len;
+ if (option_debug) {
+ ast_vinetsock_sa_getaddr(them, them_len, iabuf, sizeof(iabuf));
+ ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", iabuf);
+ }
+ }
+ return AST_SUCCESS;
}
/*! \brief Append to SIP dialog history with arg list */
@@ -2248,6 +2289,7 @@
struct sip_pkt *pkt = data, *prev, *cur = NULL;
int reschedule = DEFAULT_RETRANS;
int xmitres = 0;
+ char hostport[NI_MAXHOST];
/* Lock channel PVT */
sip_pvt_lock(pkt->owner);
@@ -2278,11 +2320,13 @@
}
if (sip_debug_test_pvt(pkt->owner)) {
- const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
- ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
- pkt->retrans, sip_nat_mode(pkt->owner),
- ast_inet_ntoa(dst->sin_addr),
- ntohs(dst->sin_port), pkt->data);
+ socklen_t dstlen = 0;
+ const struct sockaddr *dst = sip_real_dst(pkt->owner, &dstlen);
+
+ ast_vinetsock_sa_get_hostport(dst, dstlen, hostport, sizeof(hostport));
+ ast_verbose("Retransmitting #%d (%s) to %s:\n%s\n---\n",
+ pkt->retrans, sip_nat_mode(pkt->owner),
+ hostport, pkt->data);
}
append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
@@ -2591,15 +2635,17 @@
static int send_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
{
int res;
+ char hostport[NI_MAXHOST];
add_blank(req);
if (sip_debug_test_pvt(p)) {
- const struct sockaddr_in *dst = sip_real_dst(p);
-
- ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
+ socklen_t dstlen = 0;
+ const struct sockaddr *dst = sip_real_dst(p,&dstlen);
+
+ ast_vinetsock_sa_get_hostport(dst, dstlen, hostport, sizeof(hostport));
+ ast_verbose("\n<--- %sTransmitting (%s) to %s --->\n%s\n<------------>\n",
reliable ? "Reliably " : "", sip_nat_mode(p),
- ast_inet_ntoa(dst->sin_addr),
- ntohs(dst->sin_port), req->data);
+ hostport, req->data);
}
if (p->do_history) {
struct sip_request tmp;
@@ -2619,6 +2665,7 @@
static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
{
int res;
+ char hostport[NI_MAXHOST];
/* If we have an outbound proxy, reset peer address
Only do this once.
@@ -2629,10 +2676,13 @@
add_blank(req);
if (sip_debug_test_pvt(p)) {
- if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
- ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data);
- else
- ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data);
+ if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) {
+ ast_vinetsock_sa_get_hostport((struct sockaddr*)&p->recv, p->recv_len, hostport, sizeof(hostport));
+ ast_verbose("%sTransmitting (NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", hostport, req->data);
+ } else {
+ ast_vinetsock_sa_get_hostport((struct sockaddr*)&p->sa, p->sa_len, hostport, sizeof(hostport));
+ ast_verbose("%sTransmitting (no NAT) to %s:\n%s\n---\n", reliable ? "Reliably " : "", hostport, req->data);
+ }
}
if (p->do_history) {
struct sip_request tmp;
@@ -2714,17 +2764,17 @@
* - If a component is not requested, do not split around it.
* This means that if we don't have domain, we cannot split
* name:pass and domain:port.
- * It is safe to call with ret_name, pass, domain, port
+ * It is safe to call with ret_name, pass, domain
* pointing all to the same place.
* Init pointers to empty string so we never get NULL dereferencing.
* Overwrites the string.
* return 0 on success, other values on error.
* \verbatim
- * general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...]
+ * general form we are expecting is sip[s]:username[:password][;parameter]@domain[;...]
* \endverbatim
*/
static int parse_uri(char *uri, char *scheme,
- char **ret_name, char **pass, char **domain, char **port, char **options)
+ char **ret_name, char **pass, char **domain, char **options)
{
char *name = NULL;
int error = 0;
@@ -2732,8 +2782,6 @@
/* init field as required */
if (pass)
*pass = "";
- if (port)
- *port = "";
if (scheme) {
int l = strlen(scheme);
if (!strncasecmp(uri, scheme, l))
@@ -2767,10 +2815,6 @@
dom = strsep(&dom, ";");
name = strsep(&name, ";");
- if (port && (c = strchr(dom, ':'))) { /* Remove :port */
- *c++ = '\0';
- *port = c;
- }
if (pass && (c = strchr(name, ':'))) { /* user:password */
*c++ = '\0';
*pass = c;
@@ -2843,10 +2887,12 @@
that name and store that in the "regserver" field in the sippeers
table to facilitate multi-server setups.
*/
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
-{
- char port[10];
- char ipaddr[INET_ADDRSTRLEN];
+static void realtime_update_peer(const char *peername, struct sockaddr *sa,
+ socklen_t sa_len, const char *username,
+ const char *fullcontact, int expirey)
+{
+ char port[NI_MAXSERV];
+ char ipaddr[NI_MAXHOST];
char regseconds[20];
char *tablename = NULL;
@@ -2861,8 +2907,13 @@
tablename = realtimeregs ? "sipregs" : "sippeers";
snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */
- ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
- snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
+ ast_vinetsock_sa_getaddr(sa, sa_len, ipaddr, sizeof(ipaddr));
+ snprintf(port, sizeof(port), "%d",
+ ast_vinetsock_sa_getport(sa, sa_len));
+
+ if(getnameinfo(sa, sa_len, ipaddr, sizeof(ipaddr), port, sizeof(port),
+ NI_NUMERICHOST|NI_NUMERICSERV))
+ return;
if (ast_strlen_zero(sysname)) /* No system name, disable this */
sysname = NULL;
@@ -2979,7 +3030,9 @@
int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
if (sip_cfg.peer_rtupdate &&
(p->is_realtime || rtcachefriends)) {
[... 8150 lines stripped ...]
More information about the asterisk-commits
mailing list