~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjsip/src/pjsip/sip_parser.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: sip_parser.c 4288 2012-10-26 09:30:37Z bennylp $ */
 
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 <pjsip/sip_parser.h>
 
21
#include <pjsip/sip_uri.h>
 
22
#include <pjsip/sip_msg.h>
 
23
#include <pjsip/sip_multipart.h>
 
24
#include <pjsip/sip_auth_parser.h>
 
25
#include <pjsip/sip_errno.h>
 
26
#include <pjsip/sip_transport.h>        /* rdata structure */
 
27
#include <pjlib-util/scanner.h>
 
28
#include <pjlib-util/string.h>
 
29
#include <pj/except.h>
 
30
#include <pj/log.h>
 
31
#include <pj/hash.h>
 
32
#include <pj/os.h>
 
33
#include <pj/pool.h>
 
34
#include <pj/string.h>
 
35
#include <pj/ctype.h>
 
36
#include <pj/assert.h>
 
37
 
 
38
#define THIS_FILE           "sip_parser.c"
 
39
 
 
40
#define ALNUM
 
41
#define RESERVED            ";/?:@&=+$,"
 
42
#define MARK                "-_.!~*'()"
 
43
#define UNRESERVED          ALNUM MARK
 
44
#define ESCAPED             "%"
 
45
#define USER_UNRESERVED     "&=+$,;?/"
 
46
#define PASS                "&=+$,"
 
47
#define TOKEN               "-.!%*_`'~+"   /* '=' was removed for parsing 
 
48
                                            * param */
 
49
#define HOST                "_-."
 
50
#define HEX_DIGIT           "abcdefABCDEF"
 
51
#define PARAM_CHAR          "[]/:&+$" UNRESERVED ESCAPED
 
52
#define HNV_UNRESERVED      "[]/?:+$"
 
53
#define HDR_CHAR            HNV_UNRESERVED UNRESERVED ESCAPED
 
54
 
 
55
/* A generic URI can consist of (For a complete BNF see RFC 2396):
 
56
     #?;:@&=+-_.!~*'()%$,/
 
57
 */
 
58
#define GENERIC_URI_CHARS   "#?;:@&=+-_.!~*'()%$,/" "%"
 
59
 
 
60
#define UNREACHED(expr)
 
61
 
 
62
#define IS_NEWLINE(c)   ((c)=='\r' || (c)=='\n')
 
63
#define IS_SPACE(c)     ((c)==' ' || (c)=='\t')
 
64
 
 
65
/*
 
66
 * Header parser records.
 
67
 */
 
68
typedef struct handler_rec
 
69
{
 
70
    char                  hname[PJSIP_MAX_HNAME_LEN+1];
 
71
    pj_size_t             hname_len;
 
72
    pj_uint32_t           hname_hash;
 
73
    pjsip_parse_hdr_func *handler;
 
74
} handler_rec;
 
75
 
 
76
static handler_rec handler[PJSIP_MAX_HEADER_TYPES];
 
77
static unsigned handler_count;
 
78
static int parser_is_initialized;
 
79
 
 
80
/*
 
81
 * URI parser records.
 
82
 */
 
83
typedef struct uri_parser_rec
 
84
{
 
85
    pj_str_t                 scheme;
 
86
    pjsip_parse_uri_func    *parse;
 
87
} uri_parser_rec;
 
88
 
 
89
static uri_parser_rec uri_handler[PJSIP_MAX_URI_TYPES];
 
90
static unsigned uri_handler_count;
 
91
 
 
92
/*
 
93
 * Global vars (also extern).
 
94
 */
 
95
int PJSIP_SYN_ERR_EXCEPTION = -1;
 
96
 
 
97
/* Parser constants */
 
98
static pjsip_parser_const_t pconst =
 
99
{
 
100
    { "user", 4},       /* pjsip_USER_STR       */
 
101
    { "method", 6},     /* pjsip_METHOD_STR     */
 
102
    { "transport", 9},  /* pjsip_TRANSPORT_STR  */
 
103
    { "maddr", 5 },     /* pjsip_MADDR_STR      */
 
104
    { "lr", 2 },        /* pjsip_LR_STR         */
 
105
    { "sip", 3 },       /* pjsip_SIP_STR        */
 
106
    { "sips", 4 },      /* pjsip_SIPS_STR       */
 
107
    { "tel", 3 },       /* pjsip_TEL_STR        */
 
108
    { "branch", 6 },    /* pjsip_BRANCH_STR     */
 
109
    { "ttl", 3 },       /* pjsip_TTL_STR        */
 
110
    { "received", 8 },  /* pjsip_RECEIVED_STR   */
 
111
    { "q", 1 },         /* pjsip_Q_STR          */
 
112
    { "expires", 7 },   /* pjsip_EXPIRES_STR    */
 
113
    { "tag", 3 },       /* pjsip_TAG_STR        */
 
114
    { "rport", 5}       /* pjsip_RPORT_STR      */
 
115
};
 
116
 
 
117
/* Character Input Specification buffer. */
 
118
static pj_cis_buf_t cis_buf;
 
119
 
 
120
 
 
121
/*
 
122
 * Forward decl.
 
123
 */
 
124
static pjsip_msg *  int_parse_msg( pjsip_parse_ctx *ctx, 
 
125
                                   pjsip_parser_err_report *err_list);
 
126
static void         int_parse_param( pj_scanner *scanner, 
 
127
                                     pj_pool_t *pool,
 
128
                                     pj_str_t *pname, 
 
129
                                     pj_str_t *pvalue,
 
130
                                     unsigned option);
 
131
static void         int_parse_uri_param( pj_scanner *scanner, 
 
132
                                         pj_pool_t *pool,
 
133
                                         pj_str_t *pname, 
 
134
                                         pj_str_t *pvalue,
 
135
                                         unsigned option);
 
136
static void         int_parse_hparam( pj_scanner *scanner,
 
137
                                      pj_pool_t *pool,
 
138
                                      pj_str_t *hname,
 
139
                                      pj_str_t *hvalue );
 
140
static void         int_parse_req_line( pj_scanner *scanner, 
 
141
                                        pj_pool_t *pool,
 
142
                                        pjsip_request_line *req_line);
 
143
static int          int_is_next_user( pj_scanner *scanner);
 
144
static void         int_parse_status_line( pj_scanner *scanner, 
 
145
                                           pjsip_status_line *line);
 
146
static void         int_parse_user_pass( pj_scanner *scanner, 
 
147
                                         pj_pool_t *pool,
 
148
                                         pj_str_t *user, 
 
149
                                         pj_str_t *pass);
 
150
static void         int_parse_uri_host_port( pj_scanner *scanner, 
 
151
                                             pj_str_t *p_host, 
 
152
                                             int *p_port);
 
153
static pjsip_uri *  int_parse_uri_or_name_addr( pj_scanner *scanner, 
 
154
                                                pj_pool_t *pool, 
 
155
                                                unsigned option);
 
156
static void*        int_parse_sip_url( pj_scanner *scanner, 
 
157
                                         pj_pool_t *pool,
 
158
                                         pj_bool_t parse_params);
 
159
static pjsip_name_addr *
 
160
                    int_parse_name_addr( pj_scanner *scanner, 
 
161
                                         pj_pool_t *pool );
 
162
static void*        int_parse_other_uri(pj_scanner *scanner, 
 
163
                                        pj_pool_t *pool,
 
164
                                        pj_bool_t parse_params);
 
165
static void         parse_hdr_end( pj_scanner *scanner );
 
166
 
 
167
static pjsip_hdr*   parse_hdr_accept( pjsip_parse_ctx *ctx );
 
168
static pjsip_hdr*   parse_hdr_allow( pjsip_parse_ctx *ctx );
 
169
static pjsip_hdr*   parse_hdr_call_id( pjsip_parse_ctx *ctx);
 
170
static pjsip_hdr*   parse_hdr_contact( pjsip_parse_ctx *ctx);
 
171
static pjsip_hdr*   parse_hdr_content_len( pjsip_parse_ctx *ctx );
 
172
static pjsip_hdr*   parse_hdr_content_type( pjsip_parse_ctx *ctx );
 
173
static pjsip_hdr*   parse_hdr_cseq( pjsip_parse_ctx *ctx );
 
174
static pjsip_hdr*   parse_hdr_expires( pjsip_parse_ctx *ctx );
 
175
static pjsip_hdr*   parse_hdr_from( pjsip_parse_ctx *ctx );
 
176
static pjsip_hdr*   parse_hdr_max_forwards( pjsip_parse_ctx *ctx);
 
177
static pjsip_hdr*   parse_hdr_min_expires( pjsip_parse_ctx *ctx );
 
178
static pjsip_hdr*   parse_hdr_rr( pjsip_parse_ctx *ctx );
 
179
static pjsip_hdr*   parse_hdr_route( pjsip_parse_ctx *ctx );
 
180
static pjsip_hdr*   parse_hdr_require( pjsip_parse_ctx *ctx );
 
181
static pjsip_hdr*   parse_hdr_retry_after( pjsip_parse_ctx *ctx );
 
182
static pjsip_hdr*   parse_hdr_supported( pjsip_parse_ctx *ctx );
 
183
static pjsip_hdr*   parse_hdr_to( pjsip_parse_ctx *ctx );
 
184
static pjsip_hdr*   parse_hdr_unsupported( pjsip_parse_ctx *ctx );
 
185
static pjsip_hdr*   parse_hdr_via( pjsip_parse_ctx *ctx );
 
186
static pjsip_hdr*   parse_hdr_generic_string( pjsip_parse_ctx *ctx);
 
187
 
 
188
/* Convert non NULL terminated string to integer. */
 
189
static unsigned long pj_strtoul_mindigit(const pj_str_t *str, 
 
190
                                         unsigned mindig)
 
191
{
 
192
    unsigned long value;
 
193
    unsigned i;
 
194
 
 
195
    value = 0;
 
196
    for (i=0; i<(unsigned)str->slen; ++i) {
 
197
        value = value * 10 + (str->ptr[i] - '0');
 
198
    }
 
199
    for (; i<mindig; ++i) {
 
200
        value = value * 10;
 
201
    }
 
202
    return value;
 
203
}
 
204
 
 
205
/* Case insensitive comparison */
 
206
#define parser_stricmp(s1, s2)  (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2))
 
207
 
 
208
 
 
209
/* Get a token and unescape */
 
210
PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool,
 
211
                                        const pj_cis_t *spec, 
 
212
                                        const pj_cis_t *unesc_spec,
 
213
                                        pj_str_t *token)
 
214
{
 
215
#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
 
216
    PJ_UNUSED_ARG(pool);
 
217
    PJ_UNUSED_ARG(spec);
 
218
    pj_scan_get_unescape(scanner, unesc_spec, token);
 
219
#else
 
220
    PJ_UNUSED_ARG(unesc_spec);
 
221
    pj_scan_get(scanner, spec, token);
 
222
    *token = pj_str_unescape(pool, token);
 
223
#endif
 
224
}
 
225
 
 
226
 
 
227
 
 
228
/* Syntax error handler for parser. */
 
229
static void on_syntax_error(pj_scanner *scanner)
 
230
{
 
231
    PJ_UNUSED_ARG(scanner);
 
232
    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
233
}
 
234
 
 
235
/* Get parser constants. */
 
236
PJ_DEF(const pjsip_parser_const_t*) pjsip_parser_const(void)
 
237
{
 
238
    return &pconst;
 
239
}
 
240
 
 
241
/* Concatenate unrecognized params into single string. */
 
242
PJ_DEF(void) pjsip_concat_param_imp(pj_str_t *param, pj_pool_t *pool, 
 
243
                                    const pj_str_t *pname, 
 
244
                                    const pj_str_t *pvalue, 
 
245
                                    int sepchar)
 
246
{
 
247
    char *new_param, *p;
 
248
    int len;
 
249
 
 
250
    len = param->slen + pname->slen + pvalue->slen + 3;
 
251
    p = new_param = (char*) pj_pool_alloc(pool, len);
 
252
    
 
253
    if (param->slen) {
 
254
        int old_len = param->slen;
 
255
        pj_memcpy(p, param->ptr, old_len);
 
256
        p += old_len;
 
257
    }
 
258
    *p++ = (char)sepchar;
 
259
    pj_memcpy(p, pname->ptr, pname->slen);
 
260
    p += pname->slen;
 
261
 
 
262
    if (pvalue->slen) {
 
263
        *p++ = '=';
 
264
        pj_memcpy(p, pvalue->ptr, pvalue->slen);
 
265
        p += pvalue->slen;
 
266
    }
 
267
 
 
268
    *p = '\0';
 
269
    
 
270
    param->ptr = new_param;
 
271
    param->slen = p - new_param;
 
272
}
 
273
 
 
274
/* Initialize static properties of the parser. */
 
275
static pj_status_t init_parser()
 
