[asterisk-commits] branch mogorman/asterisk-xmpp r21305 - in /team/mogorman/asterisk-xmpp: ./ ch...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Apr 18 20:28:55 MST 2006


Author: markster
Date: Tue Apr 18 22:28:54 2006
New Revision: 21305

URL: http://svn.digium.com/view/asterisk?rev=21305&view=rev
Log:
Get RTP half duplex working with some STUN support

Removed:
    team/mogorman/asterisk-xmpp/res/res_stun.c
    team/mogorman/asterisk-xmpp/res/stun/
Modified:
    team/mogorman/asterisk-xmpp/channels/chan_jingle.c
    team/mogorman/asterisk-xmpp/rtp.c

Modified: team/mogorman/asterisk-xmpp/channels/chan_jingle.c
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/channels/chan_jingle.c?rev=21305&r1=21304&r2=21305&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/channels/chan_jingle.c (original)
+++ team/mogorman/asterisk-xmpp/channels/chan_jingle.c Tue Apr 18 22:28:54 2006
@@ -144,7 +144,6 @@
 
 static int flipflop = 0;
 
-
 struct jingle *find_jingle(char *name)
 {
 	struct jingle *jingle = NULL;
@@ -154,54 +153,6 @@
 	return jingle;
 }
 
-
-static int jingle_queue_frame(struct jingle_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
-{
-	struct ast_channel *other;
-retrylock:		
-	/* Recalculate outbound channel */
-/*	if (isoutbound) {
-		other = p->owner;
-	} else {
-		other = p->chan;
-	}*/
-	/* Set glare detection */
-/*	p->glaredetect = 1; */
-/*	if (p->cancelqueue) {
-		// We had a glare on the hangup.  Forget all this business,
-		//return and destroy p.
-		ast_mutex_unlock(&p->lock);
-		ast_mutex_destroy(&p->lock);
-		free(p);
-		return -1;
-	} */
-	if (!other) {
-//		p->glaredetect = 0;
-		return 0;
-	}
-	if (ast_mutex_trylock(&other->lock)) {
-		/* Failed to lock.  Release main lock and try again */
-		ast_mutex_unlock(&p->lock);
-		if (us) {
-			if (ast_mutex_unlock(&us->lock)) {
-				ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
-					us->name, f->frametype, f->subclass);
-				us = NULL;
-			}
-		}
-		/* Wait just a bit */
-		usleep(1);
-		/* Only we can destroy ourselves, so we can't disappear here */
-		if (us)
-			ast_mutex_lock(&us->lock);
-		ast_mutex_lock(&p->lock);
-		goto retrylock;
-	}
-	ast_queue_frame(other, f);
-	ast_mutex_unlock(&other->lock);
-//	p->glaredetect = 0;
-	return 0;
-}
 
 static void add_codec_to_answer(const struct jingle_pvt *p, int codec, iks *description)
 {
@@ -211,11 +162,11 @@
 		payload_pcmu = iks_new("payload-type");
 		iks_insert_attrib(payload_pcmu,"id","0");
 		iks_insert_attrib(payload_pcmu,"name","PCMU");
-		iks_insert_attrib(payload_pcmu,"xmlns",GOOGLE_NS);
+		iks_insert_attrib(payload_pcmu,"xmlns","http://www.google.com/session/phone");
 		payload_eg711u = iks_new("payload-type");
 		iks_insert_attrib(payload_eg711u,"id","100");
 		iks_insert_attrib(payload_eg711u,"name","EG711U");
-		iks_insert_attrib(payload_eg711u,"xmlns",GOOGLE_NS);
+		iks_insert_attrib(payload_eg711u,"xmlns","http://www.google.com/session/phone");
 		iks_insert_node(description,payload_pcmu);
 		iks_insert_node(description,payload_eg711u);
 	}
@@ -224,11 +175,11 @@
 		payload_pcma = iks_new("payload-type");
 		iks_insert_attrib(payload_pcma,"id","8");
 		iks_insert_attrib(payload_pcma,"name","PCMA");
