- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)
1 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,270 +0,0 @@ |
1 |
-/* |
|
2 |
- * sip first line parsing automaton |
|
3 |
- * |
|
4 |
- * Copyright (C) 2001-2003 FhG Fokus |
|
5 |
- * |
|
6 |
- * This file is part of Kamailio, a free SIP server. |
|
7 |
- * |
|
8 |
- * Kamailio is free software; you can redistribute it and/or modify |
|
9 |
- * it under the terms of the GNU General Public License as published by |
|
10 |
- * the Free Software Foundation; either version 2 of the License, or |
|
11 |
- * (at your option) any later version |
|
12 |
- * |
|
13 |
- * Kamailio is distributed in the hope that it will be useful, |
|
14 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 |
- * GNU General Public License for more details. |
|
17 |
- * |
|
18 |
- * You should have received a copy of the GNU General Public License |
|
19 |
- * along with this program; if not, write to the Free Software |
|
20 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
21 |
- * |
|
22 |
- */ |
|
23 |
- |
|
24 |
-/*! \file |
|
25 |
- * \brief Parser :: SIP first line parsing automaton |
|
26 |
- * |
|
27 |
- * \ingroup parser |
|
28 |
- */ |
|
29 |
- |
|
30 |
- |
|
31 |
-#include "../comp_defs.h" |
|
32 |
-#include "../dprint.h" |
|
33 |
-#include "msg_parser.h" |
|
34 |
-#include "parser_f.h" |
|
35 |
-#include "../mem/mem.h" |
|
36 |
-#include "../ut.h" |
|
37 |
- |
|
38 |
-/* flags for first line |
|
39 |
- * - stored on a short field (16 flags) */ |
|
40 |
-#define FLINE_FLAG_PROTO_SIP (1<<0) |
|
41 |
-#define FLINE_FLAG_PROTO_HTTP (1<<1) |
|
42 |
- |
|
43 |
-int http_reply_parse = 0; |
|
44 |
- |
|
45 |
-/* grammar: |
|
46 |
- request = method SP uri SP version CRLF |
|
47 |
- response = version SP status SP reason CRLF |
|
48 |
- (version = "SIP/2.0") |
|
49 |
-*/ |
|
50 |
- |
|
51 |
- |
|
52 |
-/* parses the first line, returns pointer to next line & fills fl; |
|
53 |
- also modifies buffer (to avoid extra copy ops) */ |
|
54 |
-char* parse_first_line(char* buffer, unsigned int len, struct msg_start* fl) |
|
55 |
-{ |
|
56 |
- |
|
57 |
- char *tmp; |
|
58 |
- char* second; |
|
59 |
- char* third; |
|
60 |
- char* nl; |
|
61 |
- int offset; |
|
62 |
- /* int l; */ |
|
63 |
- char* end; |
|
64 |
- char s1,s2,s3; |
|
65 |
- char *prn; |
|
66 |
- unsigned int t; |
|
67 |
- |
|
68 |
- /* grammar: |
|
69 |
- request = method SP uri SP version CRLF |
|
70 |
- response = version SP status SP reason CRLF |
|
71 |
- (version = "SIP/2.0") |
|
72 |
- */ |
|
73 |
- |
|
74 |
- |
|
75 |
- memset(fl, 0, sizeof(struct msg_start)); |
|
76 |
- offset = 0; |
|
77 |
- end=buffer+len; |
|
78 |
- /* see if it's a reply (status) */ |
|
79 |
- |
|
80 |
- /* jku -- parse well-known methods */ |
|
81 |
- |
|
82 |
- /* drop messages which are so short they are for sure useless; |
|
83 |
- utilize knowledge of minimum size in parsing the first |
|
84 |
- token |
|
85 |
- */ |
|
86 |
- if (len <=16 ) { |
|
87 |
- LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len); |
|
88 |
- goto error1; |
|
89 |
- } |
|
90 |
- tmp=buffer; |
|
91 |
- /* is it perhaps a reply, ie does it start with "SIP...." ? */ |
|
92 |
- if ( (*tmp=='S' || *tmp=='s') && |
|
93 |
- strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 && |
|
94 |
- (*(tmp+SIP_VERSION_LEN)==' ')) { |
|
95 |
- fl->type=SIP_REPLY; |
|
96 |
- fl->flags|=FLINE_FLAG_PROTO_SIP; |
|
97 |
- fl->u.reply.version.len=SIP_VERSION_LEN; |
|
98 |
- tmp=buffer+SIP_VERSION_LEN; |
|
99 |
- } else if (http_reply_parse != 0 && |
|
100 |
- (*tmp=='H' || *tmp=='h') && |
|
101 |
- /* 'HTTP/1.' */ |
|
102 |
- strncasecmp( tmp+1, HTTP_VERSION+1, HTTP_VERSION_LEN-1)==0 && |
|
103 |
- /* [0|1] */ |
|
104 |
- ((*(tmp+HTTP_VERSION_LEN)=='0') || (*(tmp+HTTP_VERSION_LEN)=='1')) && |
|
105 |
- (*(tmp+HTTP_VERSION_LEN+1)==' ') ){ |
|
106 |
- /* ugly hack to be able to route http replies |
|
107 |
- * Note: - the http reply must have a via |
|
108 |
- * - the message is marked as SIP_REPLY (ugly) |
|
109 |
- */ |
|
110 |
- fl->type=SIP_REPLY; |
|
111 |
- fl->flags|=FLINE_FLAG_PROTO_HTTP; |
|
112 |
- fl->u.reply.version.len=HTTP_VERSION_LEN+1 /*include last digit*/; |
|
113 |
- tmp=buffer+HTTP_VERSION_LEN+1 /* last digit */; |
|
114 |
- } else IFISMETHOD( INVITE, 'I' ) |
|
115 |
- else IFISMETHOD( CANCEL, 'C') |
|
116 |
- else IFISMETHOD( ACK, 'A' ) |
|
117 |
- else IFISMETHOD( BYE, 'B' ) |
|
118 |
- else IFISMETHOD( INFO, 'I' ) |
|
119 |
- else IFISMETHOD( REGISTER, 'R') |
|
120 |
- else IFISMETHOD( SUBSCRIBE, 'S') |
|
121 |
- else IFISMETHOD( NOTIFY, 'N') |
|
122 |
- else IFISMETHOD( MESSAGE, 'M') |
|
123 |
- else IFISMETHOD( OPTIONS, 'O') |
|
124 |
- else IFISMETHOD( PRACK, 'P') |
|
125 |
- else IFISMETHOD( UPDATE, 'U') |
|
126 |
- else IFISMETHOD( REFER, 'R') |
|
127 |
- else IFISMETHOD( PUBLISH, 'P') |
|
128 |
- /* if you want to add another method XXX, include METHOD_XXX in |
|
129 |
- H-file (this is the value which you will take later in |
|
130 |
- processing and define XXX_LEN as length of method name; |
|
131 |
- then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first |
|
132 |
- latter; everything must be capitals |
|
133 |
- */ |
|
134 |
- else { |
|
135 |
- /* neither reply, nor any of known method requests, |
|
136 |
- let's believe it is an unknown method request |
|
137 |
- */ |
|
138 |
- tmp=eat_token_end(buffer,buffer+len); |
|
139 |
- if ((tmp==buffer)||(tmp>=end)){ |
|
140 |
- LOG(L_INFO, "ERROR:parse_first_line: empty or bad first line\n"); |
|
141 |
- goto error1; |
|
142 |
- } |
|
143 |
- if (*tmp!=' ') { |
|
144 |
- LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n"); |
|
145 |
- goto error1; |
|
146 |
- } |
|
147 |
- fl->type=SIP_REQUEST; |
|
148 |
- fl->u.request.method_value=METHOD_OTHER; |
|
149 |
- fl->u.request.method.len=tmp-buffer; |
|
150 |
- } |
|
151 |
- |
|
152 |
- |
|
153 |
- /* identifying type of message over now; |
|
154 |
- tmp points at space after; go ahead */ |
|
155 |
- |
|
156 |
- fl->u.request.method.s=buffer; /* store ptr to first token */ |
|
157 |
- second=tmp+1; /* jump to second token */ |
|
158 |
- offset=second-buffer; |
|
159 |
- |
|
160 |
-/* EoJku */ |
|
161 |
- |
|
162 |
- /* next element */ |
|
163 |
- tmp=eat_token_end(second, second+len-offset); |
|
164 |
- if (tmp>=end){ |
|
165 |
- goto error; |
|
166 |
- } |
|
167 |
- offset+=tmp-second; |
|
168 |
- third=eat_space_end(tmp, tmp+len-offset); |
|
169 |
- offset+=third-tmp; |
|
170 |
- if ((third==tmp)||(tmp>=end)){ |
|
171 |
- goto error; |
|
172 |
- } |
|
173 |
- fl->u.request.uri.s=second; |
|
174 |
- fl->u.request.uri.len=tmp-second; |
|
175 |
- |
|
176 |
- /* jku: parse status code */ |
|
177 |
- if (fl->type==SIP_REPLY) { |
|
178 |
- if (fl->u.request.uri.len!=3) { |
|
179 |
- LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %.*s\n", |
|
180 |
- fl->u.request.uri.len, ZSW(second) ); |
|
181 |
- goto error; |
|
182 |
- } |
|
183 |
- s1=*second; s2=*(second+1);s3=*(second+2); |
|
184 |
- if (s1>='0' && s1<='9' && |
|
185 |
- s2>='0' && s2<='9' && |
|
186 |
- s3>='0' && s3<='9' ) { |
|
187 |
- fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0'); |
|
188 |
- } else { |
|
189 |
- LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %.*s\n", |
|
190 |
- fl->u.request.uri.len, ZSW(second) ); |
|
191 |
- goto error; |
|
192 |
- } |
|
193 |
- } |
|
194 |
- /* EoJku */ |
|
195 |
- |
|
196 |
- /* last part: for a request it must be the version, for a reply |
|
197 |
- * it can contain almost anything, including spaces, so we don't care |
|
198 |
- * about it*/ |
|
199 |
- if (fl->type==SIP_REQUEST){ |
|
200 |
- tmp=eat_token_end(third,third+len-offset); |
|
201 |
- offset+=tmp-third; |
|
202 |
- if ((tmp==third)||(tmp>=end)){ |
|
203 |
- goto error; |
|
204 |
- } |
|
205 |
- if (! is_empty_end(tmp, tmp+len-offset)){ |
|
206 |
- goto error; |
|
207 |
- } |
|
208 |
- }else{ |
|
209 |
- tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line |
|
210 |
- ('\n' or '\r') */ |
|
211 |
- if (tmp>=end){ /* no crlf in packet => invalid */ |
|
212 |
- goto error; |
|
213 |
- } |
|
214 |
- offset+=tmp-third; |
|
215 |
- } |
|
216 |
- nl=eat_line(tmp,len-offset); |
|
217 |
- if (nl>=end){ /* no crlf in packet or only 1 line > invalid */ |
|
218 |
- goto error; |
|
219 |
- } |
|
220 |
- fl->u.request.version.s=third; |
|
221 |
- fl->u.request.version.len=tmp-third; |
|
222 |
- fl->len=nl-buffer; |
|
223 |
- |
|
224 |
- if (fl->type==SIP_REQUEST) { |
|
225 |
- if(fl->u.request.version.len >= SIP_VERSION_LEN |
|
226 |
- && (fl->u.request.version.s[0]=='S' |
|
227 |
- || fl->u.request.version.s[0]=='s') |
|
228 |
- && !strncasecmp(fl->u.request.version.s+1, |
|
229 |
- SIP_VERSION+1, SIP_VERSION_LEN-1)) { |
|
230 |
- fl->flags|=FLINE_FLAG_PROTO_SIP; |
|
231 |
- } else if(fl->u.request.version.len >= HTTP_VERSION_LEN |
|
232 |
- && (fl->u.request.version.s[0]=='H' |
|
233 |
- || fl->u.request.version.s[0]=='h') |
|
234 |
- && !strncasecmp(fl->u.request.version.s+1, |
|
235 |
- HTTP_VERSION+1, HTTP_VERSION_LEN-1)) { |
|
236 |
- fl->flags|=FLINE_FLAG_PROTO_HTTP; |
|
237 |
- } |
|
238 |
- } |
|
239 |
- |
|
240 |
- return nl; |
|
241 |
- |
|
242 |
-error: |
|
243 |
- LOG(L_DBG, "parse_first_line: bad %s first line\n", |
|
244 |
- (fl->type==SIP_REPLY)?"reply(status)":"request"); |
|
245 |
- |
|
246 |
- LOG(L_DBG, "at line 0 char %d: \n", offset ); |
|
247 |
- prn=pkg_malloc( offset ); |
|
248 |
- if (prn) { |
|
249 |
- for (t=0; t<offset; t++) |
|
250 |
- if (*(buffer+t)) *(prn+t)=*(buffer+t); |
|
251 |
- else *(prn+t)=176; /* '�' */ |
|
252 |
- LOG(L_DBG, "parsed so far: %.*s\n", offset, ZSW(prn) ); |
|
253 |
- pkg_free( prn ); |
|
254 |
- }; |
|
255 |
-error1: |
|
256 |
- fl->type=SIP_INVALID; |
|
257 |
- LOG(cfg_get(core, core_cfg, corelog), "parse_first_line: bad message (offset: %d)\n", offset); |
|
258 |
- /* skip line */ |
|
259 |
- nl=eat_line(buffer,len); |
|
260 |
- return nl; |
|
261 |
-} |
|
262 |
- |
|
263 |
-char* parse_fline(char* buffer, char* end, struct msg_start* fl) |
|
264 |
-{ |
|
265 |
- if(end<=buffer) { |
|
266 |
- /* make it throw error via parse_first_line() for consistency */ |
|
267 |
- return parse_first_line(buffer, 0, fl); |
|
268 |
- } |
|
269 |
- return parse_first_line(buffer, (unsigned int)(end-buffer), fl); |
|
270 |
-} |
... | ... |
@@ -254,7 +254,7 @@ error: |
254 | 254 |
}; |
255 | 255 |
error1: |
256 | 256 |
fl->type=SIP_INVALID; |
257 |
- LOG(L_ERR, "parse_first_line: bad message (offset: %d)\n", offset); |
|
257 |
+ LOG(cfg_get(core, core_cfg, corelog), "parse_first_line: bad message (offset: %d)\n", offset); |
|
258 | 258 |
/* skip line */ |
259 | 259 |
nl=eat_line(buffer,len); |
260 | 260 |
return nl; |
... | ... |
@@ -3,19 +3,14 @@ |
3 | 3 |
* |
4 | 4 |
* Copyright (C) 2001-2003 FhG Fokus |
5 | 5 |
* |
6 |
- * This file is part of ser, a free SIP server. |
|
6 |
+ * This file is part of Kamailio, a free SIP server. |
|
7 | 7 |
* |
8 |
- * ser is free software; you can redistribute it and/or modify |
|
8 |
+ * Kamailio is free software; you can redistribute it and/or modify |
|
9 | 9 |
* it under the terms of the GNU General Public License as published by |
10 | 10 |
* the Free Software Foundation; either version 2 of the License, or |
11 | 11 |
* (at your option) any later version |
12 | 12 |
* |
13 |
- * For a license to use the ser software under conditions |
|
14 |
- * other than those described here, or to purchase support for this |
|
15 |
- * software, please contact iptel.org by e-mail at the following addresses: |
|
16 |
- * info@iptel.org |
|
17 |
- * |
|
18 |
- * ser is distributed in the hope that it will be useful, |
|
13 |
+ * Kamailio is distributed in the hope that it will be useful, |
|
19 | 14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | 15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | 16 |
* GNU General Public License for more details. |
... | ... |
@@ -24,11 +19,6 @@ |
24 | 19 |
* along with this program; if not, write to the Free Software |
25 | 20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
26 | 21 |
* |
27 |
- * History: |
|
28 |
- * --------- |
|
29 |
- * 2003-02-28 scratchpad compatibility abandoned (jiri) |
|
30 |
- * 2003-01-28: removed 0-terminators from first line (jiri) |
|
31 |
- * 2003-04-26 ZSW (jiri) |
|
32 | 22 |
*/ |
33 | 23 |
|
34 | 24 |
/*! \file |
- initialize to 0 first line struct msg_start_t in parse_first_line()
- split field int type in short type and short flags to be able to store
more info about first line without changes in other places of existing code
- set in flags if the protocol in first line is sip or http - useful to
avoid string comparison whenever needed to get the two very used
protocols
... | ... |
@@ -45,6 +45,11 @@ |
45 | 45 |
#include "../mem/mem.h" |
46 | 46 |
#include "../ut.h" |
47 | 47 |
|
48 |
+/* flags for first line |
|
49 |
+ * - stored on a short field (16 flags) */ |
|
50 |
+#define FLINE_FLAG_PROTO_SIP (1<<0) |
|
51 |
+#define FLINE_FLAG_PROTO_HTTP (1<<1) |
|
52 |
+ |
|
48 | 53 |
int http_reply_parse = 0; |
49 | 54 |
|
50 | 55 |
/* grammar: |
... | ... |
@@ -56,7 +61,7 @@ int http_reply_parse = 0; |
56 | 61 |
|
57 | 62 |
/* parses the first line, returns pointer to next line & fills fl; |
58 | 63 |
also modifies buffer (to avoid extra copy ops) */ |
59 |
-char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
|
64 |
+char* parse_first_line(char* buffer, unsigned int len, struct msg_start* fl) |
|
60 | 65 |
{ |
61 | 66 |
|
62 | 67 |
char *tmp; |
... | ... |
@@ -77,6 +82,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
77 | 82 |
*/ |
78 | 83 |
|
79 | 84 |
|
85 |
+ memset(fl, 0, sizeof(struct msg_start)); |
|
80 | 86 |
offset = 0; |
81 | 87 |
end=buffer+len; |
82 | 88 |
/* see if it's a reply (status) */ |
... | ... |
@@ -97,6 +103,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
97 | 103 |
strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 && |
98 | 104 |
(*(tmp+SIP_VERSION_LEN)==' ')) { |
99 | 105 |
fl->type=SIP_REPLY; |
106 |
+ fl->flags|=FLINE_FLAG_PROTO_SIP; |
|
100 | 107 |
fl->u.reply.version.len=SIP_VERSION_LEN; |
101 | 108 |
tmp=buffer+SIP_VERSION_LEN; |
102 | 109 |
} else if (http_reply_parse != 0 && |
... | ... |
@@ -111,6 +118,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
111 | 118 |
* - the message is marked as SIP_REPLY (ugly) |
112 | 119 |
*/ |
113 | 120 |
fl->type=SIP_REPLY; |
121 |
+ fl->flags|=FLINE_FLAG_PROTO_HTTP; |
|
114 | 122 |
fl->u.reply.version.len=HTTP_VERSION_LEN+1 /*include last digit*/; |
115 | 123 |
tmp=buffer+HTTP_VERSION_LEN+1 /* last digit */; |
116 | 124 |
} else IFISMETHOD( INVITE, 'I' ) |
... | ... |
@@ -223,6 +231,22 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
223 | 231 |
fl->u.request.version.len=tmp-third; |
224 | 232 |
fl->len=nl-buffer; |
225 | 233 |
|
234 |
+ if (fl->type==SIP_REQUEST) { |
|
235 |
+ if(fl->u.request.version.len >= SIP_VERSION_LEN |
|
236 |
+ && (fl->u.request.version.s[0]=='S' |
|
237 |
+ || fl->u.request.version.s[0]=='s') |
|
238 |
+ && !strncasecmp(fl->u.request.version.s+1, |
|
239 |
+ SIP_VERSION+1, SIP_VERSION_LEN-1)) { |
|
240 |
+ fl->flags|=FLINE_FLAG_PROTO_SIP; |
|
241 |
+ } else if(fl->u.request.version.len >= HTTP_VERSION_LEN |
|
242 |
+ && (fl->u.request.version.s[0]=='H' |
|
243 |
+ || fl->u.request.version.s[0]=='h') |
|
244 |
+ && !strncasecmp(fl->u.request.version.s+1, |
|
245 |
+ HTTP_VERSION+1, HTTP_VERSION_LEN-1)) { |
|
246 |
+ fl->flags|=FLINE_FLAG_PROTO_HTTP; |
|
247 |
+ } |
|
248 |
+ } |
|
249 |
+ |
|
226 | 250 |
return nl; |
227 | 251 |
|
228 | 252 |
error: |
... | ... |
@@ -245,3 +269,12 @@ error1: |
245 | 269 |
nl=eat_line(buffer,len); |
246 | 270 |
return nl; |
247 | 271 |
} |
272 |
+ |
|
273 |
+char* parse_fline(char* buffer, char* end, struct msg_start* fl) |
|
274 |
+{ |
|
275 |
+ if(end<=buffer) { |
|
276 |
+ /* make it throw error via parse_first_line() for consistency */ |
|
277 |
+ return parse_first_line(buffer, 0, fl); |
|
278 |
+ } |
|
279 |
+ return parse_first_line(buffer, (unsigned int)(end-buffer), fl); |
|
280 |
+} |
... | ... |
@@ -22,7 +22,7 @@ |
22 | 22 |
* |
23 | 23 |
* You should have received a copy of the GNU General Public License |
24 | 24 |
* along with this program; if not, write to the Free Software |
25 |
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
25 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
26 | 26 |
* |
27 | 27 |
* History: |
28 | 28 |
* --------- |
... | ... |
@@ -77,6 +77,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
77 | 77 |
*/ |
78 | 78 |
|
79 | 79 |
|
80 |
+ offset = 0; |
|
80 | 81 |
end=buffer+len; |
81 | 82 |
/* see if it's a reply (status) */ |
82 | 83 |
|
... | ... |
@@ -239,7 +240,7 @@ error: |
239 | 240 |
}; |
240 | 241 |
error1: |
241 | 242 |
fl->type=SIP_INVALID; |
242 |
- LOG(L_ERR, "parse_first_line: bad message\n"); |
|
243 |
+ LOG(L_ERR, "parse_first_line: bad message (offset: %d)\n", offset); |
|
243 | 244 |
/* skip line */ |
244 | 245 |
nl=eat_line(buffer,len); |
245 | 246 |
return nl; |
- a more relevant name for the core parameter that enables parsing http
replies
... | ... |
@@ -45,7 +45,7 @@ |
45 | 45 |
#include "../mem/mem.h" |
46 | 46 |
#include "../ut.h" |
47 | 47 |
|
48 |
-int http_reply_hack = 0; |
|
48 |
+int http_reply_parse = 0; |
|
49 | 49 |
|
50 | 50 |
/* grammar: |
51 | 51 |
request = method SP uri SP version CRLF |
... | ... |
@@ -98,7 +98,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
98 | 98 |
fl->type=SIP_REPLY; |
99 | 99 |
fl->u.reply.version.len=SIP_VERSION_LEN; |
100 | 100 |
tmp=buffer+SIP_VERSION_LEN; |
101 |
- } else if (http_reply_hack != 0 && |
|
101 |
+ } else if (http_reply_parse != 0 && |
|
102 | 102 |
(*tmp=='H' || *tmp=='h') && |
103 | 103 |
/* 'HTTP/1.' */ |
104 | 104 |
strncasecmp( tmp+1, HTTP_VERSION+1, HTTP_VERSION_LEN-1)==0 && |
... | ... |
@@ -225,21 +225,21 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
225 | 225 |
return nl; |
226 | 226 |
|
227 | 227 |
error: |
228 |
- LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n", |
|
228 |
+ LOG(L_DBG, "parse_first_line: bad %s first line\n", |
|
229 | 229 |
(fl->type==SIP_REPLY)?"reply(status)":"request"); |
230 | 230 |
|
231 |
- LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset ); |
|
231 |
+ LOG(L_DBG, "at line 0 char %d: \n", offset ); |
|
232 | 232 |
prn=pkg_malloc( offset ); |
233 | 233 |
if (prn) { |
234 | 234 |
for (t=0; t<offset; t++) |
235 | 235 |
if (*(buffer+t)) *(prn+t)=*(buffer+t); |
236 | 236 |
else *(prn+t)='�'; |
237 |
- LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, ZSW(prn) ); |
|
237 |
+ LOG(L_DBG, "parsed so far: %.*s\n", offset, ZSW(prn) ); |
|
238 | 238 |
pkg_free( prn ); |
239 | 239 |
}; |
240 | 240 |
error1: |
241 | 241 |
fl->type=SIP_INVALID; |
242 |
- LOG(L_INFO, "ERROR:parse_first_line: bad message\n"); |
|
242 |
+ LOG(L_ERR, "parse_first_line: bad message\n"); |
|
243 | 243 |
/* skip line */ |
244 | 244 |
nl=eat_line(buffer,len); |
245 | 245 |
return nl; |
- By default it is off, to turn it on set http_reply_hack=yes in kamailio.cfg
- You need to turn this on if you use xhttp _and_ event_route[sl:local-response].
This is because HTTP responses are stateless responses and when the
event_route is run it has to parse the response. Without HTTP_REPLY_HACK
Kamailio can't actually parse HTTP responses.
... | ... |
@@ -48,12 +48,7 @@ |
48 | 48 |
#include "../mem/mem.h" |
49 | 49 |
#include "../ut.h" |
50 | 50 |
|
51 |
- |
|
52 |
-#ifdef NO_HTTP_REPLY_HACK |
|
53 |
-#undef HTTP_REPLY_HACK |
|
54 |
-#else |
|
55 |
-/* #define HTTP_REPLY_HACK */ /* allow HTTP replies */ |
|
56 |
-#endif |
|
51 |
+int http_reply_hack = 0; |
|
57 | 52 |
|
58 | 53 |
/* grammar: |
59 | 54 |
request = method SP uri SP version CRLF |
... | ... |
@@ -106,21 +101,20 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
106 | 101 |
fl->type=SIP_REPLY; |
107 | 102 |
fl->u.reply.version.len=SIP_VERSION_LEN; |
108 | 103 |
tmp=buffer+SIP_VERSION_LEN; |
109 |
-#ifdef HTTP_REPLY_HACK |
|
110 |
- }else if ( (*tmp=='H' || *tmp=='h') && |
|
111 |
- /* 'HTTP/1.' */ |
|
112 |
- strncasecmp( tmp+1, HTTP_VERSION+1, HTTP_VERSION_LEN-1)==0 && |
|
113 |
- /* [0|1] */ |
|
114 |
- ((*(tmp+HTTP_VERSION_LEN)=='0') || (*(tmp+HTTP_VERSION_LEN)=='1')) && |
|
115 |
- (*(tmp+HTTP_VERSION_LEN+1)==' ') ){ |
|
116 |
- /* ugly hack to be able to route http replies |
|
117 |
- * Note: - the http reply must have a via |
|
118 |
- * - the message is marked as SIP_REPLY (ugly) |
|
119 |
- */ |
|
120 |
- fl->type=SIP_REPLY; |
|
121 |
- fl->u.reply.version.len=HTTP_VERSION_LEN+1 /*include last digit*/; |
|
122 |
- tmp=buffer+HTTP_VERSION_LEN+1 /* last digit */; |
|
123 |
-#endif |
|
104 |
+ } else if (http_reply_hack != 0 && |
|
105 |
+ (*tmp=='H' || *tmp=='h') && |
|
106 |
+ /* 'HTTP/1.' */ |
|
107 |
+ strncasecmp( tmp+1, HTTP_VERSION+1, HTTP_VERSION_LEN-1)==0 && |
|
108 |
+ /* [0|1] */ |
|
109 |
+ ((*(tmp+HTTP_VERSION_LEN)=='0') || (*(tmp+HTTP_VERSION_LEN)=='1')) && |
|
110 |
+ (*(tmp+HTTP_VERSION_LEN+1)==' ') ){ |
|
111 |
+ /* ugly hack to be able to route http replies |
|
112 |
+ * Note: - the http reply must have a via |
|
113 |
+ * - the message is marked as SIP_REPLY (ugly) |
|
114 |
+ */ |
|
115 |
+ fl->type=SIP_REPLY; |
|
116 |
+ fl->u.reply.version.len=HTTP_VERSION_LEN+1 /*include last digit*/; |
|
117 |
+ tmp=buffer+HTTP_VERSION_LEN+1 /* last digit */; |
|
124 | 118 |
} else IFISMETHOD( INVITE, 'I' ) |
125 | 119 |
else IFISMETHOD( CANCEL, 'C') |
126 | 120 |
else IFISMETHOD( ACK, 'A' ) |
- still duplicity of getting the method - parse_metod() and macro by
parsing first line
... | ... |
@@ -127,6 +127,8 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
127 | 127 |
else IFISMETHOD( OPTIONS, 'O') |
128 | 128 |
else IFISMETHOD( PRACK, 'P') |
129 | 129 |
else IFISMETHOD( UPDATE, 'U') |
130 |
+ else IFISMETHOD( REFER, 'R') |
|
131 |
+ else IFISMETHOD( PUBLISH, 'P') |
|
130 | 132 |
/* if you want to add another method XXX, include METHOD_XXX in |
131 | 133 |
H-file (this is the value which you will take later in |
132 | 134 |
processing and define XXX_LEN as length of method name; |
Signed-off-by: Jan Janak <jan@iptel.org>
... | ... |
@@ -125,6 +125,8 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
125 | 125 |
else IFISMETHOD( NOTIFY, 'N') |
126 | 126 |
else IFISMETHOD( MESSAGE, 'M') |
127 | 127 |
else IFISMETHOD( OPTIONS, 'O') |
128 |
+ else IFISMETHOD( PRACK, 'P') |
|
129 |
+ else IFISMETHOD( UPDATE, 'U') |
|
128 | 130 |
/* if you want to add another method XXX, include METHOD_XXX in |
129 | 131 |
H-file (this is the value which you will take later in |
130 | 132 |
processing and define XXX_LEN as length of method name; |
... | ... |
@@ -123,6 +123,8 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
123 | 123 |
else IFISMETHOD( REGISTER, 'R') |
124 | 124 |
else IFISMETHOD( SUBSCRIBE, 'S') |
125 | 125 |
else IFISMETHOD( NOTIFY, 'N') |
126 |
+ else IFISMETHOD( MESSAGE, 'M') |
|
127 |
+ else IFISMETHOD( OPTIONS, 'O') |
|
126 | 128 |
/* if you want to add another method XXX, include METHOD_XXX in |
127 | 129 |
H-file (this is the value which you will take later in |
128 | 130 |
processing and define XXX_LEN as length of method name; |
(this commit should also fix SER-248)
... | ... |
@@ -92,7 +92,6 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
92 | 92 |
LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len); |
93 | 93 |
goto error1; |
94 | 94 |
} |
95 |
- fl->line.s = buffer; |
|
96 | 95 |
tmp=buffer; |
97 | 96 |
/* is it perhaps a reply, ie does it start with "SIP...." ? */ |
98 | 97 |
if ( (*tmp=='S' || *tmp=='s') && |
... | ... |
@@ -212,7 +211,6 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
212 | 211 |
} |
213 | 212 |
offset+=tmp-third; |
214 | 213 |
} |
215 |
- fl->line.len = tmp-fl->line.s; |
|
216 | 214 |
nl=eat_line(tmp,len-offset); |
217 | 215 |
if (nl>=end){ /* no crlf in packet or only 1 line > invalid */ |
218 | 216 |
goto error; |
... | ... |
@@ -92,7 +92,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
92 | 92 |
LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len); |
93 | 93 |
goto error1; |
94 | 94 |
} |
95 |
- |
|
95 |
+ fl->line.s = buffer; |
|
96 | 96 |
tmp=buffer; |
97 | 97 |
/* is it perhaps a reply, ie does it start with "SIP...." ? */ |
98 | 98 |
if ( (*tmp=='S' || *tmp=='s') && |
... | ... |
@@ -212,6 +212,7 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
212 | 212 |
} |
213 | 213 |
offset+=tmp-third; |
214 | 214 |
} |
215 |
+ fl->line.len = tmp-fl->line.s; |
|
215 | 216 |
nl=eat_line(tmp,len-offset); |
216 | 217 |
if (nl>=end){ /* no crlf in packet or only 1 line > invalid */ |
217 | 218 |
goto error; |
... | ... |
@@ -42,7 +42,12 @@ |
42 | 42 |
#include "../mem/mem.h" |
43 | 43 |
#include "../ut.h" |
44 | 44 |
|
45 |
-#define HTTP_REPLY_HACK /* allow HTTP replies */ |
|
45 |
+ |
|
46 |
+#ifdef NO_HTTP_REPLY_HACK |
|
47 |
+#undef HTTP_REPLY_HACK |
|
48 |
+#else |
|
49 |
+/* #define HTTP_REPLY_HACK */ /* allow HTTP replies */ |
|
50 |
+#endif |
|
46 | 51 |
|
47 | 52 |
/* grammar: |
48 | 53 |
request = method SP uri SP version CRLF |
... | ... |
@@ -96,6 +101,21 @@ char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl) |
96 | 101 |
fl->type=SIP_REPLY; |
97 | 102 |
fl->u.reply.version.len=SIP_VERSION_LEN; |
98 | 103 |
tmp=buffer+SIP_VERSION_LEN; |
104 |
+#ifdef HTTP_REPLY_HACK |
|
105 |
+ }else if ( (*tmp=='H' || *tmp=='h') && |
|
106 |
+ /* 'HTTP/1.' */ |
|
107 |
+ strncasecmp( tmp+1, HTTP_VERSION+1, HTTP_VERSION_LEN-1)==0 && |
|
108 |
+ /* [0|1] */ |
|
109 |
+ ((*(tmp+HTTP_VERSION_LEN)=='0') || (*(tmp+HTTP_VERSION_LEN)=='1')) && |
|
110 |
+ (*(tmp+HTTP_VERSION_LEN+1)==' ') ){ |
|
111 |
+ /* ugly hack to be able to route http replies |
|
112 |
+ * Note: - the http reply must have a via |
|
113 |
+ * - the message is marked as SIP_REPLY (ugly) |
|
114 |
+ */ |
|
115 |
+ fl->type=SIP_REPLY; |
|
116 |
+ fl->u.reply.version.len=HTTP_VERSION_LEN+1 /*include last digit*/; |
|
117 |
+ tmp=buffer+HTTP_VERSION_LEN+1 /* last digit */; |
|
118 |
+#endif |
|
99 | 119 |
} else IFISMETHOD( INVITE, 'I' ) |
100 | 120 |
else IFISMETHOD( CANCEL, 'C') |
101 | 121 |
else IFISMETHOD( ACK, 'A' ) |
... | ... |
@@ -48,1100 +48,6 @@ |
48 | 48 |
(version = "SIP/2.0") |
49 | 49 |
*/ |
50 | 50 |
|
51 |
-/*known methods: INVITE, ACK, CANCEL, BYE*/ |
|
52 |
- |
|
53 |
-enum { START, |
|
54 |
- INVITE1, INVITE2, INVITE3, INVITE4, INVITE5, |
|
55 |
- ACK1, ACK2, |
|
56 |
- CANCEL1, CANCEL2, CANCEL3, CANCEL4, CANCEL5, |
|
57 |
- BYE1, BYE2, |
|
58 |
- SIP1, SIP2, SIP3, SIP4, SIP5, SIP6, |
|
59 |
- FIN_INVITE = 100, FIN_ACK, FIN_CANCEL, FIN_BYE, FIN_SIP, |
|
60 |
- P_METHOD = 200, L_URI, P_URI, L_VER, |
|
61 |
- VER1, VER2, VER3, VER4, VER5, VER6, FIN_VER, |
|
62 |
- L_STATUS, P_STATUS, L_REASON, P_REASON, |
|
63 |
- L_LF, F_CR, F_LF |
|
64 |
-}; |
|
65 |
- |
|
66 |
- |
|
67 |
-#ifdef _CURRENTLY_UNUSED |
|
68 |
-char* parse_fline(char* buffer, char* end, struct msg_start* fl) |
|
69 |
-{ |
|
70 |
- char* tmp; |
|
71 |
- register int state; |
|
72 |
- unsigned short stat; |
|
73 |
- |
|
74 |
- stat=0; |
|
75 |
- fl->type=SIP_REQUEST; |
|
76 |
- state=START; |
|
77 |
- for(tmp=buffer;tmp<end;tmp++){ |
|
78 |
- switch(*tmp){ |
|
79 |
- case ' ': |
|
80 |
- case '\t': |
|
81 |
- switch(state){ |
|
82 |
- case START: /*allow space at the begining, although not |
|
83 |
- legal*/ |
|
84 |
- break; |
|
85 |
- case L_URI: |
|
86 |
- case L_VER: |
|
87 |
- case L_STATUS: |
|
88 |
- case L_REASON: |
|
89 |
- case L_LF: |
|
90 |
- /*eat space*/ |
|
91 |
- break; |
|
92 |
- case FIN_INVITE: |
|
93 |
- *tmp=0; |
|
94 |
- fl->u.request.method.len=tmp-fl->u.request.method.s; |
|
95 |
- fl->u.request.method_value=METHOD_INVITE; |
|
96 |
- state=L_URI; |
|
97 |
- break; |
|
98 |
- case FIN_ACK: |
|
99 |
- *tmp=0; |
|
100 |
- fl->u.request.method.len=tmp-fl->u.request.method.s; |
|
101 |
- fl->u.request.method_value=METHOD_ACK; |
|
102 |
- state=L_URI; |
|
103 |
- break; |
|
104 |
- case FIN_CANCEL: |
|
105 |
- *tmp=0; |
|
106 |
- fl->u.request.method.len=tmp-fl->u.request.method.s; |
|
107 |
- fl->u.request.method_value=METHOD_CANCEL; |
|
108 |
- state=L_URI; |
|
109 |
- break; |
|
110 |
- case FIN_BYE: |
|
111 |
- *tmp=0; |
|
112 |
- fl->u.request.method.len=tmp-fl->u.request.method.s; |
|
113 |
- fl->u.request.method_value=METHOD_BYE; |
|
114 |
- state=L_URI; |
|
115 |
- break; |
|
116 |
- case FIN_SIP: |
|
117 |
- *tmp=0; |
|
118 |
- fl->u.reply.version.len=tmp-fl->u.reply.version.s; |
|
119 |
- state=L_STATUS; |
|
120 |
- fl->type=SIP_REPLY; |
|
121 |
- break; |
|
122 |
- case P_URI: |
|
123 |
- *tmp=0; |
|
124 |
- fl->u.request.uri.len=tmp-fl->u.request.uri.s; |
|
125 |
- state=L_VER; |
|
126 |
- break; |
|
127 |
- case FIN_VER: |
|
128 |
- *tmp=0; |
|
129 |
- fl->u.request.version.len=tmp-fl->u.request.version.s; |
|
130 |
- state=L_LF; |
|
131 |
- break; |
|
132 |
- case P_STATUS: |
|
133 |
- *tmp=0; |
|
134 |
- fl->u.reply.status.len=tmp-fl->u.reply.status.s; |
|
135 |
- state=L_REASON; |
|
136 |
- break; |
|
137 |
- case P_REASON: |
|
138 |
- /* *tmp=0; |
|
139 |
- fl->u.reply.reason.len=tmp-fl->u.reply.reason.s; |
|
140 |
- */ |
|
141 |
- break; |
|
142 |
- case VER1: |
|
143 |
- case VER2: |
|
144 |
- case VER3: |
|
145 |
- case VER4: |
|
146 |
- case VER5: |
|
147 |
- case VER6: |
|
148 |
- LOG(L_ERR, "ERROR: parse_first_line: invalid version " |
|
149 |
- " in request\n"); |
|
150 |
- goto error; |
|
151 |
- case P_METHOD: |
|
152 |
- default: |
|
153 |
- *tmp=0; |
|
154 |
- fl->u.request.method.len=tmp-fl->u.request.method.s; |
|
155 |
- fl->u.request.method_value=METHOD_OTHER; |
|
156 |
- state=L_URI; |
|
157 |
- } |
|
158 |
- break; |
|
159 |
- case 's': |
|
160 |
- case 'S': |
|
161 |
- switch(state){ |
|
162 |
- case START: |
|
163 |
- state=SIP1; |
|
164 |
- fl->u.reply.version.s=tmp; |
|
165 |
- break; |
|
166 |
- case P_URI: |
|
167 |
- case P_REASON: |
|
168 |
- case P_METHOD: |
|
169 |
- break; |
|
170 |
- case L_REASON: |
|
171 |
- fl->u.reply.reason.s=tmp; |
|
172 |
- state=P_REASON; |
|
173 |
- break; |
|
174 |
- case P_STATUS: |
|
175 |
- case L_STATUS: |
|
176 |
- LOG(L_ERR, "ERROR: parse_first_line: non-number " |
|
177 |
- "character <%c> in request status\n", *tmp); |
|
178 |
- goto error; |
|
179 |
- case L_LF: |
|
180 |
- LOG(L_ERR, "ERROR: parse_first_line: invalid " |
|
181 |
- "character <%c> in request\n", *tmp); |
|
182 |
- goto error; |
|
183 |
- case L_URI: |
|
184 |
- fl->u.request.uri.s=tmp; |
|
185 |
- state=P_URI; |
|
186 |
- break; |
|
187 |
- case L_VER: |
|
188 |
- fl->u.request.version.s=tmp; |
|
189 |
- state=VER1; |
|
190 |
- break; |
|
191 |
- case VER1: |
|
192 |
- case VER2: |
|
193 |
- case VER3: |
|
194 |
- case VER4: |
|
195 |
- case VER5: |
|
196 |
- case VER6: |
|
197 |
- case FIN_VER: |
|
198 |
- LOG(L_ERR, "ERROR: parse_first_line: invalid version " |
|
199 |
- " in request\n"); |
|
200 |
- goto error; |
|
201 |
- default: |
|
202 |
- state=P_METHOD; |
|
203 |
- } |
|
204 |
- break; |
|
205 |
- |
|
206 |
- case 'i': |
|
207 |
- case 'I': |
|
208 |
- switch(state){ |
|
209 |
- case START: |
|
210 |
- state=INVITE1; |
|
211 |
- fl->u.request.method.s=tmp; |
|
212 |
- break; |
|
213 |
- case INVITE3: |
|
214 |
- state=INVITE4; |
|
215 |
- break; |
|
216 |
- case SIP1: |
|
217 |
- state=SIP2; |
|
218 |
- break; |
|
219 |
- case P_URI: |
|
220 |
- case P_REASON: |
|
221 |
- case P_METHOD: |
|
222 |
- break; |
|
223 |
- case L_REASON: |
|
224 |
- fl->u.reply.reason.s=tmp; |
|
225 |
- state=P_REASON; |
|
226 |
- break; |
|
227 |
- case P_STATUS: |
|
228 |
- case L_STATUS: |
|
229 |
- LOG(L_ERR, "ERROR: parse_first_line: non-number " |
|
230 |
- "character <%c> in request status\n", *tmp); |
|
231 |
- goto error; |
|
232 |
- case L_LF: |
|
233 |
- LOG(L_ERR, "ERROR: parse_first_line: invalid " |
|
234 |
- "character <%c> in request\n", *tmp); |
|
235 |
- goto error; |
|
236 |
- case L_URI: |
|
237 |
- fl->u.request.uri.s=tmp; |
|
238 |
- state=P_URI; |
|
239 |
- break; |
|
240 |
- case VER1: |
|
241 |
- state=VER2; |
|
242 |
- break; |
|
243 |
- case L_VER: |
|
244 |
- case VER2: |
|
245 |
- case VER3: |
|
246 |
- case VER4: |
|
247 |
- case VER5: |
|
248 |
- case VER6: |
|
249 |
- case FIN_VER: |
|
250 |
- LOG(L_ERR, "ERROR: parse_first_line: invalid version " |
|
251 |
- " in request\n"); |
|
252 |
- goto error; |
|
253 |
- default: |
|
254 |
- state=P_METHOD; |
|
255 |
- } |
|
256 |
- break; |
|
257 |
- |
|
258 |
- case 'p': |
|
259 |
- case 'P': |
|
260 |
- switch(state){ |
|
261 |
- case START: |
|
262 |
- state=P_METHOD; |
|
263 |
- fl->u.request.method.s=tmp; |
|
264 |
- break; |
|
265 |
- case SIP2: |
|
266 |
- state=SIP3; |
|
267 |
- break; |
|
268 |
- case P_URI: |
|
269 |
- case P_REASON: |
|
270 |
- case P_METHOD: |
|
271 |
- break; |
|
272 |
- case L_REASON: |
|
273 |
- fl->u.reply.reason.s=tmp; |
|
274 |
- state=P_REASON; |
|
275 |
- break; |
|
276 |
- case P_STATUS: |
|
277 |
- case L_STATUS: |
|
278 |
- LOG(L_ERR, "ERROR: parse_first_line: non-number " |
|
279 |
- "character <%c> in request status\n", *tmp); |
|
280 |
- goto error; |
|
281 |
- case L_LF: |