1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
Copyright (C) 2005-2009 Michel de Boer <michel@twinklephone.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Parser control
#ifndef _PARSE_CTRL_H
#define _PARSE_CTRL_H
#include "sip_message.h"
#include "threads/mutex.h"
#define MSG t_parser::msg
#define CTXT_INITIAL (t_parser::context = t_parser::X_INITIAL)
#define CTXT_URI (t_parser::context = t_parser::X_URI)
#define CTXT_URI_SPECIAL (t_parser::context = t_parser::X_URI_SPECIAL)
#define CTXT_LANG (t_parser::context = t_parser::X_LANG)
#define CTXT_WORD (t_parser::context = t_parser::X_WORD)
#define CTXT_NUM (t_parser::context = t_parser::X_NUM)
#define CTXT_DATE (t_parser::context = t_parser::X_DATE)
#define CTXT_LINE (t_parser::context = t_parser::X_LINE)
#define CTXT_COMMENT (t_parser::enter_ctx_comment())
#define CTXT_NEW (t_parser::context = t_parser::X_NEW)
#define CTXT_AUTH_SCHEME (t_parser::context = t_parser::X_AUTH_SCHEME)
#define CTXT_IPV6ADDR (t_parser::context = t_parser::X_IPV6ADDR)
#define CTXT_PARAMVAL (t_parser::context = t_parser::X_PARAMVAL)
#define PARSE_ERROR(h) { t_parser::add_header_error(h); CTXT_INITIAL; }
// The t_parser controls the direction of the scanner/parser
// process and it stores the results from the parser.
class t_parser {
private:
/** Mutex to synchronize parse operations */
static t_mutex mtx_parser;
// Level for nested comments
static int comment_level;
// Non-fatal parse errors generated during parsing.
static list<string> parse_errors;
// Unfold SIP headers
static string unfold(const string &h);
public:
enum t_context {
X_INITIAL, // Initial context
X_URI, // URI context where parameters belong to URI
X_URI_SPECIAL, // URI context where parameters belong to SIP header
// if URI is not enclosed by < and >
X_LANG, // Language tag context
X_WORD, // Word context
X_NUM, // Number context
X_DATE, // Date context
X_LINE, // Whole line context
X_COMMENT, // Comment context
X_NEW, // Start of a new SIP message to distinguish
// request from responses
X_AUTH_SCHEME, // Authorization scheme context
X_IPV6ADDR, // IPv6 address context
X_PARAMVAL, // Generic parameter value context
};
// Parser options
// According to RFC3261 the Max-Forwards header is mandatory, but
// many implementations do not send this header.
static bool check_max_forwards;
// Encode headers in compact forom
static bool compact_headers;
// Encode multiple values as comma separated list or multiple headers
static bool multi_values_as_list;
static t_context context; // Scan context
static t_sip_message *msg; // Message that has been parsed
/**
* Parse a string representing a SIP message.
* @param s [in] String to parse.
* @param parse_errors_ [out] List of non-fatal parse errors.
* @return The parsed SIP message.
* @throw int exception when parsing fails.
*/
static t_sip_message *parse(const string &s, list<string> &parse_errors_);
/**
* Parse a string of headers (hdr1=val1;hdr=val2;...)
* The resulting SIP message is a SIP request with a fake request line.
* @param s [in] String to parse.
* @param parse_errors_ [out] List of non-fatal parse errors.
* @return The parsed SIP message.
* @throw int exception when parsing fails.
*/
static t_sip_message *parse_headers(const string &s, list<string> &parse_errors_);
static void enter_ctx_comment(void);
// Increment and decrement levels for nested comments
// dec_comment_level returns false if the level cannot be decremented.
static void inc_comment_level(void);
static bool dec_comment_level(void);
// Add parsing error for a header to the list of parse errors
static void add_header_error(const string &header_name);
};
// Error that can be thrown as exception
class t_syntax_error {
public:
string error;
t_syntax_error(const string &e);
};
#endif
|