-		iks_insert_attrib(payload_pcma,"xmlns",GOOGLE_NS);
+		iks_insert_attrib(payload_pcma,"xmlns","http://www.google.com/session/phone");
 		payload_eg711a = iks_new("payload-type");
 		iks_insert_attrib(payload_eg711a,"id","101");
 		iks_insert_attrib(payload_eg711a,"name","EG711A");
-		iks_insert_attrib(payload_eg711a,"xmlns",GOOGLE_NS);
+		iks_insert_attrib(payload_eg711a,"xmlns","http://www.google.com/session/phone");
 		iks_insert_node(description,payload_pcma);
 		iks_insert_node(description,payload_eg711a);
 	}
@@ -237,7 +188,7 @@
 		payload_ilbc= iks_new("payload-type");
 		iks_insert_attrib(payload_ilbc,"id","102");
 		iks_insert_attrib(payload_ilbc,"name","iLBC");
-		iks_insert_attrib(payload_ilbc,"xmlns",GOOGLE_NS);
+		iks_insert_attrib(payload_ilbc,"xmlns","http://www.google.com/session/phone");
 		iks_insert_node(description,payload_ilbc);
 	}
 	if(!strcasecmp("g723",ast_getformatname(codec))) {
@@ -245,7 +196,7 @@
 		payload_g723= iks_new("payload-type");
 		iks_insert_attrib(payload_g723,"id","4");
 		iks_insert_attrib(payload_g723,"name","G723");
-		iks_insert_attrib(payload_g723,"xmlns",GOOGLE_NS);
+		iks_insert_attrib(payload_g723,"xmlns","http://www.google.com/session/phone");
 		iks_insert_node(description,payload_g723);
 	}
 	ast_rtp_lookup_code(p->rtp, 1, codec);
@@ -381,98 +332,6 @@
 	/* Reset lastrtprx timer */
 	ast_mutex_unlock(&p->lock);
 	return 0;
