[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