276
{
 
277
    pj_status_t status;
 
278
 
 
279
    /*
 
280
     * Syntax error exception number.
 
281
     */
 
282
    pj_assert (PJSIP_SYN_ERR_EXCEPTION == -1);
 
283
    status = pj_exception_id_alloc("PJSIP syntax error", 
 
284
                                   &PJSIP_SYN_ERR_EXCEPTION);
 
285
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
286
 
 
287
    /*
 
288
     * Init character input spec (cis)
 
289
     */
 
290
 
 
291
    pj_cis_buf_init(&cis_buf);
 
292
 
 
293
    status = pj_cis_init(&cis_buf, &pconst.pjsip_DIGIT_SPEC);
 
294
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
295
    pj_cis_add_num(&pconst.pjsip_DIGIT_SPEC);
 
296
    
 
297
    status = pj_cis_init(&cis_buf, &pconst.pjsip_ALPHA_SPEC);
 
298
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
299
    pj_cis_add_alpha( &pconst.pjsip_ALPHA_SPEC );
 
300
    
 
301
    status = pj_cis_init(&cis_buf, &pconst.pjsip_ALNUM_SPEC);
 
302
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
303
    pj_cis_add_alpha( &pconst.pjsip_ALNUM_SPEC );
 
304
    pj_cis_add_num( &pconst.pjsip_ALNUM_SPEC );
 
305
 
 
306
    status = pj_cis_init(&cis_buf, &pconst.pjsip_NOT_NEWLINE);
 
307
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
308
    pj_cis_add_str(&pconst.pjsip_NOT_NEWLINE, "\r\n");
 
309
    pj_cis_invert(&pconst.pjsip_NOT_NEWLINE);
 
310
 
 
311
    status = pj_cis_init(&cis_buf, &pconst.pjsip_NOT_COMMA_OR_NEWLINE);
 
312
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
313
    pj_cis_add_str( &pconst.pjsip_NOT_COMMA_OR_NEWLINE, ",\r\n");
 
314
    pj_cis_invert(&pconst.pjsip_NOT_COMMA_OR_NEWLINE);
 
315
 
 
316
    status = pj_cis_dup(&pconst.pjsip_TOKEN_SPEC, &pconst.pjsip_ALNUM_SPEC);
 
317
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
318
    pj_cis_add_str( &pconst.pjsip_TOKEN_SPEC, TOKEN);
 
319
 
 
320
    status = pj_cis_dup(&pconst.pjsip_TOKEN_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC);
 
321
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
322
    pj_cis_del_str(&pconst.pjsip_TOKEN_SPEC_ESC, "%");
 
323
 
 
324
    status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC, &pconst.pjsip_TOKEN_SPEC);
 
325
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
326
    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":");
 
327
 
 
328
    status = pj_cis_dup(&pconst.pjsip_VIA_PARAM_SPEC_ESC, &pconst.pjsip_TOKEN_SPEC_ESC);
 
329
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
330
    pj_cis_add_str(&pconst.pjsip_VIA_PARAM_SPEC, ":");
 
331
 
 
332
    status = pj_cis_dup(&pconst.pjsip_HOST_SPEC, &pconst.pjsip_ALNUM_SPEC);
 
333
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
334
    pj_cis_add_str( &pconst.pjsip_HOST_SPEC, HOST);
 
335
 
 
336
    status = pj_cis_dup(&pconst.pjsip_HEX_SPEC, &pconst.pjsip_DIGIT_SPEC);
 
337
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
338
    pj_cis_add_str( &pconst.pjsip_HEX_SPEC, HEX_DIGIT);
 
339
 
 
340
    status = pj_cis_dup(&pconst.pjsip_PARAM_CHAR_SPEC, &pconst.pjsip_ALNUM_SPEC);
 
341
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
342
    pj_cis_add_str(&pconst.pjsip_PARAM_CHAR_SPEC, PARAM_CHAR);
 
343
 
 
344
    status = pj_cis_dup(&pconst.pjsip_PARAM_CHAR_SPEC_ESC, &pconst.pjsip_PARAM_CHAR_SPEC);
 
345
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
346
    pj_cis_del_str(&pconst.pjsip_PARAM_CHAR_SPEC_ESC, ESCAPED);
 
347
 
 
348
    status = pj_cis_dup(&pconst.pjsip_HDR_CHAR_SPEC, &pconst.pjsip_ALNUM_SPEC);
 
349
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
350
    pj_cis_add_str(&pconst.pjsip_HDR_CHAR_SPEC, HDR_CHAR);
 
351
 
 
352
    status = pj_cis_dup(&pconst.pjsip_HDR_CHAR_SPEC_ESC, &pconst.pjsip_HDR_CHAR_SPEC);
 
353
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
354
    pj_cis_del_str(&pconst.pjsip_HDR_CHAR_SPEC_ESC, ESCAPED);
 
355
 
 
356
    status = pj_cis_dup(&pconst.pjsip_USER_SPEC, &pconst.pjsip_ALNUM_SPEC);
 
357
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
358
    pj_cis_add_str( &pconst.pjsip_USER_SPEC, UNRESERVED ESCAPED USER_UNRESERVED );
 
359
 
 
360
    status = pj_cis_dup(&pconst.pjsip_USER_SPEC_ESC, &pconst.pjsip_USER_SPEC);
 
361
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
362
    pj_cis_del_str( &pconst.pjsip_USER_SPEC_ESC, ESCAPED);
 
363
 
 
364
    status = pj_cis_dup(&pconst.pjsip_USER_SPEC_LENIENT, &pconst.pjsip_USER_SPEC);
 
365
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
366
    pj_cis_add_str(&pconst.pjsip_USER_SPEC_LENIENT, "#");
 
367
 
 
368
    status = pj_cis_dup(&pconst.pjsip_USER_SPEC_LENIENT_ESC, &pconst.pjsip_USER_SPEC_ESC);
 
369
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
370
    pj_cis_add_str(&pconst.pjsip_USER_SPEC_LENIENT_ESC, "#");
 
371
 
 
372
    status = pj_cis_dup(&pconst.pjsip_PASSWD_SPEC, &pconst.pjsip_ALNUM_SPEC);
 
373
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
374
    pj_cis_add_str( &pconst.pjsip_PASSWD_SPEC, UNRESERVED ESCAPED PASS);
 
375
 
 
376
    status = pj_cis_dup(&pconst.pjsip_PASSWD_SPEC_ESC, &pconst.pjsip_PASSWD_SPEC);
 
377
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
378
    pj_cis_del_str( &pconst.pjsip_PASSWD_SPEC_ESC, ESCAPED);
 
379
 
 
380
    status = pj_cis_init(&cis_buf, &pconst.pjsip_PROBE_USER_HOST_SPEC);
 
381
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
382
    pj_cis_add_str( &pconst.pjsip_PROBE_USER_HOST_SPEC, "@ \n>");
 
383
    pj_cis_invert( &pconst.pjsip_PROBE_USER_HOST_SPEC );
 
384
 
 
385
    status = pj_cis_init(&cis_buf, &pconst.pjsip_DISPLAY_SPEC);
 
386
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
387
    pj_cis_add_str( &pconst.pjsip_DISPLAY_SPEC, ":\r\n<");
 
388
    pj_cis_invert(&pconst.pjsip_DISPLAY_SPEC);
 
389
 
 
390
    status = pj_cis_dup(&pconst.pjsip_OTHER_URI_CONTENT, &pconst.pjsip_ALNUM_SPEC);
 
391
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
392
    pj_cis_add_str( &pconst.pjsip_OTHER_URI_CONTENT, GENERIC_URI_CHARS);
 
393
 
 
394
    /*
 
395
     * Register URI parsers.
 
396
     */
 
397
 
 
398
    status = pjsip_register_uri_parser("sip", &int_parse_sip_url);
 
399
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
400
 
 
401
    status = pjsip_register_uri_parser("sips", &int_parse_sip_url);
 
402
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
403
 
 
404
    /*
 
405
     * Register header parsers.
 
406
     */
 
407
 
 
408
    status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept);
 
409
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
410
 
 
411
    status = pjsip_register_hdr_parser( "Allow", NULL, &parse_hdr_allow);
 
412
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
413
 
 
414
    status = pjsip_register_hdr_parser( "Call-ID", "i", &parse_hdr_call_id);
 
415
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
416
 
 
417
    status = pjsip_register_hdr_parser( "Contact", "m", &parse_hdr_contact);
 
418
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
419
 
 
420
    status = pjsip_register_hdr_parser( "Content-Length", "l", 
 
421
                                        &parse_hdr_content_len);
 
422
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
423
 
 
424
    status = pjsip_register_hdr_parser( "Content-Type", "c", 
 
425
                                        &parse_hdr_content_type);
 
426
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
427
 
 
428
    status = pjsip_register_hdr_parser( "CSeq", NULL, &parse_hdr_cseq);
 
429
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
430
 
 
431
    status = pjsip_register_hdr_parser( "Expires", NULL, &parse_hdr_expires);
 
432
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
433
 
 
434
    status = pjsip_register_hdr_parser( "From", "f", &parse_hdr_from);
 
435
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
436
 
 
437
    status = pjsip_register_hdr_parser( "Max-Forwards", NULL, 
 
438
                                        &parse_hdr_max_forwards);
 
439
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
440
 
 
441
    status = pjsip_register_hdr_parser( "Min-Expires", NULL, 
 
442
                                        &parse_hdr_min_expires);
 
443
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
444
 
 
445
    status = pjsip_register_hdr_parser( "Record-Route", NULL, &parse_hdr_rr);
 
446
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
447
 
 
448
    status = pjsip_register_hdr_parser( "Route", NULL, &parse_hdr_route);
 
449
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
450
 
 
451
    status = pjsip_register_hdr_parser( "Require", NULL, &parse_hdr_require);
 
452
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
453
 
 
454
    status = pjsip_register_hdr_parser( "Retry-After", NULL, 
 
455
                                        &parse_hdr_retry_after);
 
456
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
457
 
 
458
    status = pjsip_register_hdr_parser( "Supported", "k", 
 
459
                                        &parse_hdr_supported);
 
460
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
461
 
 
462
    status = pjsip_register_hdr_parser( "To", "t", &parse_hdr_to);
 
463
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
464
 
 
465
    status = pjsip_register_hdr_parser( "Unsupported", NULL, 
 
466
                                        &parse_hdr_unsupported);
 
467
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
468
 
 
469
    status = pjsip_register_hdr_parser( "Via", "v", &parse_hdr_via);
 
470
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
471
 
 
472
    /* 
 
473
     * Register auth parser. 
 
474
     */
 
475
 
 
476
    status = pjsip_auth_init_parser();
 
477
 
 
478
    return status;
 
479
}
 
480
 
 
481
void init_sip_parser(void)
 
482
{
 
483
    pj_enter_critical_section();
 
484
    if (++parser_is_initialized == 1) {
 
485
        init_parser();
 
486
    }
 
487
    pj_leave_critical_section();
 
488
}
 
489
 
 
490
void deinit_sip_parser(void)
 
491
{
 
492
    pj_enter_critical_section();
 
493
    if (--parser_is_initialized == 0) {
 
494
        /* Clear header handlers */
 
495
        pj_bzero(handler, sizeof(handler));
 
496
        handler_count = 0;
 
497
 
 
498
        /* Clear URI handlers */
 
499
        pj_bzero(uri_handler, sizeof(uri_handler));
 
500
        uri_handler_count = 0;
 
501
 
 
502
        /* Deregister exception ID */
 
503
        pj_exception_id_free(PJSIP_SYN_ERR_EXCEPTION);
 
504
        PJSIP_SYN_ERR_EXCEPTION = -1;
 
505
    }
 
506
    pj_leave_critical_section();
 
507
}
 
508
 
 
509
/* Compare the handler record with header name, and return:
 
510
 * - 0  if handler match.
 
511
 * - <0 if handler is 'less' than the header name.
 
512
 * - >0 if handler is 'greater' than header name.
 
513
 */
 
514
PJ_INLINE(int) compare_handler( const handler_rec *r1, 
 
515
                                const char *name, 
 
516
                                pj_size_t name_len,
 
517
                                pj_uint32_t hash )
 
518
{
 
519
    PJ_UNUSED_ARG(name_len);
 
520
 
 
521
    /* Compare hashed value. */
 
522
    if (r1->hname_hash < hash)
 
523
        return -1;
 
524
    if (r1->hname_hash > hash)
 
525
        return 1;
 
526
 
 
527
    /* Compare length. */
 
528
    /*
 
529
    if (r1->hname_len < name_len)
 
530
        return -1;
 
531
    if (r1->hname_len > name_len)
 
532
        return 1;
 
533
     */
 
534
 
 
535
    /* Equal length and equal hash. compare the strings. */
 
536
    return pj_memcmp(r1->hname, name, name_len);
 
537
}
 
538
 
 
539
/* Register one handler for one header name. */
 
540
static pj_status_t int_register_parser( const char *name, 
 
541
                                        pjsip_parse_hdr_func *fptr )
 