-}
-
-static int jingle_bridge_call(struct jingle *client,ikspak *pak)
-{
-	char *data, sid[100];
-	struct jingle_pvt *p=client->p;
-	struct ast_channel *bridgepeer = NULL;
-	struct hostent *hp;
-	struct ast_hostent ahp;
-	char iabuf[INET_ADDRSTRLEN];
-	struct sockaddr_in sin;
-	
-	ast_verbose("ONLY A Little further %s\n",(iks_find_attrib(pak->x,"id")));
-	data = iks_find_attrib(pak->x,"id");
-	data = data + 9;
-	ast_copy_string(sid,data,sizeof(sid));
-
-	while(p) {
-		if(!strcasecmp(p->sid,sid)) {
-			break;
-		}
-		p = p->next;
-	}
-	
-	hp = ast_gethostbyname(p->theircandidates->ip, &ahp);
-        sin.sin_family = AF_INET;
-	memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
-	sin.sin_port = htons(p->theircandidates->port);
-	if (p->rtp && sin.sin_port) {
-		ast_rtp_set_peer(p->rtp, &sin);
-		ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
-	}
-	
-	if (!p->owner)  /* There's no open channel owning us */
-		return 0;
-	if (!(p->owner->nativeformats & p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
-		const unsigned slen=512;
-		char s1[slen], s2[slen];
-		ast_log(LOG_DEBUG, "Oooh, we need to change our formats since our peer supports only %s and not %s\n", 
-				ast_getformatname_multiple(s1, slen, p->jointcapability),
-				ast_getformatname_multiple(s2, slen, p->owner->nativeformats));
-		p->owner->nativeformats = ast_codec_choose(&client->prefs, p->jointcapability, 1);
-		ast_set_read_format(p->owner, p->owner->readformat);
-		ast_set_write_format(p->owner, p->owner->writeformat);
-	}
-	if ((bridgepeer=ast_bridged_channel(p->owner))) {
-	//	/* We have a bridge */
-	//	/* Turn on/off music on hold if we are holding/unholding */
-	//	if (sin.sin_addr.s_addr && !sendonly) {
-	//		ast_moh_stop(bridgepeer);
-	//	
-	//		/* Activate a re-invite */
-	//		ast_queue_frame(p->owner, &ast_null_frame);
-	//	} else {
-	//		/* No address for RTP, we're on hold */
-	//		
-	//		ast_moh_start(bridgepeer, NULL);
-	//		if (sendonly)
-	//			ast_rtp_stop(p->rtp);
-	//		/* Activate a re-invite */
-	//		ast_queue_frame(p->owner, &ast_null_frame);
-	//	}
-	}
-
-//	/* Manager Hold and Unhold events must be generated, if necessary */
-//	if (sin.sin_addr.s_addr && !sendonly) {
-//		append_history(p, "Unhold", "%s", req->data);
-//
-//		if (global_callevents && ast_test_flag(p, SIP_CALL_ONHOLD)) {
-//			manager_event(EVENT_FLAG_CALL, "Unhold",
-//				"Channel: %s\r\n"
-//				"Uniqueid: %s\r\n",
-//				p->owner->name, 
-//				p->owner->uniqueid);
-//
-//		}
-//		ast_clear_flag(p, SIP_CALL_ONHOLD);
-//	} else {
-//		/* No address for RTP, we're on hold */
-//		append_history(p, "Hold", "%s", req->data);
-//
-//		if (global_callevents && !ast_test_flag(p, SIP_CALL_ONHOLD)) {
-//			manager_event(EVENT_FLAG_CALL, "Hold",
-//				"Channel: %s\r\n"
-//				"Uniqueid: %s\r\n",
-//				p->owner->name, 
-//				p->owner->uniqueid);
-//		}
-//		ast_set_flag(p, SIP_CALL_ONHOLD);
-//	}
-//	
-	return 1;
 }
 
 static int jingle_response(struct jingle *client, ikspak *pak, const char *reasonstr)
@@ -955,6 +814,7 @@
 	newcandidate->network = atoi(iks_find_attrib(candidate_node, "network"));
 	newcandidate->generation = atoi(iks_find_attrib(candidate_node, "generation"));
 	newcandidate->next = NULL;
+	tmp = client->p;
 	while(tmp) {
 		if(iks_find_with_attrib(pak->x,GOOGLE_NODE,GOOGLE_SID,tmp->sid)) {
 			p = tmp;
@@ -972,7 +832,7 @@
 		memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
 		sin.sin_port = htons(newcandidate->port);
 		if (p->rtp && sin.sin_port) {
-			ast_rtp_set_peer(p->rtp, &sin);
+			/* ast_rtp_set_peer(p->rtp, &sin); */
 			ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
 		}
 		newcandidate->next = p->theircandidates;
@@ -1092,15 +952,7 @@
 {
 	struct jingle_pvt *p = ast->tech_pvt;
 	int res = -1;
-	struct ast_frame f = { AST_FRAME_CONTROL, };
-	int isoutbound;
-
-	/* Queue up a frame representing the indication as a control frame */
-	ast_mutex_lock(&p->lock);
-//	isoutbound = IS_OUTBOUND(ast, p);
-	f.subclass = condition;
-	res = jingle_queue_frame(p, isoutbound, &f, ast);
-	ast_mutex_unlock(&p->lock);
+	ast_log(LOG_NOTICE, "XXX Implement jingle indicate XXX\n");
 	return res;
 }
 
@@ -1108,14 +960,8 @@
 {
 	struct jingle_pvt *p = ast->tech_pvt;
 	int res = -1;
-	struct ast_frame f = { AST_FRAME_DTMF, };
-	int isoutbound;
-
-	ast_mutex_lock(&p->lock);
-//	isoutbound = IS_OUTBOUND(ast, p);
-	f.subclass = digit;
-	res = jingle_queue_frame(p, isoutbound, &f, ast);
-	ast_mutex_unlock(&p->lock);
+
+	ast_log(LOG_NOTICE, "XXX Implement jingle digit XXX\n");
 	return res;
 }
 
@@ -1123,16 +969,8 @@
 {
 	struct jingle_pvt *p = ast->tech_pvt;
 	int res = -1;
-	struct ast_frame f = { AST_FRAME_HTML, };
-	int isoutbound;
-
-	ast_mutex_lock(&p->lock);
-//	isoutbound = IS_OUTBOUND(ast, p);
-	f.subclass = subclass;
-	f.data = (char *)data;
-	f.datalen = datalen;
-	res = jingle_queue_frame(p, isoutbound, &f, ast);
-	ast_mutex_unlock(&p->lock);
+
+	ast_log(LOG_NOTICE, "XXX Implement jingle sendhtml XXX\n");
 	return res;
 }
 
@@ -1175,31 +1013,6 @@
 	ast_mutex_unlock(&p->lock);
 	return res;
 }
-
-#if 0
-static void jingle_destroy(struct jingle_pvt *p)
-{
-	struct jingle_pvt *cur, *prev = NULL;
-	ast_mutex_lock(&jinglelock);
-	cur = jingles->p;
-	while(cur) {
-		if (cur == p) {
-			if (prev)
-				prev->next = cur->next;
-			else
-				jingles->p = cur->next;
-			ast_mutex_destroy(cur);
-			free(cur);
-			break;
-		}
-		prev = cur;
-		cur = cur->next;
-	}
-	ast_mutex_unlock(&jinglelock);
-	if (!cur)
-		ast_log(LOG_WARNING, "Unable ot find jingle '%s@%s' in jingle list\n", p->exten, p->context);
-}
-#endif
 
 /*! \brief Hangup a call through the jingle proxy channel */
 static int jingle_hangup(struct ast_channel *ast)
@@ -1326,10 +1139,6 @@
 		}
 	} else if(iks_find_with_attrib(pak->x,GOOGLE_NODE,"type","terminate")) {
 		jingle_hangup_farend(client, pak);
-	}
-	
-	else if(pak->subtype==IKS_TYPE_RESULT) {
-		jingle_bridge_call(client,pak);	
 	}
 	return 1;
 }
