add a bit of documentation on what the stun code in rtp.c does
authorLuigi Rizzo <rizzo@icir.org>
Wed, 11 Jul 2007 16:24:35 +0000 (16:24 +0000)
committerLuigi Rizzo <rizzo@icir.org>
Wed, 11 Jul 2007 16:24:35 +0000 (16:24 +0000)
(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.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@74571 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/rtp.c

index ab55a05..01f1b07 100644 (file)
@@ -237,10 +237,34 @@ struct ast_rtcp {
        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 @@ struct stun_attr {
        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 @@ struct stun_addr {
 #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 @@ struct stun_addr {
 #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 @@ struct stun_addr {
 #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 @@ static const char *stun_msg2str(int msg)
        return "Non-RFC3489 Message";
 }
 
+/*! \brief helper function to print attribute names */
 static const char *stun_attr2str(int msg)
 {
        switch (msg) {
@@ -331,6 +370,7 @@ static const char *stun_attr2str(int msg)
        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 @@ static int stun_process_attr(struct stun_state *state, struct stun_attr *attr)
        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 @@ static void append_attr_string(struct stun_attr **attr, int attrval, const char
        }
 }
 
+/*! \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 @@ static void append_attr_address(struct stun_attr **attr, int attrval, struct soc
        }
 }
 
+/*! \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 @@ size_t ast_rtp_alloc_size(void)
        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 @@ void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, c
        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 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
        /* 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));