542
{
 
543
    unsigned    pos;
 
544
    handler_rec rec;
 
545
 
 
546
    if (handler_count >= PJ_ARRAY_SIZE(handler)) {
 
547
        pj_assert(!"Too many handlers!");
 
548
        return PJ_ETOOMANY;
 
549
    }
 
550
 
 
551
    /* Initialize temporary handler. */
 
552
    rec.handler = fptr;
 
553
    rec.hname_len = strlen(name);
 
554
    if (rec.hname_len >= sizeof(rec.hname)) {
 
555
        pj_assert(!"Header name is too long!");
 
556
        return PJ_ENAMETOOLONG;
 
557
    }
 
558
    /* Copy name. */
 
559
    pj_memcpy(rec.hname, name, rec.hname_len);
 
560
    rec.hname[rec.hname_len] = '\0';
 
561
 
 
562
    /* Calculate hash value. */
 
563
    rec.hname_hash = pj_hash_calc(0, rec.hname, rec.hname_len);
 
564
 
 
565
    /* Get the pos to insert the new handler. */
 
566
    for (pos=0; pos < handler_count; ++pos) {
 
567
        int d;
 
568
        d = compare_handler(&handler[pos], rec.hname, rec.hname_len, 
 
569
                            rec.hname_hash);
 
570
        if (d == 0) {
 
571
            pj_assert(0);
 
572
            return PJ_EEXISTS;
 
573
        }
 
574
        if (d > 0) {
 
575
            break;
 
576
        }
 
577
    }
 
578
 
 
579
    /* Shift handlers. */
 
580
    if (pos != handler_count) {
 
581
        pj_memmove( &handler[pos+1], &handler[pos], 
 
582
                    (handler_count-pos)*sizeof(handler_rec));
 
583
    }
 
584
    /* Add new handler. */
 
585
    pj_memcpy( &handler[pos], &rec, sizeof(handler_rec));
 
586
    ++handler_count;
 
587
 
 
588
    return PJ_SUCCESS;
 
589
}
 
590
 
 
591
/* Register parser handler. If both header name and short name are valid,
 
592
 * then two instances of handler will be registered.
 
593
 */
 
594
PJ_DEF(pj_status_t) pjsip_register_hdr_parser( const char *hname,
 
595
                                               const char *hshortname,
 
596
                                               pjsip_parse_hdr_func *fptr)
 
597
{
 
598
    unsigned i, len;
 
599
    char hname_lcase[PJSIP_MAX_HNAME_LEN+1];
 
600
    pj_status_t status;
 
601
 
 
602
    /* Check that name is not too long */
 
603
    len = pj_ansi_strlen(hname);
 
604
    if (len > PJSIP_MAX_HNAME_LEN) {
 
605
        pj_assert(!"Header name is too long!");
 
606
        return PJ_ENAMETOOLONG;
 
607
    }
 
608
 
 
609
    /* Register the normal Mixed-Case name */
 
610
    status = int_register_parser(hname, fptr);
 
611
    if (status != PJ_SUCCESS) {
 
612
        return status;
 
613
    }
 
614
 
 
615
    /* Get the lower-case name */
 
616
    for (i=0; i<len; ++i) {
 
617
        hname_lcase[i] = (char)pj_tolower(hname[i]);
 
618
    }
 
619
    hname_lcase[len] = '\0';
 
620
 
 
621
    /* Register the lower-case version of the name */
 
622
    status = int_register_parser(hname_lcase, fptr);
 
623
    if (status != PJ_SUCCESS) {
 
624
        return status;
 
625
    }
 
626
    
 
627
 
 
628
    /* Register the shortname version of the name */
 
629
    if (hshortname) {
 
630
        status = int_register_parser(hshortname, fptr);
 
631
        if (status != PJ_SUCCESS) 
 
632
            return status;
 
633
    }
 
634
    return PJ_SUCCESS;
 
635
}
 
636
 
 
637
 
 
638
/* Find handler to parse the header name. */
 
639
static pjsip_parse_hdr_func * find_handler_imp(pj_uint32_t  hash, 
 
640
                                               const pj_str_t *hname)
 
641
{
 
642
    handler_rec *first;
 
643
    int          comp;
 
644
    unsigned     n;
 
645
 
 
646
    /* Binary search for the handler. */
 
647
    comp = -1;
 
648
    first = &handler[0];
 
649
    n = handler_count;
 
650
    for (; n > 0; ) {
 
651
        unsigned half = n / 2;
 
652
        handler_rec *mid = first + half;
 
653
 
 
654
        comp = compare_handler(mid, hname->ptr, hname->slen, hash);
 
655
        if (comp < 0) {
 
656
            first = ++mid;
 
657
            n -= half + 1;
 
658
        } else if (comp==0) {
 
659
            first = mid;
 
660
            break;
 
661
        } else {
 
662
            n = half;
 
663
        }
 
664
    }
 
665
 
 
666
    return comp==0 ? first->handler : NULL;
 
667
}
 
668
 
 
669
 
 
670
/* Find handler to parse the header name. */
 
671
static pjsip_parse_hdr_func* find_handler(const pj_str_t *hname)
 
672
{
 
673
    pj_uint32_t hash;
 
674
    char hname_copy[PJSIP_MAX_HNAME_LEN];
 
675
    pj_str_t tmp;
 
676
    pjsip_parse_hdr_func *handler;
 
677
 
 
678
    if (hname->slen >= PJSIP_MAX_HNAME_LEN) {
 
679
        /* Guaranteed not to be able to find handler. */
 
680
        return NULL;
 
681
    }
 
682
 
 
683
    /* First, common case, try to find handler with exact name */
 
684
    hash = pj_hash_calc(0, hname->ptr, hname->slen);
 
685
    handler = find_handler_imp(hash, hname);
 
686
    if (handler)
 
687
        return handler;
 
688
 
 
689
 
 
690
    /* If not found, try converting the header name to lowercase and
 
691
     * search again.
 
692
     */
 
693
    hash = pj_hash_calc_tolower(0, hname_copy, hname);
 
694
    tmp.ptr = hname_copy;
 
695
    tmp.slen = hname->slen;
 
696
    return find_handler_imp(hash, &tmp);
 
697
}
 
698
 
 
699
 
 
700
/* Find URI handler. */
 
701
static pjsip_parse_uri_func* find_uri_handler(const pj_str_t *scheme)
 
702
{
 
703
    unsigned i;
 
704
    for (i=0; i<uri_handler_count; ++i) {
 
705
        if (parser_stricmp(uri_handler[i].scheme, (*scheme))==0)
 
706
            return uri_handler[i].parse;
 
707
    }
 
708
    return &int_parse_other_uri;
 
709
}
 
710
 
 
711
/* Register URI parser. */
 
712
PJ_DEF(pj_status_t) pjsip_register_uri_parser( char *scheme,
 
713
                                               pjsip_parse_uri_func *func)
 
714
{
 
715
    if (uri_handler_count >= PJ_ARRAY_SIZE(uri_handler))
 
716
        return PJ_ETOOMANY;
 
717
 
 
718
    uri_handler[uri_handler_count].scheme = pj_str((char*)scheme);
 
719
    uri_handler[uri_handler_count].parse = func;
 
720
    ++uri_handler_count;
 
721
 
 
722
    return PJ_SUCCESS;
 
723
}
 
724
 
 
725
/* Public function to parse SIP message. */
 
726
PJ_DEF(pjsip_msg*) pjsip_parse_msg( pj_pool_t *pool, 
 
727
                                    char *buf, pj_size_t size,
 
728
                                    pjsip_parser_err_report *err_list)
 
729
{
 
730
    pjsip_msg *msg = NULL;
 
731
    pj_scanner scanner;
 
732
    pjsip_parse_ctx context;
 
733
 
 
734
    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
 
735
                 &on_syntax_error);
 
736
 
 
737
    context.scanner = &scanner;
 
738
    context.pool = pool;
 
739
    context.rdata = NULL;
 
740
 
 
741
    msg = int_parse_msg(&context, err_list);
 
742
 
 
743
    pj_scan_fini(&scanner);
 
744
    return msg;
 
745
}
 
746
 
 
747
/* Public function to parse as rdata.*/
 
748
PJ_DEF(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,
 
749
                                       pjsip_rx_data *rdata )
 
750
{
 
751
    pj_scanner scanner;
 
752
    pjsip_parse_ctx context;
 
753
 
 
754
    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
 
755
                 &on_syntax_error);
 
756
 
 
757
    context.scanner = &scanner;
 
758
    context.pool = rdata->tp_info.pool;
 
759
    context.rdata = rdata;
 
760
 
 
761
    rdata->msg_info.msg = int_parse_msg(&context, &rdata->msg_info.parse_err);
 
762
 
 
763
    pj_scan_fini(&scanner);
 
764
    return rdata->msg_info.msg;
 
765
}
 
766
 
 
767
/* Determine if a message has been received. */
 
768
PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, 
 
769
                                  pj_bool_t is_datagram, pj_size_t *msg_size)
 
770
{
 
771
#if PJ_HAS_TCP
 
772
    const char *hdr_end;
 
773
    const char *body_start;
 
774
    const char *pos;
 
775
    const char *line;
 
776
    int content_length = -1;
 
777
    pj_str_t cur_msg;
 
778
    const pj_str_t end_hdr = { "\n\r\n", 3};
 
779
 
 
780
    *msg_size = size;
 
781
 
 
782
    /* For datagram, the whole datagram IS the message. */
 
783
    if (is_datagram) {
 
784
        return PJ_SUCCESS;
 
785
    }
 
786
 
 
787
 
 
788
    /* Find the end of header area by finding an empty line. 
 
789
     * Don't use plain strstr() since we want to be able to handle
 
790
     * NULL character in the message
 
791
     */
 
792
    cur_msg.ptr = (char*)buf; cur_msg.slen = size;
 
793
    pos = pj_strstr(&cur_msg, &end_hdr);
 
794
    if (pos == NULL) {
 
795
        return PJSIP_EPARTIALMSG;
 
796
    }
 
797
 
 
798
    hdr_end = pos+1;
 
799
    body_start = pos+3;
 
800
 
 
801
    /* Find "Content-Length" header the hard way. */
 
802
    line = pj_strchr(&cur_msg, '\n');
 
803
    while (line && line < hdr_end) {
 
804
        ++line;
 
805
        if ( ((*line=='C' || *line=='c') && 
 
806
              strnicmp_alnum(line, "Content-Length", 14) == 0) ||
 
807
             ((*line=='l' || *line=='L') && 
 
808
              (*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':')))
 
809
        {
 
810
            /* Try to parse the header. */
 
811
            pj_scanner scanner;
 
812
            PJ_USE_EXCEPTION;
 
813
 
 
814
            pj_scan_init(&scanner, (char*)line, hdr_end-line, 
 
815
                         PJ_SCAN_AUTOSKIP_WS_HEADER, &on_syntax_error);
 
816
 
 
817
            PJ_TRY {
 
818
                pj_str_t str_clen;
 
819
 
 
820
                /* Get "Content-Length" or "L" name */
 
821
                if (*line=='C' || *line=='c')
 
822
                    pj_scan_advance_n(&scanner, 14, PJ_TRUE);
 
823
                else if (*line=='l' || *line=='L')
 
824
                    pj_scan_advance_n(&scanner, 1, PJ_TRUE);
 
825
 
 
826
                /* Get colon */
 
827
                if (pj_scan_get_char(&scanner) != ':') {
 
828
                    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
829
                }
 
830
 
 
831
                /* Get number */
 
832
                pj_scan_get(&scanner, &pconst.pjsip_DIGIT_SPEC, &str_clen);
 
833
 
 
834
                /* Get newline. */
 
835
                pj_scan_get_newline(&scanner);
 
836
 
 
837
                /* Found a valid Content-Length header. */
 
838
                content_length = pj_strtoul(&str_clen);
 
839
            }
 
840
            PJ_CATCH_ANY {
 
841
                content_length = -1;
 
842
            }
 
843
            PJ_END
 
844
 
 
845
            pj_scan_fini(&scanner);
 
846
        }
 
847
 
 
848
        /* Found valid Content-Length? */
 
849
        if (content_length != -1)
 
850
            break;
 
851
 
 
852
        /* Go to next line. */
 
853
        cur_msg.slen -= (line - cur_msg.ptr);
 
854
        cur_msg.ptr = (char*)line;
 
855
        line = pj_strchr(&cur_msg, '\n');
 
856
    }
 
857
 
 
858
    /* Found Content-Length? */
 
859
    if (content_length == -1) {
 
860
        return PJSIP_EMISSINGHDR;
 
861
    }
 
862
 
 
863
    /* Enough packet received? */
 
864
    *msg_size = (body_start - buf) + content_length;
 
865
    return (*msg_size) <= size ? PJ_SUCCESS : PJSIP_EPARTIALMSG;
 
866
#else
 
867
    PJ_UNUSED_ARG(buf);
 
868
    PJ_UNUSED_ARG(is_datagram);
 
869
    *msg_size = size;
 
870
    return PJ_SUCCESS;
 
871
#endif
 
872
}
 
873
 
 
874
/* Public function to parse URI */
 
875
PJ_DEF(pjsip_uri*) pjsip_parse_uri( pj_pool_t *pool, 
 
876
                                         char *buf, pj_size_t size,
 
877
                                         unsigned option)
 