@@ -1572,7 +1381,7 @@
 }
 
 /*! \brief Reload module */
-static int reload()
+static int reload(void)
 {
 	return 0;
 }
@@ -1603,17 +1412,17 @@
 	return 0;
 }
 
-int usecount()
+int usecount(void)
 {
 	return usecnt;
 }
 
-static const char *key()
+static const char *key(void)
 {
 	return ASTERISK_GPL_KEY;
 }
 
-static const char *description()
+static const char *description(void)
 {
 	return desc;
 }

Modified: team/mogorman/asterisk-xmpp/rtp.c
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/rtp.c?rev=21305&r1=21304&r2=21305&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/rtp.c (original)
+++ team/mogorman/asterisk-xmpp/rtp.c Tue Apr 18 22:28:54 2006
@@ -68,6 +68,7 @@
 static int rtpstart = 0;		/*!< First port for RTP sessions (set in rtp.conf) */
 static int rtpend = 0;			/*!< Last port for RTP sessions (set in rtp.conf) */
 static int rtpdebug = 0;		/*!< Are we debugging? */
+static int stundebug = 1;		/*!< Are we debugging stun? */
 static struct sockaddr_in rtpdebugaddr;	/*!< Debug packets to/from this host */
 #ifdef SO_NO_CHECK
 static int nochecksums = 0;
@@ -142,6 +143,232 @@
 	struct sockaddr_in them;	/*!< Socket representation of the remote endpoint. */
 };
 
