~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/pjlib-util/src/pjlib-util/stun_simple.c

  • Committer: Jackson Doak
  • Date: 2013-07-10 21:04:46 UTC
  • mfrom: (20.1.3 sid)
  • Revision ID: noskcaj@ubuntu.com-20130710210446-y8f587vza807icr9
Properly merged from upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: stun_simple.c 3553 2011-05-05 06:14:19Z nanang $ */
2
 
/* 
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19
 
 */
20
 
#include <pjlib-util/stun_simple.h>
21
 
#include <pjlib-util/errno.h>
22
 
#include <pj/pool.h>
23
 
#include <pj/log.h>
24
 
#include <pj/sock.h>
25
 
#include <pj/os.h>
26
 
 
27
 
#define THIS_FILE   "stun_simple.c"
28
 
 
29
 
PJ_DEF(pj_status_t) pjstun_create_bind_req( pj_pool_t *pool, 
30
 
                                             void **msg, pj_size_t *len,
31
 
                                             pj_uint32_t id_hi, 
32
 
                                             pj_uint32_t id_lo)
33
 
{
34
 
    pjstun_msg_hdr *hdr;
35
 
    
36
 
    PJ_CHECK_STACK();
37
 
 
38
 
 
39
 
    hdr = PJ_POOL_ZALLOC_T(pool, pjstun_msg_hdr);
40
 
    if (!hdr)
41
 
        return PJ_ENOMEM;
42
 
 
43
 
    hdr->type = pj_htons(PJSTUN_BINDING_REQUEST);
44
 
    hdr->tsx[2] = pj_htonl(id_hi);
45
 
    hdr->tsx[3] = pj_htonl(id_lo);
46
 
    *msg = hdr;
47
 
    *len = sizeof(pjstun_msg_hdr);
48
 
 
49
 
    return PJ_SUCCESS;
50
 
}
51
 
 
52
 
PJ_DEF(pj_status_t) pjstun_parse_msg( void *buf, pj_size_t len, 
53
 
                                       pjstun_msg *msg)
54
 
{
55
 
    pj_uint16_t msg_type, msg_len;
56
 
    char *p_attr;
57
 
 
58
 
    PJ_CHECK_STACK();
59
 
 
60
 
    msg->hdr = (pjstun_msg_hdr*)buf;
61
 
    msg_type = pj_ntohs(msg->hdr->type);
62
 
 
63
 
    switch (msg_type) {
64
 
    case PJSTUN_BINDING_REQUEST:
65
 
    case PJSTUN_BINDING_RESPONSE:
66
 
    case PJSTUN_BINDING_ERROR_RESPONSE:
67
 
    case PJSTUN_SHARED_SECRET_REQUEST:
68
 
    case PJSTUN_SHARED_SECRET_RESPONSE:
69
 
    case PJSTUN_SHARED_SECRET_ERROR_RESPONSE:
70
 
        break;
71
 
    default:
72
 
        PJ_LOG(4,(THIS_FILE, "Error: unknown msg type %d", msg_type));
73
 
        return PJLIB_UTIL_ESTUNINMSGTYPE;
74
 
    }
75
 
 
76
 
    msg_len = pj_ntohs(msg->hdr->length);
77
 
    if (msg_len != len - sizeof(pjstun_msg_hdr)) {
78
 
        PJ_LOG(4,(THIS_FILE, "Error: invalid msg_len %d (expecting %d)", 
79
 
                             msg_len, len - sizeof(pjstun_msg_hdr)));
80
 
        return PJLIB_UTIL_ESTUNINMSGLEN;
81
 
    }
82
 
 
83
 
    msg->attr_count = 0;
84
 
    p_attr = (char*)buf + sizeof(pjstun_msg_hdr);
85
 
 
86
 
    while (msg_len > 0) {
87
 
        pjstun_attr_hdr **attr = &msg->attr[msg->attr_count];
88
 
        pj_uint32_t len;
89
 
        pj_uint16_t attr_type;
90
 
 
91
 
        *attr = (pjstun_attr_hdr*)p_attr;
92
 
        len = pj_ntohs((pj_uint16_t) ((*attr)->length)) + sizeof(pjstun_attr_hdr);
93
 
        len = (len + 3) & ~3;
94
 
 
95
 
        if (msg_len < len) {
96
 
            PJ_LOG(4,(THIS_FILE, "Error: length mismatch in attr %d", 
97
 
                                 msg->attr_count));
98
 
            return PJLIB_UTIL_ESTUNINATTRLEN;
99
 
        }
100
 
 
101
 
        attr_type = pj_ntohs((*attr)->type);
102
 
        if (attr_type > PJSTUN_ATTR_REFLECTED_FROM &&
103
 
            attr_type != PJSTUN_ATTR_XOR_MAPPED_ADDR)
104
 
        {
105
 
            PJ_LOG(5,(THIS_FILE, "Warning: unknown attr type %x in attr %d. "
106
 
                                 "Attribute was ignored.",
107
 
                                 attr_type, msg->attr_count));
108
 
        }
109
 
 
110
 
        msg_len = (pj_uint16_t)(msg_len - len);
111
 
        p_attr += len;
112
 
        ++msg->attr_count;
113
 
    }
114
 
 
115
 
    return PJ_SUCCESS;
116
 
}
117
 
 
118
 
PJ_DEF(void*) pjstun_msg_find_attr( pjstun_msg *msg, pjstun_attr_type t)
119
 
{
120
 
    int i;
121
 
 
122
 
    PJ_CHECK_STACK();
123
 
 
124
 
    for (i=0; i<msg->attr_count; ++i) {
125
 
        pjstun_attr_hdr *attr = msg->attr[i];
126
 
        if (pj_ntohs(attr->type) == t)
127
 
            return attr;
128
 
    }
129
 
 
130
 
    return 0;
131
 
}