[asterisk-commits] rizzo: trunk r74571 - /trunk/main/rtp.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 11 11:24:35 CDT 2007


Author: rizzo
Date: Wed Jul 11 11:24:35 2007
New Revision: 74571

URL: http://svn.digium.com/view/asterisk?view=rev&rev=74571
Log:
add a bit of documentation on what the stun code in rtp.c does
(which is very little, at the moment).

Eventually, when the functionality is extended, the changes can be merged
back to 1.4. At the moment this is pointless.

Note, this change is whitespace only.


Modified:
    trunk/main/rtp.c

Modified: trunk/main/rtp.c
URL: http://svn.digium.com/view/asterisk/trunk/main/rtp.c?view=diff&rev=74571&r1=74570&r2=74571
==============================================================================
--- trunk/main/rtp.c (original)
+++ trunk/main/rtp.c Wed Jul 11 11:24:35 2007
@@ -237,10 +237,34 @@
 	int sendfur;
 };
 
+/*!
+ * \brief STUN support code
+ *
+ * This code provides some support for doing STUN transactions.
+ * Eventually it should be moved elsewhere as other protocols
+ * than RTP can benefit from it - e.g. SIP.
+ * STUN is described in RFC3489 and it is based on the exchange
+ * of UDP packets between a client and one or more servers to
+ * determine the externally visible address (and port) of the client
+ * once it has gone through the NAT boxes that connect it to the
+ * outside.
+ * The simplest request packet is just the header defined in
+ * struct stun_header, and from the response we may just look at
+ * one attribute, STUN_MAPPED_ADDRESS, that we find in the response.
+ * By doing more transactions with different server addresses we
+ * may determine more about the behaviour of the NAT boxes, of
+ * course - the details are in the RFC.
+ *
+ * All STUN packets start with a simple header made of a type,
+ * length (excluding the header) and a 16-byte random transaction id.
+ * Following the header we may have zero or more attributes, each
+ * structured as a type, length and a value (whose format depends
+ * on the type, but often contains addresses).
+ * Of course all fields are in network format.
+ */
 
 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;
@@ -254,6 +278,9 @@
 	unsigned char value[0];
 } __attribute__((packed));
 
+/*
+ * The format normally used for addresses carried by STUN messages.
+ */
 struct stun_addr {
 	unsigned char unused;
 	unsigned char family;
@@ -264,6 +291,13 @@
 #define STUN_IGNORE		(0)
 #define STUN_ACCEPT		(1)
 
+/*! \brief STUN message types
+ * 'BIND' refers to transactions used to determine the externally
+ * visible addresses. 'SEC' refers to transactions used to establish
+ * a session key for subsequent requests.
+ * 'SEC' functionality is not supported here.
+ */
+ 
 #define STUN_BINDREQ	0x0001
 #define STUN_BINDRESP	0x0101
 #define STUN_BINDERR	0x0111
@@ -271,6 +305,9 @@
 #define STUN_SECRESP	0x0102
 #define STUN_SECERR	0x0112
 
+/*! \brief Basic attribute types in stun messages.
+ * Messages can also contain custom attributes (codes above 0x7fff)
+ */
 #define STUN_MAPPED_ADDRESS	0x0001
 #define STUN_RESPONSE_ADDRESS	0x0002
 #define STUN_CHANGE_REQUEST	0x0003
@@ -283,6 +320,7 @@
 #define STUN_UNKNOWN_ATTRIBUTES	0x000a
 #define STUN_REFLECTED_FROM	0x000b
 
+/*! \brief helper function to print message names */
 static const char *stun_msg2str(int msg)
 {
 	switch (msg) {
@@ -302,6 +340,7 @@
 	return "Non-RFC3489 Message";
 }
 
+/*! \brief helper function to print attribute names */
 static const char *stun_attr2str(int msg)
 {
 	switch (msg) {
@@ -331,6 +370,7 @@
 	return "Non-RFC3489 Attribute";
 }
 
+/*! \brief here we store credentials extracted from a message */
 struct stun_state {
 	const char *username;
 	const char *password;
@@ -356,6 +396,7 @@
 	return 0;
 }
 
+/*! \brief append a string to an STUN message */
 static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
 {
 	int size = sizeof(**attr) + strlen(s);
@@ -369,6 +410,7 @@
 	}
 }
 
+/*! \brief append an address to an STUN message */
 static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
 {
 	int size = sizeof(**attr) + 8;
@@ -387,12 +429,14 @@
 	}
 }
 
+/*! \brief wrapper to send an STUN message */
 static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
 {
 	return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0,
 		      (struct sockaddr *)dst, sizeof(*dst));
 }
 
+/*! \brief helper function to generate a random request id */
 static void stun_req_id(struct stun_header *req)
 {
 	int x;
@@ -405,6 +449,9 @@
 	return sizeof(struct ast_rtp);
 }
 
+/*! \brief send a STUN BIND request to the given destination.
+ * Optionally, add a username if specified.
+ */
 void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username)
 {
 	struct stun_header *req;
@@ -426,6 +473,13 @@
 	stun_send(rtp->s, suggestion, req);
 }
 
+/*! \brief handle an incoming STUN message.
+ *
+ * Do some basic sanity checks on packet size and content,
+ * try to extract a bit of information, and possibly reply.
+ * At the moment this only processes BIND requests, and returns
+ * the externally visible address of the request.
+ */
 static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len)
 {
 	struct stun_header *resp, *hdr = (struct stun_header *)data;
@@ -1259,6 +1313,11 @@
 	/* Check RTP version */
 	version = (seqno & 0xC0000000) >> 30;
 	if (!version) {
+		/* If the two high bits are 0, this might be a
+		 * STUN message, so process it. stun_handle_packet()
+		 * answers to requests, and it returns STUN_ACCEPT
+		 * if the request is valid.
+		 */
 		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));




More information about the asterisk-commits mailing list