878
{
 
879
    pj_scanner scanner;
 
880
    pjsip_uri *uri = NULL;
 
881
    PJ_USE_EXCEPTION;
 
882
 
 
883
    pj_scan_init(&scanner, buf, size, 0, &on_syntax_error);
 
884
 
 
885
    
 
886
    PJ_TRY {
 
887
        uri = int_parse_uri_or_name_addr(&scanner, pool, option);
 
888
    }
 
889
    PJ_CATCH_ANY {
 
890
        uri = NULL;
 
891
    }
 
892
    PJ_END;
 
893
 
 
894
    /* Must have exhausted all inputs. */
 
895
    if (pj_scan_is_eof(&scanner) || IS_NEWLINE(*scanner.curptr)) {
 
896
        /* Success. */
 
897
        pj_scan_fini(&scanner);
 
898
        return uri;
 
899
    }
 
900
 
 
901
    /* Still have some characters unparsed. */
 
902
    pj_scan_fini(&scanner);
 
903
    return NULL;
 
904
}
 
905
 
 
906
/* SIP version */
 
907
static void parse_sip_version(pj_scanner *scanner)
 
908
{
 
909
    pj_str_t SIP = { "SIP", 3 };
 
910
    pj_str_t V2 = { "2.0", 3 };
 
911
    pj_str_t sip, version;
 
912
 
 
913
    pj_scan_get( scanner, &pconst.pjsip_ALPHA_SPEC, &sip);
 
914
    if (pj_scan_get_char(scanner) != '/')
 
915
        on_syntax_error(scanner);
 
916
    pj_scan_get_n( scanner, 3, &version);
 
917
    if (pj_stricmp(&sip, &SIP) || pj_stricmp(&version, &V2))
 
918
        on_syntax_error(scanner);
 
919
}
 
920
 
 
921
static pj_bool_t is_next_sip_version(pj_scanner *scanner)
 
922
{
 
923
    pj_str_t SIP = { "SIP", 3 };
 
924
    pj_str_t sip;
 
925
    int c;
 
926
 
 
927
    c = pj_scan_peek(scanner, &pconst.pjsip_ALPHA_SPEC, &sip);
 
928
    /* return TRUE if it is "SIP" followed by "/" or space.
 
929
     * we include space since the "/" may be separated by space,
 
930
     * although this would mean it would return TRUE if it is a
 
931
     * request and the method is "SIP"!
 
932
     */
 
933
    return c && (c=='/' || c==' ' || c=='\t') && pj_stricmp(&sip, &SIP)==0;
 
934
}
 
935
 
 
936
/* Internal function to parse SIP message */
 
937
static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
 
938
                                 pjsip_parser_err_report *err_list)
 
939
{
 
940
    pj_bool_t parsing_headers;
 
941
    pjsip_msg *msg = NULL;
 
942
    pj_str_t hname;
 
943
    pjsip_ctype_hdr *ctype_hdr = NULL;
 
944
    pj_scanner *scanner = ctx->scanner;
 
945
    pj_pool_t *pool = ctx->pool;
 
946
    PJ_USE_EXCEPTION;
 
947
 
 
948
    parsing_headers = PJ_FALSE;
 
949
 
 
950
retry_parse:
 
951
    PJ_TRY 
 
952
    {
 
953
        if (parsing_headers)
 
954
            goto parse_headers;
 
955
 
 
956
        /* Skip leading newlines. */
 
957
        while (IS_NEWLINE(*scanner->curptr)) {
 
958
            pj_scan_get_newline(scanner);
 
959
        }
 
960
 
 
961
        /* Check if we still have valid packet.
 
962
         * Sometimes endpoints just send blank (CRLF) packets just to keep
 
963
         * NAT bindings open.
 
964
         */
 
965
        if (pj_scan_is_eof(scanner))
 
966
            return NULL;
 
967
 
 
968
        /* Parse request or status line */
 
969
        if (is_next_sip_version(scanner)) {
 
970
            msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG);
 
971
            int_parse_status_line( scanner, &msg->line.status );
 
972
        } else {
 
973
            msg = pjsip_msg_create(pool, PJSIP_REQUEST_MSG);
 
974
            int_parse_req_line(scanner, pool, &msg->line.req );
 
975
        }
 
976
 
 
977
        parsing_headers = PJ_TRUE;
 
978
 
 
979
parse_headers:
 
980
        /* Parse headers. */
 
981
        do {
 
982
            pjsip_parse_hdr_func * handler;
 
983
            pjsip_hdr *hdr = NULL;
 
984
 
 
985
            /* Init hname just in case parsing fails.
 
986
             * Ref: PROTOS #2412
 
987
             */
 
988
            hname.slen = 0;
 
989
            
 
990
            /* Get hname. */
 
991
            pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hname);
 
992
            if (pj_scan_get_char( scanner ) != ':') {
 
993
                PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
994
            }
 
995
            
 
996
            /* Find handler. */
 
997
            handler = find_handler(&hname);
 
998
            
 
999
            /* Call the handler if found.
 
1000
             * If no handler is found, then treat the header as generic
 
1001
             * hname/hvalue pair.
 
1002
             */
 
1003
            if (handler) {
 
1004
                hdr = (*handler)(ctx);
 
1005
 
 
1006
                /* Note:
 
1007
                 *  hdr MAY BE NULL, if parsing does not yield a new header
 
1008
                 *  instance, e.g. the values have been added to existing
 
1009
                 *  header. See http://trac.pjsip.org/repos/ticket/940
 
1010
                 */
 
1011
 
 
1012
                /* Check if we've just parsed a Content-Type header. 
 
1013
                 * We will check for a message body if we've got Content-Type 
 
1014
                 * header.
 
1015
                 */
 
1016
                if (hdr && hdr->type == PJSIP_H_CONTENT_TYPE) {
 
1017
                    ctype_hdr = (pjsip_ctype_hdr*)hdr;
 
1018
                }
 
1019
 
 
1020
            } else {
 
1021
                hdr = parse_hdr_generic_string(ctx);
 
1022
                hdr->name = hdr->sname = hname;
 
1023
            }
 
1024
            
 
1025
        
 
1026
            /* Single parse of header line can produce multiple headers.
 
1027
             * For example, if one Contact: header contains Contact list
 
1028
             * separated by comma, then these Contacts will be split into
 
1029
             * different Contact headers.
 
1030
             * So here we must insert list instead of just insert one header.
 
1031
             */
 
1032
            if (hdr)
 
1033
                pj_list_insert_nodes_before(&msg->hdr, hdr);
 
1034
            
 
1035
            /* Parse until EOF or an empty line is found. */
 
1036
        } while (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr));
 
1037
        
 
1038
        parsing_headers = PJ_FALSE;
 
1039
 
 
1040
        /* If empty line is found, eat it. */
 
1041
        if (!pj_scan_is_eof(scanner)) {
 
1042
            if (IS_NEWLINE(*scanner->curptr)) {
 
1043
                pj_scan_get_newline(scanner);
 
1044
            }
 
1045
        }
 
1046
 
 
1047
        /* If we have Content-Type header, treat the rest of the message 
 
1048
         * as body.
 
1049
         */
 
1050
        if (ctype_hdr && scanner->curptr!=scanner->end) {
 
1051
            /* New: if Content-Type indicates that this is a multipart
 
1052
             * message body, parse it.
 
1053
             */
 
1054
            const pj_str_t STR_MULTIPART = { "multipart", 9 };
 
1055
            pjsip_msg_body *body;
 
1056
 
 
1057
            if (pj_stricmp(&ctype_hdr->media.type, &STR_MULTIPART)==0) {
 
1058
                body = pjsip_multipart_parse(pool, scanner->curptr,
 
1059
                                             scanner->end - scanner->curptr,
 
1060
                                             &ctype_hdr->media, 0);
 
1061
            } else {
 
1062
                body = PJ_POOL_ALLOC_T(pool, pjsip_msg_body);
 
1063
                pjsip_media_type_cp(pool, &body->content_type,
 
1064
                                    &ctype_hdr->media);
 
1065
 
 
1066
                body->data = scanner->curptr;
 
1067
                body->len = scanner->end - scanner->curptr;
 
1068
                body->print_body = &pjsip_print_text_body;
 
1069
                body->clone_data = &pjsip_clone_text_data;
 
1070
            }
 
1071
 
 
1072
            msg->body = body;
 
1073
        }
 
1074
    }
 
1075
    PJ_CATCH_ANY 
 
1076
    {
 
1077
        /* Exception was thrown during parsing. 
 
1078
         * Skip until newline, and parse next header. 
 
1079
         */
 
1080
        if (err_list) {
 
1081
            pjsip_parser_err_report *err_info;
 
1082
            
 
1083
            err_info = PJ_POOL_ALLOC_T(pool, pjsip_parser_err_report);
 
1084
            err_info->except_code = PJ_GET_EXCEPTION();
 
1085
            err_info->line = scanner->line;
 
1086
            /* Scanner's column is zero based, so add 1 */
 
1087
            err_info->col = pj_scan_get_col(scanner) + 1;
 
1088
            if (parsing_headers)
 
1089
                err_info->hname = hname;
 
1090
            else if (msg && msg->type == PJSIP_REQUEST_MSG)
 
1091
                err_info->hname = pj_str("Request Line");
 
1092
            else if (msg && msg->type == PJSIP_RESPONSE_MSG)
 
1093
                err_info->hname = pj_str("Status Line");
 
1094
            else
 
1095
                err_info->hname.slen = 0;
 
1096
            
 
1097
            pj_list_insert_before(err_list, err_info);
 
1098
        }
 
1099
        
 
1100
        if (parsing_headers) {
 
1101
            if (!pj_scan_is_eof(scanner)) {
 
1102
                /* Skip until next line.
 
1103
                 * Watch for header continuation.
 
1104
                 */
 
1105
                do {
 
1106
                    pj_scan_skip_line(scanner);
 
1107
                } while (IS_SPACE(*scanner->curptr));
 
1108
            }
 
1109
 
 
1110
            /* Restore flag. Flag may be set in int_parse_sip_url() */
 
1111
            scanner->skip_ws = PJ_SCAN_AUTOSKIP_WS_HEADER;
 
1112
 
 
1113
            /* Continue parse next header, if any. */
 
1114
            if (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr)) {
 
1115
                goto retry_parse;
 
1116
            }
 
1117
        }
 
1118
 
 
1119
        msg = NULL;
 
1120
    }
 
1121
    PJ_END;
 
1122
 
 
1123
    return msg;
 
1124
}
 
1125
 
 
1126
 
 
1127
/* Parse parameter (pname ["=" pvalue]). */
 
1128
static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,
 
1129
                             pj_str_t *pname, pj_str_t *pvalue,
 
1130
                             const pj_cis_t *spec, const pj_cis_t *esc_spec,
 
1131
                             unsigned option)
 
1132
{
 
1133
    /* pname */
 
1134
    parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);
 
1135
 
 
1136
    /* init pvalue */
 
1137
    pvalue->ptr = NULL;
 
1138
    pvalue->slen = 0;
 
1139
 
 
1140
    /* pvalue, if any */
 
1141
    if (*scanner->curptr == '=') {
 
1142
        pj_scan_get_char(scanner);
 
1143
        if (!pj_scan_is_eof(scanner)) {
 
1144
            /* pvalue can be a quoted string. */
 
1145
            if (*scanner->curptr == '"') {
 
1146
                pj_scan_get_quote( scanner, '"', '"', pvalue);
 
1147
                if (option & PJSIP_PARSE_REMOVE_QUOTE) {
 
1148
                    pvalue->ptr++;
 
1149
                    pvalue->slen -= 2;
 
1150
                }
 
1151
            } else if (*scanner->curptr == '[') {
 
1152
                /* pvalue can be a quoted IPv6; in this case, the
 
1153
                 * '[' and ']' quote characters are to be removed
 
1154
                 * from the pvalue. 
 
1155
                 */
 
1156
                pj_scan_get_char(scanner);
 
1157
                pj_scan_get_until_ch(scanner, ']', pvalue);
 
1158
                pj_scan_get_char(scanner);
 
1159
            } else if(pj_cis_match(spec, *scanner->curptr)) {
 
1160
                parser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);
 
1161
            }
 
1162
        }
 
1163
    }
 
1164
}
 
1165
 
 
1166
/* Parse parameter (pname ["=" pvalue]) using token. */
 
1167
PJ_DEF(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,
 
1168
                                   pj_str_t *pname, pj_str_t *pvalue,
 
1169
                                   unsigned option)
 
1170
{
 
1171
    parse_param_imp(scanner, pool, pname, pvalue, &pconst.pjsip_TOKEN_SPEC,
 
1172
                    &pconst.pjsip_TOKEN_SPEC_ESC, option);
 
1173
}
 
1174
 
 
1175
 
 
1176
/* Parse parameter (pname ["=" pvalue]) using paramchar. */
 
1177
PJ_DEF(void) pjsip_parse_uri_param_imp( pj_scanner *scanner, pj_pool_t *pool,
 
1178
                                        pj_str_t *pname, pj_str_t *pvalue,
 
1179
                                        unsigned option)
 
1180
{
 
1181
    parse_param_imp(scanner,pool, pname, pvalue, &pconst.pjsip_PARAM_CHAR_SPEC,
 
1182
                    &pconst.pjsip_PARAM_CHAR_SPEC_ESC, option);
 
1183
}
 
1184
 
 
1185
 
 
1186
/* Parse parameter (";" pname ["=" pvalue]) in SIP header. */
 