+
+typedef struct { unsigned int id[4]; } __attribute__((packed)) stun_trans_id;
+
+/* XXX Maybe stun belongs in another file if it ever has use outside of RTP */
+struct stun_header {
+	unsigned short msgtype;
+	unsigned short msglen;
+	stun_trans_id  id;
+	unsigned char ies[0];
+} __attribute__((packed));
+
+struct stun_attr {
+	unsigned short attr;
+	unsigned short len;
+	unsigned char value[0];
+} __attribute__((packed));
+
+struct stun_addr {
+	unsigned char unused;
+	unsigned char family;
+	unsigned short port;
+	unsigned int addr;
+} __attribute__((packed));
+
+#define STUN_IGNORE		(0)
+#define STUN_ACCEPT		(1)
+
+#define STUN_BINDREQ	0x0001
+#define STUN_BINDRESP	0x0101
+#define STUN_BINDERR	0x0111
+#define STUN_SECREQ		0x0002
+#define STUN_SECRESP	0x0102
+#define STUN_SECERR		0x0112
+
+#define STUN_MAPPED_ADDRESS		0x0001
+#define STUN_RESPONSE_ADDRESS	0x0002
+#define STUN_CHANGE_REQUEST		0x0003
+#define STUN_SOURCE_ADDRESS		0x0004
+#define STUN_CHANGED_ADDRESS	0x0005
+#define STUN_USERNAME			0x0006
+#define STUN_PASSWORD			0x0007
+#define STUN_MESSAGE_INTEGRITY	0x0008
+#define STUN_ERROR_CODE			0x0009
+#define STUN_UNKNOWN_ATTRIBUTES	0x000a
+#define STUN_REFLECTED_FROM		0x000b
+
+static const char *stun_msg2str(int msg)
+{
+	switch(msg) {
+	case STUN_BINDREQ:
+		return "Binding Request";
+	case STUN_BINDRESP:
+		return "Binding Response";
+	case STUN_BINDERR:
+		return "Binding Error Response";
+	case STUN_SECREQ:
+		return "Shared Secret Request";
+	case STUN_SECRESP:
+		return "Shared Secret Response";
+	case STUN_SECERR:
+		return "Shared Secret Error Response";
+	}
+	return "Non-RFC3489 Message";
+}
+
+static const char *stun_attr2str(int msg)
+{
+	switch(msg) {
+	case STUN_MAPPED_ADDRESS:
+		return "Mapped Address";
+	case STUN_RESPONSE_ADDRESS:
+		return "Response Address";
+	case STUN_CHANGE_REQUEST:
+		return "Change Request";
+	case STUN_SOURCE_ADDRESS:
+		return "Source Address";
+	case STUN_CHANGED_ADDRESS:
+		return "Changed Address";
+	case STUN_USERNAME:
+		return "Username";
+	case STUN_PASSWORD:
+		return "Password";
+	case STUN_MESSAGE_INTEGRITY:
+		return "Message Integrity";
+	case STUN_ERROR_CODE:
+		return "Error Code";
+	case STUN_UNKNOWN_ATTRIBUTES:
+		return "Unknown Attributes";
+	case STUN_REFLECTED_FROM:
+		return "Reflected From";
+	}
+	return "Non-RFC3489 Attribute";
+}
+
+struct stun_state {
+	unsigned char *username;
+	unsigned char *password;
+};
+
+static int stun_process_attr(struct stun_state *state, struct stun_attr *attr)
+{
+	if (stundebug)
+		ast_verbose("Found STUN Attribute %s (%04x), length %d\n",
+			stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
+	switch(ntohs(attr->attr)) {
+	case STUN_USERNAME:
+		state->username = (unsigned char *)(attr->value);
+		break;
+	case STUN_PASSWORD:
+		state->password = (unsigned char *)(attr->value);
+		break;
+	default:
+		if (stundebug)
+			ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n", 
+				stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
+	}
+	return 0;
+}
+
+static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
+{
+	int size = sizeof(**attr) + strlen(s);
+	if (*left > size) {
+		(*attr)->attr = htons(attrval);
+		(*attr)->len = htons(strlen(s));
+		memcpy((*attr)->value, s, strlen(s));
+		(*attr) = (struct stun_attr *)((*attr)->value + strlen(s));
+		*len += size;
+		*left -= size;
+	}
+}
+
+static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
+{
+	int size = sizeof(**attr) + 8;
+	struct stun_addr *addr;
+	if (*left > size) {
+		(*attr)->attr = htons(attrval);
+		(*attr)->len = htons(8);
+		addr = (struct stun_addr *)((*attr)->value);
+		addr->unused = 0;
+		addr->family = 0x01;
+		addr->port = sin->sin_port;
+		addr->addr = sin->sin_addr.s_addr;
+		(*attr) = (struct stun_attr *)((*attr)->value + 8);
+		*len += size;
+		*left -= size;
+	}
+}
+
+static int stun_send_response(int s, struct sockaddr_in *dst, struct stun_header *resp)
+{
+	return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0, dst, sizeof(*dst));
+}
+
+static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, int len)
+{
+	struct stun_header *resp, *hdr = (struct stun_header *)data;
+	struct stun_attr *attr;
+	struct stun_state st;
+	int ret = STUN_IGNORE;	
+	unsigned char respdata[1024];
+	int resplen, respleft;
+	
+	if (len < sizeof(struct stun_header)) {
+		ast_log(LOG_DEBUG, "Runt STUN packet (only %d, wanting at least %d)\n", len, sizeof(struct stun_header));
+		return -1;
+	}
+	if (stundebug)
+		ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), ntohs(hdr->msglen));
+	if (ntohs(hdr->msglen) > len - sizeof(struct stun_header)) {
+		ast_log(LOG_DEBUG, "Scrambled STUN packet length (got %d, expecting %d)\n", ntohs(hdr->msglen), len - sizeof(struct stun_header));
+	} else
+		len = ntohs(hdr->msglen);
+	data += sizeof(struct stun_header);
+	memset(&st, 0, sizeof(st));
+	while(len) {
+		if (len < sizeof(struct stun_attr)) {
+			ast_log(LOG_DEBUG, "Runt Attribute (got %d, expecting %d)\n", len, sizeof(struct stun_attr));
+			break;
+		}
+		attr = (struct stun_attr *)data;
+		if (ntohs(attr->len) > len) {
+			ast_log(LOG_DEBUG, "Inconsistant Attribute (length %d exceeds remaining msg len %d)\n", ntohs(attr->len), len);
+			break;
+		}
+		if (stun_process_attr(&st, attr)) {
+			ast_log(LOG_DEBUG, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr));
+			break;
+		}
+		/* Clear attribute in case previous entry was a string */
+		attr->attr = 0;
+		data += ntohs(attr->len) + sizeof(struct stun_attr);
+		len -= ntohs(attr->len) + sizeof(struct stun_attr);
+	}
+	/* Null terminate any string */
+	*data = '\0';
+	resp = (struct stun_header *)respdata;
+	resplen = 0;
+	respleft = sizeof(respdata) - sizeof(struct stun_header);
+	resp->id = hdr->id;
+	resp->msgtype = 0;
+	resp->msglen = 0;
+	attr = (struct stun_attr *)resp->ies;
+	if (!len) {
+		switch(ntohs(hdr->msgtype)) {
+		case STUN_BINDREQ:
+			if (stundebug)
+				ast_verbose("STUN Bind Request, username: %s\n", 
+					st.username ? (const char *)st.username : "<none>");
+			if (st.username)
+				append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft);
+			append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft);
+			resp->msglen = htons(resplen);
+			resp->msgtype = htons(STUN_BINDRESP);
+			stun_send_response(s, src, resp);
+			ret = STUN_ACCEPT;
+			break;
+		default:
+			if (stundebug)
+				ast_verbose("Dunno what to do with STUN message %04x (%s)\n", ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype)));
+		}
+	}
+	return ret;
+}
+
 /*! \brief List of current sessions */
 static AST_LIST_HEAD_STATIC(protos, ast_rtp_protocol);
 