1187
static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool,
 
1188
                             pj_str_t *pname, pj_str_t *pvalue,
 
1189
                             unsigned option)
 
1190
{
 
1191
    /* Get ';' character */
 
1192
    pj_scan_get_char(scanner);
 
1193
 
 
1194
    /* Get pname and optionally pvalue */
 
1195
    pjsip_parse_param_imp(scanner, pool, pname, pvalue, option);
 
1196
}
 
1197
 
 
1198
/* Parse parameter (";" pname ["=" pvalue]) in URI. */
 
1199
static void int_parse_uri_param( pj_scanner *scanner, pj_pool_t *pool,
 
1200
                                 pj_str_t *pname, pj_str_t *pvalue,
 
1201
                                 unsigned option)
 
1202
{
 
1203
    /* Get ';' character */
 
1204
    pj_scan_get_char(scanner);
 
1205
 
 
1206
    /* Get pname and optionally pvalue */
 
1207
    pjsip_parse_uri_param_imp(scanner, pool, pname, pvalue, 
 
1208
                              option);
 
1209
}
 
1210
 
 
1211
 
 
1212
/* Parse header parameter. */
 
1213
static void int_parse_hparam( pj_scanner *scanner, pj_pool_t *pool,
 
1214
                              pj_str_t *hname, pj_str_t *hvalue )
 
1215
{
 
1216
    /* Get '?' or '&' character. */
 
1217
    pj_scan_get_char(scanner);
 
1218
 
 
1219
    /* hname */
 
1220
    parser_get_and_unescape(scanner, pool, &pconst.pjsip_HDR_CHAR_SPEC, 
 
1221
                            &pconst.pjsip_HDR_CHAR_SPEC_ESC, hname);
 
1222
 
 
1223
    /* Init hvalue */
 
1224
    hvalue->ptr = NULL;
 
1225
    hvalue->slen = 0;
 
1226
 
 
1227
    /* pvalue, if any */
 
1228
    if (*scanner->curptr == '=') {
 
1229
        pj_scan_get_char(scanner);
 
1230
        if (!pj_scan_is_eof(scanner) && 
 
1231
            pj_cis_match(&pconst.pjsip_HDR_CHAR_SPEC, *scanner->curptr))
 
1232
        {
 
1233
            parser_get_and_unescape(scanner, pool, &pconst.pjsip_HDR_CHAR_SPEC,
 
1234
                                    &pconst.pjsip_HDR_CHAR_SPEC_ESC, hvalue);
 
1235
        }
 
1236
    }
 
1237
}
 
1238
 
 
1239
/* Parse host part:
 
1240
 *   host =  hostname / IPv4address / IPv6reference
 
1241
 */
 
1242
static void int_parse_host(pj_scanner *scanner, pj_str_t *host)
 
1243
{
 
1244
    if (*scanner->curptr == '[') {
 
1245
        /* Note: the '[' and ']' characters are removed from the host */
 
1246
        pj_scan_get_char(scanner);
 
1247
        pj_scan_get_until_ch(scanner, ']', host);
 
1248
        pj_scan_get_char(scanner);
 
1249
    } else {
 
1250
        pj_scan_get( scanner, &pconst.pjsip_HOST_SPEC, host);
 
1251
    }
 
1252
}
 
1253
 
 
1254
/* Parse host:port in URI. */
 
1255
static void int_parse_uri_host_port( pj_scanner *scanner, 
 
1256
                                     pj_str_t *host, int *p_port)
 
1257
{
 
1258
    int_parse_host(scanner, host);
 
1259
 
 
1260
    /* RFC3261 section 19.1.2: host don't need to be unescaped */
 
1261
    if (*scanner->curptr == ':') {
 
1262
        pj_str_t port;
 
1263
        pj_scan_get_char(scanner);
 
1264
        pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &port);
 
1265
        *p_port = pj_strtoul(&port);
 
1266
    } else {
 
1267
        *p_port = 0;
 
1268
    }
 
1269
}
 
1270
 
 
1271
/* Determine if the next token in an URI is a user specification. */
 
1272
static int int_is_next_user(pj_scanner *scanner)
 
1273
{
 
1274
    pj_str_t dummy;
 
1275
    int is_user;
 
1276
 
 
1277
    /* Find character '@'. If this character exist, then the token
 
1278
     * must be a username.
 
1279
     */
 
1280
    if (pj_scan_peek( scanner, &pconst.pjsip_PROBE_USER_HOST_SPEC, &dummy) == '@')
 
1281
        is_user = 1;
 
1282
    else
 
1283
        is_user = 0;
 
1284
 
 
1285
    return is_user;
 
1286
}
 
1287
 
 
1288
/* Parse user:pass tokens in an URI. */
 
1289
static void int_parse_user_pass( pj_scanner *scanner, pj_pool_t *pool,
 
1290
                                 pj_str_t *user, pj_str_t *pass)
 
1291
{
 
1292
    parser_get_and_unescape(scanner, pool, &pconst.pjsip_USER_SPEC_LENIENT, 
 
1293
                            &pconst.pjsip_USER_SPEC_LENIENT_ESC, user);
 
1294
 
 
1295
    if ( *scanner->curptr == ':') {
 
1296
        pj_scan_get_char( scanner );
 
1297
        parser_get_and_unescape(scanner, pool, &pconst.pjsip_PASSWD_SPEC,
 
1298
                                &pconst.pjsip_PASSWD_SPEC_ESC, pass);
 
1299
    } else {
 
1300
        pass->ptr = NULL;
 
1301
        pass->slen = 0;
 
1302
    }
 
1303
 
 
1304
    /* Get the '@' */
 
1305
    pj_scan_get_char( scanner );
 
1306
}
 
1307
 
 
1308
/* Parse all types of URI. */
 
1309
static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *pool,
 
1310
                                              unsigned opt)
 
1311
{
 
1312
    pjsip_uri *uri;
 
1313
    int is_name_addr = 0;
 
1314
 
 
1315
    /* Exhaust any whitespaces. */
 
1316
    pj_scan_skip_whitespace(scanner);
 
1317
 
 
1318
    if (*scanner->curptr=='"' || *scanner->curptr=='<') {
 
1319
        uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );
 
1320
        is_name_addr = 1;
 
1321
    } else {
 
1322
        pj_str_t scheme;
 
1323
        int next_ch;
 
1324
 
 
1325
        next_ch = pj_scan_peek( scanner, &pconst.pjsip_DISPLAY_SPEC, &scheme);
 
1326
 
 
1327
        if (next_ch==':') {
 
1328
            pjsip_parse_uri_func *func = find_uri_handler(&scheme);
 
1329
 
 
1330
            if (func == NULL) {
 
1331
                /* Unsupported URI scheme */
 
1332
                PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
1333
            }
 
1334
 
 
1335
            uri = (pjsip_uri*)
 
1336
                  (*func)(scanner, pool, 
 
1337
                          (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)==0);
 
1338
 
 
1339
 
 
1340
        } else {
 
1341
            uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );
 
1342
            is_name_addr = 1;
 
1343
        }
 
1344
    }
 
1345
 
 
1346
    /* Should we return the URI object as name address? */
 
1347
    if (opt & PJSIP_PARSE_URI_AS_NAMEADDR) {
 
1348
        if (is_name_addr == 0) {
 
1349
            pjsip_name_addr *name_addr;
 
1350
 
 
1351
            name_addr = pjsip_name_addr_create(pool);
 
1352
            name_addr->uri = uri;
 
1353
 
 
1354
            uri = (pjsip_uri*)name_addr;
 
1355
        }
 
1356
    }
 
1357
 
 
1358
    return uri;
 
1359
}
 
1360
 
 
1361
/* Parse URI. */
 
1362
static pjsip_uri *int_parse_uri(pj_scanner *scanner, pj_pool_t *pool, 
 
1363
                                pj_bool_t parse_params)
 
1364
{
 
1365
    /* Bug:
 
1366
     * This function should not call back int_parse_name_addr() because
 
1367
     * it is called by that function. This would cause stack overflow
 
1368
     * with PROTOS test #1223.
 
1369
    if (*scanner->curptr=='"' || *scanner->curptr=='<') {
 
1370
        return (pjsip_uri*)int_parse_name_addr( scanner, pool );
 
1371
    } else {
 
1372
    */
 
1373
        pj_str_t scheme;
 
1374
        int colon;
 
1375
        pjsip_parse_uri_func *func;
 
1376
 
 
1377
        /* Get scheme. */
 
1378
        colon = pj_scan_peek(scanner, &pconst.pjsip_TOKEN_SPEC, &scheme);
 
1379
        if (colon != ':') {
 
1380
            PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
1381
        }
 
1382
 
 
1383
        func = find_uri_handler(&scheme);
 
1384
        if (func)  {
 
1385
            return (pjsip_uri*)(*func)(scanner, pool, parse_params);
 
1386
 
 
1387
        } else {
 
1388
            /* Unsupported URI scheme */
 
1389
            PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
1390
            UNREACHED({ return NULL; /* Not reached. */ })
 
1391
        }
 
1392
 
 
1393
    /*
 
1394
    }
 
1395
    */
 
1396
}
 
1397
 
 
1398
/* Parse "sip:" and "sips:" URI. 
 
1399
 * This actually returns (pjsip_sip_uri*) type,
 
1400
 */
 
1401
static void* int_parse_sip_url( pj_scanner *scanner, 
 
1402
                                pj_pool_t *pool,
 
1403
                                pj_bool_t parse_params)
 
1404
{
 
1405
    pj_str_t scheme;
 
1406
    pjsip_sip_uri *url = NULL;
 
1407
    int colon;
 
1408
    int skip_ws = scanner->skip_ws;
 
1409
    scanner->skip_ws = 0;
 
1410
 
 
1411
    pj_scan_get(scanner, &pconst.pjsip_TOKEN_SPEC, &scheme);
 
1412
    colon = pj_scan_get_char(scanner);
 
1413
    if (colon != ':') {
 
1414
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
1415
    }
 
1416
 
 
1417
    if (parser_stricmp(scheme, pconst.pjsip_SIP_STR)==0) {
 
1418
        url = pjsip_sip_uri_create(pool, 0);
 
1419
 
 
1420
    } else if (parser_stricmp(scheme, pconst.pjsip_SIPS_STR)==0) {
 
1421
        url = pjsip_sip_uri_create(pool, 1);
 
1422
 
 
1423
    } else {
 
1424
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
1425
        /* should not reach here */
 
1426
        UNREACHED({
 
1427
            pj_assert(0);
 
1428
            return 0;
 
1429
        })
 
1430
    }
 
1431
 
 
1432
    if (int_is_next_user(scanner)) {
 
1433
        int_parse_user_pass(scanner, pool, &url->user, &url->passwd);
 
1434
    }
 
1435
 
 
1436
    /* Get host:port */
 
1437
    int_parse_uri_host_port(scanner, &url->host, &url->port);
 
1438
 
 
1439
    /* Get URL parameters. */
 
1440
    if (parse_params) {
 
1441
      while (*scanner->curptr == ';' ) {
 
1442
        pj_str_t pname, pvalue;
 
1443
 
 
1444
        int_parse_uri_param( scanner, pool, &pname, &pvalue, 0);
 
1445
 
 
1446
        if (!parser_stricmp(pname, pconst.pjsip_USER_STR) && pvalue.slen) {
 
1447
            url->user_param = pvalue;
 
1448
 
 
1449
        } else if (!parser_stricmp(pname, pconst.pjsip_METHOD_STR) && pvalue.slen) {
 
1450
            url->method_param = pvalue;
 
1451
 
 
1452
        } else if (!parser_stricmp(pname, pconst.pjsip_TRANSPORT_STR) && pvalue.slen) {
 
1453
            url->transport_param = pvalue;
 
1454
 
 
1455
        } else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {
 
1456
            url->ttl_param = pj_strtoul(&pvalue);
 
1457
 
 
1458
        } else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {
 
1459
            url->maddr_param = pvalue;
 
1460
 
 
1461
        } else if (!parser_stricmp(pname, pconst.pjsip_LR_STR)) {
 
1462
            url->lr_param = 1;
 
1463
 
 
1464
        } else {
 
1465
            pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
 
1466
            p->name = pname;
 
1467
            p->value = pvalue;
 
1468
            pj_list_insert_before(&url->other_param, p);
 
1469
        }
 
1470
      }
 
1471
    }
 
1472
 
 
1473
    /* Get header params. */
 
1474
    if (parse_params && *scanner->curptr == '?') {
 
1475
      do {
 
1476
        pjsip_param *param;
 
1477
        param = PJ_POOL_ALLOC_T(pool, pjsip_param);
 
1478
        int_parse_hparam(scanner, pool, &param->name, &param->value);
 
1479
        pj_list_insert_before(&url->header_param, param);
 
1480
      } while (*scanner->curptr == '&');
 
1481
    }
 
1482
 
 
1483
    scanner->skip_ws = skip_ws;
 
1484
    pj_scan_skip_whitespace(scanner);
 
1485
    return url;
 
1486
}
 
1487
 
 
1488
/* Parse nameaddr. */
 
1489
static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner, 
 
1490
                                             pj_pool_t *pool )
 
1491
{
 
1492
    int has_bracket;
 
1493
    pjsip_name_addr *name_addr;
 
1494
 
 
1495
    name_addr = pjsip_name_addr_create(pool);
 
1496
 
 
1497
    if (*scanner->curptr == '"') {
 
1498
        pj_scan_get_quote( scanner, '"', '"', &name_addr->display);
 
1499
        /* Trim the leading and ending quote */
 
1500
        name_addr->display.ptr++;
 
1501
        name_addr->display.slen -= 2;
 
1502
 
 
1503
    } else if (*scanner->curptr != '<') {
 
1504
        int next;
 
1505
        pj_str_t dummy;
 
1506
 
 
1507
        /* This can be either the start of display name,
 
1508
         * the start of URL ("sip:", "sips:", "tel:", etc.), or '<' char.
 
1509
         * We're only interested in display name, because SIP URL
 
1510
         * will be parser later.
 
1511
         */
 
1512
        next = pj_scan_peek(scanner, &pconst.pjsip_DISPLAY_SPEC, &dummy);
 
1513
        if (next == '<') {
 
1514
            /* Ok, this is what we're looking for, a display name. */
 
1515
            pj_scan_get_until_ch( scanner, '<', &name_addr->display);
 
1516
            pj_strtrim(&name_addr->display);
 
1517
        }
 
1518
    }
 
1519
 
 
1520
    /* Manually skip whitespace. */
 
1521
    pj_scan_skip_whitespace(scanner);
 
1522
 
 
1523
    /* Get the SIP-URL */
 
1524
    has_bracket = (*scanner->curptr == '<');
 
1525
    if (has_bracket) {
 
1526
        pj_scan_get_char(scanner);
 
1527
    } else if (name_addr->display.slen) {
 
1528
        /* Must have bracket now (2012-10-26).
 
1529
         * Allowing (invalid) name-addr to pass URI verification will
 
1530
         * cause us to send invalid URI to the wire.
 
1531
         */
 
1532
        PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);
 
1533
    }
 
1534
    name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE );
 
1535
    if (has_bracket) {
 
1536
        if (pj_scan_get_char(scanner) != '>')
 
1537
            PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);
 
1538
    }
 
1539
 
 
1540
    return name_addr;
 
1541
}
 
1542
 
 
1543
 
 
1544
/* Parse other URI */
 
1545
static void* int_parse_other_uri(pj_scanner *scanner, 
 
1546
                                 pj_pool_t *pool,
 
1547
                                 pj_bool_t parse_params)
 
1548
{
 
1549
    pjsip_other_uri *uri = 0;
 
1550
    const pjsip_parser_const_t *pc = pjsip_parser_const();
 
1551
    int skip_ws = scanner->skip_ws;
 
1552
 
 
1553
    PJ_UNUSED_ARG(parse_params);
 
1554
 
 
1555
    scanner->skip_ws = 0;
 
1556
    
 
1557
    uri = pjsip_other_uri_create(pool); 
 
1558
    
 
1559
    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &uri->scheme);
 
1560
    if (pj_scan_get_char(scanner) != ':') {
 
1561
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
1562
    }
 
1563
    
 
1564
    pj_scan_get(scanner, &pc->pjsip_OTHER_URI_CONTENT, &uri->content);
 
1565
    scanner->skip_ws = skip_ws;
 
1566
    
 
1567
    return uri;
 
1568
}
 
1569
 
 
1570
 
 
1571
/* Parse SIP request line. */
 
1572
static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool,
 
1573
                                pjsip_request_line *req_line)
 
1574
{
 
1575
    pj_str_t token;
 
1576
 
 
1577
    pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &token);
 
1578
    pjsip_method_init_np( &req_line->method, &token);
 
1579
 
 
1580
    req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE);
 
1581
    parse_sip_version(scanner);
 
1582
    pj_scan_get_newline( scanner );
 
1583
}
 
1584
 
 
1585
/* Parse status line. */
 
1586
static void int_parse_status_line( pj_scanner *scanner, 
 
1587
                                   pjsip_status_line *status_line)
 
1588
{
 
1589
    pj_str_t token;
 
1590
 
 
1591
    parse_sip_version(scanner);
 
1592
    pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token);
 
1593
    status_line->code = pj_strtoul(&token);
 
1594
    if (*scanner->curptr != '\r' && *scanner->curptr != '\n')
 
1595
        pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &status_line->reason);
 
1596
    else
 
1597
        status_line->reason.slen=0, status_line->reason.ptr=NULL;
 
1598
    pj_scan_get_newline( scanner );
 
1599
}
 
1600
 
 
1601
 
 
1602
/*
 
1603
 * Public API to parse SIP status line.
 
1604
 */
 
1605
PJ_DEF(pj_status_t) pjsip_parse_status_line( char *buf, pj_size_t size,
 
1606
                                             pjsip_status_line *status_line)
 
1607
{
 
1608
    pj_scanner scanner;
 
1609
    PJ_USE_EXCEPTION;
 
1610
 
 
1611
    pj_bzero(status_line, sizeof(*status_line));
 
1612
    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
 
1613
                 &on_syntax_error);
 
1614
 
 
1615
    PJ_TRY {
 
1616
        int_parse_status_line(&scanner, status_line);
 
1617
    } 
 
1618
    PJ_CATCH_ANY {
 
1619
        /* Tolerate the error if it is caused only by missing newline */
 
1620
        if (status_line->code == 0 && status_line->reason.slen == 0) {
 
1621
            pj_scan_fini(&scanner);
 
1622
            return PJSIP_EINVALIDMSG;
 
1623
        }
 
1624
    }
 
1625
    PJ_END;
 
1626
 
 
1627
    pj_scan_fini(&scanner);
 
1628
    return PJ_SUCCESS;
 
1629
}
 
1630
 
 
1631
 
 
1632
/* Parse ending of header. */
 
1633
static void parse_hdr_end( pj_scanner *scanner )
 
1634
{
 
1635
    if (pj_scan_is_eof(scanner)) {
 
1636
        ;   /* Do nothing. */
 
1637
    } else if (*scanner->curptr == '&') {
 
1638
        pj_scan_get_char(scanner);
 
1639
    } else {
 
1640
        pj_scan_get_newline(scanner);
 
1641
    }
 
1642
}
 
1643
 
 
1644
/* Parse ending of header. */
 
1645
PJ_DEF(void) pjsip_parse_end_hdr_imp( pj_scanner *scanner )
 
1646
{
 
1647
    parse_hdr_end(scanner);
 
1648
}
 
1649
 
 
1650
/* Parse generic array header. */
 
1651
static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
 
1652
                                     pj_scanner *scanner)
 
1653
{
 
1654
    /* Some header fields allow empty elements in the value:
 
1655
     *   Accept, Allow, Supported
 
1656
     */
 
1657
    if (pj_scan_is_eof(scanner) || 
 
1658
        *scanner->curptr == '\r' || *scanner->curptr == '\n') 
 
1659
    {
 
1660
        goto end;
 
1661
    }
 
1662
 
 
1663
    if (hdr->count >= PJ_ARRAY_SIZE(hdr->values)) {
 
1664
        /* Too many elements */
 
1665
        on_syntax_error(scanner);
 
1666
        return;
 
1667
    }
 
1668
 
 
1669
    pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, 
 
1670
                 &hdr->values[hdr->count]);
 
1671
    hdr->count++;
 
1672
 
 
1673
    while (*scanner->curptr == ',') {
 
1674
        pj_scan_get_char(scanner);
 
1675
        pj_scan_get( scanner, &pconst.pjsip_NOT_COMMA_OR_NEWLINE, 
 
1676
                     &hdr->values[hdr->count]);
 
1677
        hdr->count++;
 
1678
 
 
1679
        if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT)
 
1680
            break;
 
1681
    }
 
1682
 
 
1683
end:
 
1684
    parse_hdr_end(scanner);
 
1685
}
 
1686
 
 
1687
/* Parse generic string header. */
 
1688
static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr,
 
1689
                                      pjsip_parse_ctx *ctx)
 
1690
{
 
1691
    pj_scanner *scanner = ctx->scanner;
 
1692
 
 
1693
    hdr->hvalue.slen = 0;
 
1694
 
 
1695
    /* header may be mangled hence the loop */
 
1696
    while (pj_cis_match(&pconst.pjsip_NOT_NEWLINE, *scanner->curptr)) {
 
1697
        pj_str_t next, tmp;
 
1698
 
 
1699
        pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &hdr->hvalue);
 
1700
        if (pj_scan_is_eof(scanner) || IS_NEWLINE(*scanner->curptr))
 
1701
            break;
 
1702
        /* mangled, get next fraction */
 
1703
        pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &next);
 
1704
        /* concatenate */
 
1705
        tmp.ptr = (char*)pj_pool_alloc(ctx->pool, 
 
1706
                                       hdr->hvalue.slen + next.slen + 2);
 
1707
        tmp.slen = 0;
 
1708
        pj_strcpy(&tmp, &hdr->hvalue);
 
1709
        pj_strcat2(&tmp, " ");
 
1710
        pj_strcat(&tmp, &next);
 
1711
        tmp.ptr[tmp.slen] = '\0';
 
1712
 
 
1713
        hdr->hvalue = tmp;
 
1714
    }
 
1715
 
 
1716
    parse_hdr_end(scanner);
 
1717
}
 
1718
 
 
1719
/* Parse generic integer header. */
 
1720
static void parse_generic_int_hdr( pjsip_generic_int_hdr *hdr,
 
1721
                                   pj_scanner *scanner )
 
1722
{
 
1723
    pj_str_t tmp;
 
1724
    pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);
 
1725
    hdr->ivalue = pj_strtoul(&tmp);
 
1726
    parse_hdr_end(scanner);
 
1727
}
 
1728
 
 
1729
 
 
1730
/* Parse Accept header. */
 
1731
static pjsip_hdr* parse_hdr_accept(pjsip_parse_ctx *ctx)
 
1732
{
 
1733
    pjsip_accept_hdr *accept = pjsip_accept_hdr_create(ctx->pool);
 
1734
    parse_generic_array_hdr(accept, ctx->scanner);
 
1735
    return (pjsip_hdr*)accept;
 
1736
}
 
1737
 
 
1738
/* Parse Allow header. */
 
1739
static pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx)
 
1740
{
 
1741
    pjsip_allow_hdr *allow = pjsip_allow_hdr_create(ctx->pool);
 
1742
    parse_generic_array_hdr(allow, ctx->scanner);
 
1743
    return (pjsip_hdr*)allow;
 
1744
}
 
1745
 
 
1746
/* Parse Call-ID header. */
 
1747
static pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx)
 
1748
{
 
1749
    pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool);
 
1750
    pj_scan_get( ctx->scanner, &pconst.pjsip_NOT_NEWLINE, &hdr->id);
 
1751
    parse_hdr_end(ctx->scanner);
 
1752
 
 
1753
    if (ctx->rdata)
 
1754
        ctx->rdata->msg_info.cid = hdr;
 
1755
 
 
1756
    return (pjsip_hdr*)hdr;
 
1757
}
 
1758
 
 
1759
/* Parse and interpret Contact param. */
 
1760
static void int_parse_contact_param( pjsip_contact_hdr *hdr, 
 
1761
                                     pj_scanner *scanner,
 
1762
                                     pj_pool_t *pool)
 
1763
{
 
1764
    while ( *scanner->curptr == ';' ) {
 
1765
        pj_str_t pname, pvalue;
 
1766
 
 
1767
        int_parse_param( scanner, pool, &pname, &pvalue, 0);
 
1768
        if (!parser_stricmp(pname, pconst.pjsip_Q_STR) && pvalue.slen) {
 
1769
            char *dot_pos = (char*) pj_memchr(pvalue.ptr, '.', pvalue.slen);
 
1770
            if (!dot_pos) {
 
1771
                hdr->q1000 = pj_strtoul(&pvalue) * 1000;
 
1772
            } else {
 
1773
                pj_str_t tmp = pvalue;
 
1774
 
 
1775
                tmp.slen = dot_pos - pvalue.ptr;
 
1776
                hdr->q1000 = pj_strtoul(&tmp) * 1000;
 
1777
 
 
1778
                pvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1);
 
1779
                pvalue.ptr = dot_pos + 1;
 
1780
                hdr->q1000 += pj_strtoul_mindigit(&pvalue, 3);
 
1781
            }    
 
1782
        } else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && pvalue.slen) {
 
1783
            hdr->expires = pj_strtoul(&pvalue);
 
1784
 
 
1785
        } else {
 
1786
            pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
 
1787
            p->name = pname;
 
1788
            p->value = pvalue;
 
1789
            pj_list_insert_before(&hdr->other_param, p);
 
1790
        }
 
1791
    }
 
1792
}
 
1793
 
 
1794
/* Parse Contact header. */
 
1795
static pjsip_hdr* parse_hdr_contact( pjsip_parse_ctx *ctx )
 