@@ -440,7 +667,6 @@
 	res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
 					0, (struct sockaddr *)&sin, &len);
 
-
 	rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
 	if (res < 0) {
 		if (errno != EAGAIN)
@@ -454,6 +680,21 @@
 		return &ast_null_frame;
 	}
 
+	/* Get fields */
+	seqno = ntohl(rtpheader[0]);
+
+	/* Check RTP version */
+	version = (seqno & 0xC0000000) >> 30;
+	if (!version) {
+		if ((stun_handle_packet(rtp->s, &sin, rtp->rawdata + AST_FRIENDLY_OFFSET, res) == STUN_ACCEPT) &&
+			(!rtp->them.sin_port && !rtp->them.sin_addr.s_addr)) {
+			memcpy(&rtp->them, &sin, sizeof(rtp->them));
+		}
+		return &ast_null_frame;
+	}
+
+	if (version != 2)
+		return &ast_null_frame;
 	/* Ignore if the other side hasn't been given an address
 	   yet.  */
 	if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
@@ -471,14 +712,6 @@
 		}
 	}
 
-	/* Get fields */
-	seqno = ntohl(rtpheader[0]);
-
-	/* Check RTP version */
-	version = (seqno & 0xC0000000) >> 30;
-	if (version != 2)
-		return &ast_null_frame;
-	
 	payloadtype = (seqno & 0x7f0000) >> 16;
 	padding = seqno & (1 << 29);
 	mark = seqno & (1 << 23);



More information about the asterisk-commits mailing list