1796
{
 
1797
    pjsip_contact_hdr *first = NULL;
 
1798
    pj_scanner *scanner = ctx->scanner;
 
1799
    
 
1800
    do {
 
1801
        pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(ctx->pool);
 
1802
        if (first == NULL)
 
1803
            first = hdr;
 
1804
        else
 
1805
            pj_list_insert_before(first, hdr);
 
1806
 
 
1807
        if (*scanner->curptr == '*') {
 
1808
            pj_scan_get_char(scanner);
 
1809
            hdr->star = 1;
 
1810
 
 
1811
        } else {
 
1812
            hdr->star = 0;
 
1813
            hdr->uri = int_parse_uri_or_name_addr(scanner, ctx->pool, 
 
1814
                                                  PJSIP_PARSE_URI_AS_NAMEADDR |
 
1815
                                                  PJSIP_PARSE_URI_IN_FROM_TO_HDR);
 
1816
 
 
1817
            int_parse_contact_param(hdr, scanner, ctx->pool);
 
1818
        }
 
1819
 
 
1820
        if (*scanner->curptr != ',')
 
1821
            break;
 
1822
 
 
1823
        pj_scan_get_char(scanner);
 
1824
 
 
1825
    } while (1);
 
1826
 
 
1827
    parse_hdr_end(scanner);
 
1828
 
 
1829
    return (pjsip_hdr*)first;
 
1830
}
 
1831
 
 
1832
/* Parse Content-Length header. */
 
1833
static pjsip_hdr* parse_hdr_content_len( pjsip_parse_ctx *ctx )
 
1834
{
 
1835
    pj_str_t digit;
 
1836
    pjsip_clen_hdr *hdr;
 
1837
 
 
1838
    hdr = pjsip_clen_hdr_create(ctx->pool);
 
1839
    pj_scan_get(ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &digit);
 
1840
    hdr->len = pj_strtoul(&digit);
 
1841
    parse_hdr_end(ctx->scanner);
 
1842
 
 
1843
    if (ctx->rdata)
 
1844
        ctx->rdata->msg_info.clen = hdr;
 
1845
 
 
1846
    return (pjsip_hdr*)hdr;
 
1847
}
 
1848
 
 
1849
/* Parse Content-Type header. */
 
1850
static pjsip_hdr* parse_hdr_content_type( pjsip_parse_ctx *ctx )
 
1851
{
 
1852
    pjsip_ctype_hdr *hdr;
 
1853
    pj_scanner *scanner = ctx->scanner;
 
1854
 
 
1855
    hdr = pjsip_ctype_hdr_create(ctx->pool);
 
1856
    
 
1857
    /* Parse media type and subtype. */
 
1858
    pj_scan_get(scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->media.type);
 
1859
    pj_scan_get_char(scanner);
 
1860
    pj_scan_get(scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->media.subtype);
 
1861
 
 
1862
    /* Parse media parameters */
 
1863
    while (*scanner->curptr == ';') {
 
1864
        pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
 
1865
        int_parse_param(scanner, ctx->pool, &param->name, &param->value, 0);
 
1866
        pj_list_push_back(&hdr->media.param, param);
 
1867
    }
 
1868
 
 
1869
    parse_hdr_end(ctx->scanner);
 
1870
 
 
1871
    if (ctx->rdata)
 
1872
        ctx->rdata->msg_info.ctype = hdr;
 
1873
 
 
1874
    return (pjsip_hdr*)hdr;
 
1875
}
 
1876
 
 
1877
/* Parse CSeq header. */
 
1878
static pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx )
 
1879
{
 
1880
    pj_str_t cseq, method;
 
1881
    pjsip_cseq_hdr *hdr;
 
1882
 
 
1883
    hdr = pjsip_cseq_hdr_create(ctx->pool);
 
1884
    pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq);
 
1885
    hdr->cseq = pj_strtoul(&cseq);
 
1886
 
 
1887
    pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);
 
1888
    pjsip_method_init_np(&hdr->method, &method);
 
1889
 
 
1890
    parse_hdr_end( ctx->scanner );
 
1891
 
 
1892
    if (ctx->rdata)
 
1893
        ctx->rdata->msg_info.cseq = hdr;
 
1894
 
 
1895
    return (pjsip_hdr*)hdr;
 
1896
}
 
1897
 
 
1898
/* Parse Expires header. */
 
1899
static pjsip_hdr* parse_hdr_expires(pjsip_parse_ctx *ctx)
 
1900
{
 
1901
    pjsip_expires_hdr *hdr = pjsip_expires_hdr_create(ctx->pool, 0);
 
1902
    parse_generic_int_hdr(hdr, ctx->scanner);
 
1903
    return (pjsip_hdr*)hdr;
 
1904
}
 
1905
 
 
1906
/* Parse From: or To: header. */
 
1907
static void parse_hdr_fromto( pj_scanner *scanner, 
 
1908
                              pj_pool_t *pool, 
 
1909
                              pjsip_from_hdr *hdr)
 
1910
{
 
1911
    hdr->uri = int_parse_uri_or_name_addr(scanner, pool, 
 
1912
                                          PJSIP_PARSE_URI_AS_NAMEADDR |
 
1913
                                          PJSIP_PARSE_URI_IN_FROM_TO_HDR);
 
1914
 
 
1915
    while ( *scanner->curptr == ';' ) {
 
1916
        pj_str_t pname, pvalue;
 
1917
 
 
1918
        int_parse_param( scanner, pool, &pname, &pvalue, 0);
 
1919
 
 
1920
        if (!parser_stricmp(pname, pconst.pjsip_TAG_STR)) {
 
1921
            hdr->tag = pvalue;
 
1922
            
 
1923
        } else {
 
1924
            pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
 
1925
            p->name = pname;
 
1926
            p->value = pvalue;
 
1927
            pj_list_insert_before(&hdr->other_param, p);
 
1928
        }
 
1929
    }
 
1930
 
 
1931
    parse_hdr_end(scanner);
 
1932
}
 
1933
 
 
1934
/* Parse From: header. */
 
1935
static pjsip_hdr* parse_hdr_from( pjsip_parse_ctx *ctx )
 
1936
{
 
1937
    pjsip_from_hdr *hdr = pjsip_from_hdr_create(ctx->pool);
 
1938
    parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);
 
1939
    if (ctx->rdata)
 
1940
        ctx->rdata->msg_info.from = hdr;
 
1941
 
 
1942
    return (pjsip_hdr*)hdr;
 
1943
}
 
1944
 
 
1945
/* Parse Require: header. */
 
1946
static pjsip_hdr* parse_hdr_require( pjsip_parse_ctx *ctx )
 
1947
{
 
1948
    pjsip_require_hdr *hdr;
 
1949
    pj_bool_t new_hdr = (ctx->rdata==NULL ||
 
1950
                         ctx->rdata->msg_info.require == NULL);
 
1951
    
 
1952
    if (ctx->rdata && ctx->rdata->msg_info.require) {
 
1953
        hdr = ctx->rdata->msg_info.require;
 
1954
    } else {
 
1955
        hdr = pjsip_require_hdr_create(ctx->pool);
 
1956
        if (ctx->rdata)
 
1957
            ctx->rdata->msg_info.require = hdr;
 
1958
    }
 
1959
 
 
1960
    parse_generic_array_hdr(hdr, ctx->scanner);
 
1961
 
 
1962
    return new_hdr ? (pjsip_hdr*)hdr : NULL;
 
1963
}
 
1964
 
 
1965
/* Parse Retry-After: header. */
 
1966
static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx)
 
1967
{
 
1968
    pjsip_retry_after_hdr *hdr;
 
1969
    pj_scanner *scanner = ctx->scanner;
 
1970
    pj_str_t tmp;
 
1971
 
 
1972
    hdr = pjsip_retry_after_hdr_create(ctx->pool, 0);
 
1973
    
 
1974
    pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &tmp);
 
1975
    hdr->ivalue = pj_strtoul(&tmp);
 
1976
 
 
1977
    while (!pj_scan_is_eof(scanner) && *scanner->curptr!='\r' &&
 
1978
           *scanner->curptr!='\n')
 
1979
    {
 
1980
        if (*scanner->curptr=='(') {
 
1981
            pj_scan_get_quote(scanner, '(', ')', &hdr->comment);
 
1982
            /* Trim the leading and ending parens */
 
1983
            hdr->comment.ptr++;
 
1984
            hdr->comment.slen -= 2;
 
1985
        } else if (*scanner->curptr==';') {
 
1986
            pjsip_param *prm = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
 
1987
            int_parse_param(scanner, ctx->pool, &prm->name, &prm->value, 0);
 
1988
            pj_list_push_back(&hdr->param, prm);
 
1989
        }
 
1990
    }
 
1991
 
 
1992
    parse_hdr_end(scanner);
 
1993
    return (pjsip_hdr*)hdr;
 
1994
}
 
1995
 
 
1996
/* Parse Supported: header. */
 
1997
static pjsip_hdr* parse_hdr_supported(pjsip_parse_ctx *ctx)
 
1998
{
 
1999
    pjsip_supported_hdr *hdr;
 
2000
    pj_bool_t new_hdr = (ctx->rdata==NULL || 
 
2001
                         ctx->rdata->msg_info.supported == NULL);
 
2002
 
 
2003
    if (ctx->rdata && ctx->rdata->msg_info.supported) {
 
2004
        hdr = ctx->rdata->msg_info.supported;
 
2005
    } else {
 
2006
        hdr = pjsip_supported_hdr_create(ctx->pool);
 
2007
        if (ctx->rdata)
 
2008
            ctx->rdata->msg_info.supported = hdr;
 
2009
    }
 
2010
 
 
2011
    parse_generic_array_hdr(hdr, ctx->scanner);
 
2012
    return new_hdr ? (pjsip_hdr*)hdr : NULL;
 
2013
}
 
2014
 
 
2015
/* Parse To: header. */
 
2016
static pjsip_hdr* parse_hdr_to( pjsip_parse_ctx *ctx )
 
2017
{
 
2018
    pjsip_to_hdr *hdr = pjsip_to_hdr_create(ctx->pool);
 
2019
    parse_hdr_fromto(ctx->scanner, ctx->pool, hdr);
 
2020
 
 
2021
    if (ctx->rdata)
 
2022
        ctx->rdata->msg_info.to = hdr;
 
2023
 
 
2024
    return (pjsip_hdr*)hdr;
 
2025
}
 
2026
 
 
2027
/* Parse Unsupported: header. */
 
2028
static pjsip_hdr* parse_hdr_unsupported(pjsip_parse_ctx *ctx)
 
2029
{
 
2030
    pjsip_unsupported_hdr *hdr = pjsip_unsupported_hdr_create(ctx->pool);
 
2031
    parse_generic_array_hdr(hdr, ctx->scanner);
 
2032
    return (pjsip_hdr*)hdr;
 
2033
}
 
2034
 
 
2035
/* Parse and interpret Via parameters. */
 
2036
static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner,
 
2037
                                 pj_pool_t *pool)
 
2038
{
 
2039
    while ( *scanner->curptr == ';' ) {
 
2040
        pj_str_t pname, pvalue;
 
2041
 
 
2042
        //Parse with PARAM_CHAR instead, to allow IPv6
 
2043
        //No, back to using int_parse_param() for the "`" character!
 
2044
        //int_parse_param( scanner, pool, &pname, &pvalue, 0);
 
2045
        //parse_param_imp(scanner, pool, &pname, &pvalue, 
 
2046
        //              &pconst.pjsip_TOKEN_SPEC,
 
2047
        //              &pconst.pjsip_TOKEN_SPEC_ESC, 0);
 
2048
        //int_parse_param(scanner, pool, &pname, &pvalue, 0);
 
2049
        // This should be the correct one:
 
2050
        //  added special spec for Via parameter, basically token plus
 
2051
        //  ":" to allow IPv6 address in the received param.
 
2052
        pj_scan_get_char(scanner);
 
2053
        parse_param_imp(scanner, pool, &pname, &pvalue,
 
2054
                        &pconst.pjsip_VIA_PARAM_SPEC,
 
2055
                        &pconst.pjsip_VIA_PARAM_SPEC_ESC,
 
2056
                        0);
 
2057
 
 
2058
        if (!parser_stricmp(pname, pconst.pjsip_BRANCH_STR) && pvalue.slen) {
 
2059
            hdr->branch_param = pvalue;
 
2060
 
 
2061
        } else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) {
 
2062
            hdr->ttl_param = pj_strtoul(&pvalue);
 
2063
            
 
2064
        } else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) {
 
2065
            hdr->maddr_param = pvalue;
 
2066
 
 
2067
        } else if (!parser_stricmp(pname, pconst.pjsip_RECEIVED_STR) && pvalue.slen) {
 
2068
            hdr->recvd_param = pvalue;
 
2069
 
 
2070
        } else if (!parser_stricmp(pname, pconst.pjsip_RPORT_STR)) {
 
2071
            if (pvalue.slen)
 
2072
                hdr->rport_param = pj_strtoul(&pvalue);
 
2073
            else
 
2074
                hdr->rport_param = 0;
 
2075
        } else {
 
2076
            pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
 
2077
            p->name = pname;
 
2078
            p->value = pvalue;
 
2079
            pj_list_insert_before(&hdr->other_param, p);
 
2080
        }
 
2081
    }
 
2082
}
 
2083
 
 
2084
/* Parse Max-Forwards header. */
 
2085
static pjsip_hdr* parse_hdr_max_forwards( pjsip_parse_ctx *ctx )
 
2086
{
 
2087
    pjsip_max_fwd_hdr *hdr;
 
2088
    hdr = pjsip_max_fwd_hdr_create(ctx->pool, 0);
 
2089
    parse_generic_int_hdr(hdr, ctx->scanner);
 
2090
 
 
2091
    if (ctx->rdata)
 
2092
        ctx->rdata->msg_info.max_fwd = hdr;
 
2093
 
 
2094
    return (pjsip_hdr*)hdr;
 
2095
}
 
2096
 
 
2097
/* Parse Min-Expires header. */
 
2098
static pjsip_hdr* parse_hdr_min_expires(pjsip_parse_ctx *ctx)
 
2099
{
 
2100
    pjsip_min_expires_hdr *hdr;
 
2101
    hdr = pjsip_min_expires_hdr_create(ctx->pool, 0);
 
2102
    parse_generic_int_hdr(hdr, ctx->scanner);
 
2103
    return (pjsip_hdr*)hdr;
 
2104
}
 
2105
 
 
2106
 
 
2107
/* Parse Route: or Record-Route: header. */
 
2108
static void parse_hdr_rr_route( pj_scanner *scanner, pj_pool_t *pool,
 
2109
                                pjsip_routing_hdr *hdr )
 
2110
{
 
2111
    pjsip_name_addr *temp=int_parse_name_addr(scanner, pool);
 
2112
 
 
2113
    pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));
 
2114
 
 
2115
    while (*scanner->curptr == ';') {
 
2116
        pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
 
2117
        int_parse_param(scanner, pool, &p->name, &p->value, 0);
 
2118
        pj_list_insert_before(&hdr->other_param, p);
 
2119
    }
 
2120
}
 
2121
 
 
2122
/* Parse Record-Route header. */
 
2123
static pjsip_hdr* parse_hdr_rr( pjsip_parse_ctx *ctx)
 
2124
{
 
2125
    pjsip_rr_hdr *first = NULL;
 
2126
    pj_scanner *scanner = ctx->scanner;
 
2127
 
 
2128
    do {
 
2129
        pjsip_rr_hdr *hdr = pjsip_rr_hdr_create(ctx->pool);
 
2130
        if (!first) {
 
2131
            first = hdr;
 
2132
        } else {
 
2133
            pj_list_insert_before(first, hdr);
 
2134
        }
 
2135
        parse_hdr_rr_route(scanner, ctx->pool, hdr);
 
2136
        if (*scanner->curptr == ',') {
 
2137
            pj_scan_get_char(scanner);
 
2138
        } else {
 
2139
            break;
 
2140
        }
 
2141
    } while (1);
 
2142
    parse_hdr_end(scanner);
 
2143
 
 
2144
    if (ctx->rdata && ctx->rdata->msg_info.record_route==NULL)
 
2145
        ctx->rdata->msg_info.record_route = first;
 
2146
 
 
2147
    return (pjsip_hdr*)first;
 
2148
}
 
2149
 
 
2150
/* Parse Route: header. */
 
2151
static pjsip_hdr* parse_hdr_route( pjsip_parse_ctx *ctx )
 
2152
{
 
2153
    pjsip_route_hdr *first = NULL;
 
2154
    pj_scanner *scanner = ctx->scanner;
 
2155
 
 
2156
    do {
 
2157
        pjsip_route_hdr *hdr = pjsip_route_hdr_create(ctx->pool);
 
2158
        if (!first) {
 
2159
            first = hdr;
 
2160
        } else {
 
2161
            pj_list_insert_before(first, hdr);
 
2162
        }
 
2163
        parse_hdr_rr_route(scanner, ctx->pool, hdr);
 
2164
        if (*scanner->curptr == ',') {
 
2165
            pj_scan_get_char(scanner);
 
2166
        } else {
 
2167
            break;
 
2168
        }
 
2169
    } while (1);
 
2170
    parse_hdr_end(scanner);
 
2171
 
 
2172
    if (ctx->rdata && ctx->rdata->msg_info.route==NULL)
 
2173
        ctx->rdata->msg_info.route = first;
 
2174
 
 
2175
    return (pjsip_hdr*)first;
 
2176
}
 
2177
 
 
2178
/* Parse Via: header. */
 
2179
static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )
 
2180
{
 
2181
    pjsip_via_hdr *first = NULL;
 
2182
    pj_scanner *scanner = ctx->scanner;
 
2183
 
 
2184
    do {
 
2185
        pjsip_via_hdr *hdr = pjsip_via_hdr_create(ctx->pool);
 
2186
        if (!first)
 
2187
            first = hdr;
 
2188
        else
 
2189
            pj_list_insert_before(first, hdr);
 
2190
 
 
2191
        parse_sip_version(scanner);
 
2192
        if (pj_scan_get_char(scanner) != '/')
 
2193
            on_syntax_error(scanner);
 
2194
 
 
2195
        pj_scan_get( scanner, &pconst.pjsip_TOKEN_SPEC, &hdr->transport);
 
2196
        int_parse_host(scanner, &hdr->sent_by.host);
 
2197
 
 
2198
        if (*scanner->curptr==':') {
 
2199
            pj_str_t digit;
 
2200
            pj_scan_get_char(scanner);
 
2201
            pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &digit);
 
2202
            hdr->sent_by.port = pj_strtoul(&digit);
 
2203
        }
 
2204
        
 
2205
        int_parse_via_param(hdr, scanner, ctx->pool);
 
2206
 
 
2207
        if (*scanner->curptr == '(') {
 
2208
            pj_scan_get_char(scanner);
 
2209
            pj_scan_get_until_ch( scanner, ')', &hdr->comment);
 
2210
            pj_scan_get_char( scanner );
 
2211
        }
 
2212
 
 
2213
        if (*scanner->curptr != ',')
 
2214
            break;
 
2215
 
 
2216
        pj_scan_get_char(scanner);
 
2217
 
 
2218
    } while (1);
 
2219
 
 
2220
    parse_hdr_end(scanner);
 
2221
 
 
2222
    if (ctx->rdata && ctx->rdata->msg_info.via == NULL)
 
2223
        ctx->rdata->msg_info.via = first;
 
2224
 
 
2225
    return (pjsip_hdr*)first;
 
2226
}
 
2227
 
 
2228
/* Parse generic header. */
 
2229
static pjsip_hdr* parse_hdr_generic_string( pjsip_parse_ctx *ctx )
 
2230
{
 
2231
    pjsip_generic_string_hdr *hdr;
 
2232
 
 
2233
    hdr = pjsip_generic_string_hdr_create(ctx->pool, NULL, NULL);
 
2234
    parse_generic_string_hdr(hdr, ctx);
 
2235
    return (pjsip_hdr*)hdr;
 
2236
 
 
2237
}
 
2238
 
 
2239
/* Public function to parse a header value. */
 
2240
PJ_DEF(void*) pjsip_parse_hdr( pj_pool_t *pool, const pj_str_t *hname,
 
2241
                               char *buf, pj_size_t size, int *parsed_len )
 
2242
{
 
2243
    pj_scanner scanner;
 
2244
    pjsip_hdr *hdr = NULL;
 
2245
    pjsip_parse_ctx context;
 
2246
    PJ_USE_EXCEPTION;
 
2247
 
 
2248
    pj_scan_init(&scanner, buf, size, PJ_SCAN_AUTOSKIP_WS_HEADER, 
 
2249
                 &on_syntax_error);
 
2250
 
 
2251
    context.scanner = &scanner;
 
2252
    context.pool = pool;
 
2253
    context.rdata = NULL;
 
2254
 
 
2255
    PJ_TRY {
 
2256
        pjsip_parse_hdr_func *handler = find_handler(hname);
 
2257
        if (handler) {
 
2258
            hdr = (*handler)(&context);
 
2259
        } else {
 
2260
            hdr = parse_hdr_generic_string(&context);
 
2261
            hdr->type = PJSIP_H_OTHER;
 
2262
            pj_strdup(pool, &hdr->name, hname);
 
2263
            hdr->sname = hdr->name;
 
2264
        }
 
2265
 
 
2266
    } 
 
2267
    PJ_CATCH_ANY {
 
2268
        hdr = NULL;
 
2269
    }
 
2270
    PJ_END
 
2271
 
 
2272
    if (parsed_len) {
 
2273
        *parsed_len = (scanner.curptr - scanner.begin);
 
2274
    }
 
2275
 
 
2276
    pj_scan_fini(&scanner);
 
2277
 
 
2278
    return hdr;
 
2279
}
 
2280
 
 
2281
/* Parse multiple header lines */
 
2282
PJ_DEF(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input,
 
2283
                                         pj_size_t size, pjsip_hdr *hlist,
 
2284
                                         unsigned options)
 
2285
{
 
2286
    enum { STOP_ON_ERROR = 1 };
 
2287
    pj_scanner scanner;
 
2288
    pjsip_parse_ctx ctx;
 
2289
    pj_str_t hname;
 
2290
    PJ_USE_EXCEPTION;
 
2291
 
 
2292
    pj_scan_init(&scanner, input, size, PJ_SCAN_AUTOSKIP_WS_HEADER,
 
2293
                 &on_syntax_error);
 
2294
 
 
2295
    pj_bzero(&ctx, sizeof(ctx));
 
2296
    ctx.scanner = &scanner;
 
2297
    ctx.pool = pool;
 
2298
 
 
2299
retry_parse:
 
2300
    PJ_TRY
 
2301
    {
 
2302
        /* Parse headers. */
 
2303
        do {
 
2304
            pjsip_parse_hdr_func * handler;
 
2305
            pjsip_hdr *hdr = NULL;
 
2306
 
 
2307
            /* Init hname just in case parsing fails.
 
2308
             * Ref: PROTOS #2412
 
2309
             */
 
2310
            hname.slen = 0;
 
2311
 
 
2312
            /* Get hname. */
 
2313
            pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname);
 
2314
            if (pj_scan_get_char( &scanner ) != ':') {
 
2315
                PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
 
2316
            }
 
2317
 
 
2318
            /* Find handler. */
 
2319
            handler = find_handler(&hname);
 
2320
 
 
2321
            /* Call the handler if found.
 
2322
             * If no handler is found, then treat the header as generic
 
2323
             * hname/hvalue pair.
 
2324
             */
 
2325
            if (handler) {
 
2326
                hdr = (*handler)(&ctx);
 
2327
            } else {
 
2328
                hdr = parse_hdr_generic_string(&ctx);
 
2329
                hdr->name = hdr->sname = hname;
 
2330
            }
 
2331
 
 
2332
            /* Single parse of header line can produce multiple headers.
 
2333
             * For example, if one Contact: header contains Contact list
 
2334
             * separated by comma, then these Contacts will be split into
 
2335
             * different Contact headers.
 
2336
             * So here we must insert list instead of just insert one header.
 
2337
             */
 
2338
            if (hdr)
 
2339
                pj_list_insert_nodes_before(hlist, hdr);
 
2340
 
 
2341
            /* Parse until EOF or an empty line is found. */
 
2342
        } while (!pj_scan_is_eof(&scanner) && !IS_NEWLINE(*scanner.curptr));
 
2343
 
 
2344
        /* If empty line is found, eat it. */
 
2345
        if (!pj_scan_is_eof(&scanner)) {
 
2346
            if (IS_NEWLINE(*scanner.curptr)) {
 
2347
                pj_scan_get_newline(&scanner);
 
2348
            }
 
2349
        }
 
2350
    }
 
2351
    PJ_CATCH_ANY
 
2352
    {
 
2353
        PJ_LOG(4,(THIS_FILE, "Error parsing header: '%.*s' line %d col %d",
 
2354
                  (int)hname.slen, hname.ptr, scanner.line,
 
2355
                  pj_scan_get_col(&scanner)));
 
2356
 
 
2357
        /* Exception was thrown during parsing. */
 
2358
        if ((options & STOP_ON_ERROR) == STOP_ON_ERROR) {
 
2359
            pj_scan_fini(&scanner);
 
2360
            return PJSIP_EINVALIDHDR;
 
2361
        }
 
2362
 
 
2363
        /* Skip until newline, and parse next header. */
 
2364
        if (!pj_scan_is_eof(&scanner)) {
 
2365
            /* Skip until next line.
 
2366
             * Watch for header continuation.
 
2367
             */
 
2368
            do {
 
2369
                pj_scan_skip_line(&scanner);
 
2370
            } while (IS_SPACE(*scanner.curptr));
 
2371
        }
 
2372
 
 
2373
        /* Restore flag. Flag may be set in int_parse_sip_url() */
 
2374
        scanner.skip_ws = PJ_SCAN_AUTOSKIP_WS_HEADER;
 
2375
 
 
2376
        /* Continue parse next header, if any. */
 
2377
        if (!pj_scan_is_eof(&scanner) && !IS_NEWLINE(*scanner.curptr)) {
 
2378
            goto retry_parse;
 
2379
        }
 
2380
 
 
2381
    }
 
2382
    PJ_END;
 
2383
 
 
2384
    return PJ_SUCCESS;
 
2385
}
 
2386