1 /*
2 belle-sip - SIP (RFC3261) library.
3 Copyright (C) 2010 Belledonne Communications SARL
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "grammars/belle_sip_messageLexer.h"
19 #include "grammars/belle_sip_messageParser.h"
20
21 #include "belle_sip_internal.h"
22
23
24 typedef struct _headers_container {
25 char* name;
26 belle_sip_list_t* header_list;
27 } headers_container_t;
28
29 /*reference is
30 * http://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-2
31 */
expand_name(const char * name)32 static const char * expand_name(const char *name){
33 const char *full_name=NULL;
34
35 if (strlen(name)>1) return name;
36 switch(name[0]){
37 case 'a':
38 full_name="Accept-Contact";
39 break;
40 case 'u':
41 full_name="Allow-Events";
42 break;
43 case 'e':
44 full_name="Content-Encoding";
45 break;
46 case 'o':
47 full_name="Event";
48 break;
49 case 'y':
50 full_name="Identity";
51 break;
52 case 'n':
53 full_name="Identity-Info";
54 break;
55 case 'r':
56 full_name="Refer-To";
57 break;
58 case 'b':
59 full_name="Referred-By";
60 break;
61 case 'j':
62 full_name="Reject-Contact";
63 break;
64 case 'd':
65 full_name="Request-Disposition";
66 break;
67 case 'x':
68 full_name="Session-Expires";
69 break;
70 case 's':
71 full_name="Subject";
72 break;
73 case 'k':
74 full_name="Supported";
75 break;
76 default:
77 full_name=name;
78 }
79 return full_name;
80 }
81
belle_sip_message_headers_container_new(const char * name)82 static headers_container_t* belle_sip_message_headers_container_new(const char* name) {
83 headers_container_t* headers_container = belle_sip_new0(headers_container_t);
84 headers_container->name = belle_sip_strdup(expand_name(name));
85 return headers_container;
86 }
87
belle_sip_headers_container_delete(headers_container_t * obj)88 static void belle_sip_headers_container_delete(headers_container_t *obj){
89 belle_sip_free(obj->name);
90 belle_sip_list_free_with_data(obj->header_list,(void (*)(void*))belle_sip_object_unref);
91 belle_sip_free(obj);
92 }
93
belle_sip_message_destroy(belle_sip_message_t * msg)94 static void belle_sip_message_destroy(belle_sip_message_t *msg){
95 belle_sip_list_free_with_data(msg->header_list,(void (*)(void*))belle_sip_headers_container_delete);
96 if (msg->body_handler)
97 belle_sip_object_unref(msg->body_handler);
98 }
99
100 /*very sub-optimal clone method */
belle_sip_message_clone(belle_sip_message_t * obj,const belle_sip_message_t * orig)101 static void belle_sip_message_clone(belle_sip_message_t *obj, const belle_sip_message_t *orig){
102 headers_container_t *c;
103 const belle_sip_list_t *l;
104 for(l=orig->header_list;l!=NULL;l=l->next){
105 c=(headers_container_t*)l->data;
106 if (c->header_list){
107 belle_sip_list_t * ll=belle_sip_list_copy_with_data(c->header_list,(void *(*)(void*))belle_sip_object_clone);
108 belle_sip_message_add_headers(obj,ll);
109 belle_sip_list_free(ll);
110 }
111 }
112 }
113
114 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_message_t);
115
116 BELLE_SIP_INSTANCIATE_VPTR(belle_sip_message_t,belle_sip_object_t,belle_sip_message_destroy,belle_sip_message_clone,NULL,TRUE);
117
belle_sip_message_parse(const char * value)118 belle_sip_message_t* belle_sip_message_parse (const char* value) {
119 size_t message_length;
120 return belle_sip_message_parse_raw(value,strlen(value),&message_length);
121 }
122
belle_sip_message_parse_raw(const char * buff,size_t buff_length,size_t * message_length)123 belle_sip_message_t* belle_sip_message_parse_raw (const char* buff, size_t buff_length,size_t* message_length ) { \
124 pANTLR3_INPUT_STREAM input;
125 pbelle_sip_messageLexer lex;
126 pANTLR3_COMMON_TOKEN_STREAM tokens;
127 pbelle_sip_messageParser parser;
128 belle_sip_message_t* l_parsed_object;
129 input = ANTLR_STREAM_NEW("message",buff,buff_length);
130 lex = belle_sip_messageLexerNew (input);
131 tokens = antlr3CommonTokenStreamSourceNew (1025, lex->pLexer->rec->state->tokSource);
132 parser = belle_sip_messageParserNew (tokens);
133 l_parsed_object = parser->message_raw(parser,message_length);
134 /* if (*message_length < buff_length) {*/
135 /*there is a body*/
136 /* l_parsed_object->body_length=buff_length-*message_length;
137 l_parsed_object->body = belle_sip_malloc(l_parsed_object->body_length+1);
138 memcpy(l_parsed_object->body,buff+*message_length,l_parsed_object->body_length);
139 l_parsed_object->body[l_parsed_object->body_length]='\0';
140 }*/
141 parser ->free(parser);
142 tokens ->free(tokens);
143 lex ->free(lex);
144 input ->close(input);
145 return l_parsed_object;
146 }
147
belle_sip_headers_container_comp_func(const headers_container_t * a,const char * b)148 static int belle_sip_headers_container_comp_func(const headers_container_t *a, const char*b) {
149 return strcasecmp(a->name,b);
150 }
151
belle_sip_message_init(belle_sip_message_t * message)152 void belle_sip_message_init(belle_sip_message_t *message){
153
154 }
155
belle_sip_headers_container_get(const belle_sip_message_t * message,const char * header_name)156 headers_container_t* belle_sip_headers_container_get(const belle_sip_message_t* message,const char* header_name) {
157 belle_sip_list_t * result = belle_sip_list_find_custom( message->header_list
158 , (belle_sip_compare_func)belle_sip_headers_container_comp_func
159 , header_name);
160 return result?(headers_container_t*)(result->data):NULL;
161 }
162
get_or_create_container(belle_sip_message_t * message,const char * header_name)163 headers_container_t * get_or_create_container(belle_sip_message_t *message, const char *header_name){
164 // first check if already exist
165 headers_container_t* headers_container = belle_sip_headers_container_get(message,header_name);
166 if (headers_container == NULL) {
167 headers_container = belle_sip_message_headers_container_new(header_name);
168 message->header_list=belle_sip_list_append(message->header_list,headers_container);
169 }
170 return headers_container;
171 }
172
belle_sip_message_add_first(belle_sip_message_t * message,belle_sip_header_t * header)173 void belle_sip_message_add_first(belle_sip_message_t *message,belle_sip_header_t* header) {
174 headers_container_t *headers_container=get_or_create_container(message,belle_sip_header_get_name(header));
175 headers_container->header_list=belle_sip_list_prepend(headers_container->header_list,belle_sip_object_ref(header));
176 }
177
belle_sip_message_add_header(belle_sip_message_t * message,belle_sip_header_t * header)178 void belle_sip_message_add_header(belle_sip_message_t *message,belle_sip_header_t* header) {
179 headers_container_t *headers_container=get_or_create_container(message,belle_sip_header_get_name(header));
180 headers_container->header_list=belle_sip_list_append(headers_container->header_list,belle_sip_object_ref(header));
181 }
182
belle_sip_message_add_headers(belle_sip_message_t * message,const belle_sip_list_t * header_list)183 void belle_sip_message_add_headers(belle_sip_message_t *message, const belle_sip_list_t *header_list){
184 const char *hname;
185 headers_container_t *headers_container;
186
187 if (header_list == NULL) return;
188
189 hname=belle_sip_header_get_name(BELLE_SIP_HEADER((header_list->data)));
190 headers_container=get_or_create_container(message,hname);
191
192 for(;header_list!=NULL;header_list=header_list->next){
193 belle_sip_header_t *h=BELLE_SIP_HEADER(header_list->data);
194 if (strcmp(belle_sip_header_get_name(h),hname)!=0){
195 belle_sip_fatal("Bad use of belle_sip_message_add_headers(): all headers of the list must be of the same type.");
196 return ;
197 }
198 headers_container->header_list=belle_sip_list_append(headers_container->header_list,belle_sip_object_ref(h));
199 }
200 }
201
belle_sip_message_set_header(belle_sip_message_t * msg,belle_sip_header_t * header)202 void belle_sip_message_set_header(belle_sip_message_t *msg, belle_sip_header_t* header){
203 headers_container_t *headers_container=get_or_create_container(msg,belle_sip_header_get_name(header));
204 belle_sip_object_ref(header);
205 headers_container->header_list=belle_sip_list_free_with_data(headers_container->header_list,belle_sip_object_unref);
206 headers_container->header_list=belle_sip_list_append(headers_container->header_list,header);
207 }
208
belle_sip_message_get_headers(const belle_sip_message_t * message,const char * header_name)209 const belle_sip_list_t* belle_sip_message_get_headers(const belle_sip_message_t *message,const char* header_name) {
210 headers_container_t* headers_container = belle_sip_headers_container_get(message,header_name);
211 return headers_container ? headers_container->header_list:NULL;
212 }
213
_belle_sip_message_get_header_by_type_id(const belle_sip_message_t * message,belle_sip_type_id_t id)214 belle_sip_object_t *_belle_sip_message_get_header_by_type_id(const belle_sip_message_t *message, belle_sip_type_id_t id){
215 const belle_sip_list_t *e1;
216 for(e1=message->header_list;e1!=NULL;e1=e1->next){
217 headers_container_t* headers_container=(headers_container_t*)e1->data;
218 if (headers_container->header_list){
219 belle_sip_object_t *ret=headers_container->header_list->data;
220 if (ret->vptr->id==id) return ret;
221 }
222 }
223 return NULL;
224 }
225
belle_sip_message_remove_first(belle_sip_message_t * msg,const char * header_name)226 void belle_sip_message_remove_first(belle_sip_message_t *msg, const char *header_name){
227 headers_container_t* headers_container = belle_sip_headers_container_get(msg,header_name);
228 if (headers_container && headers_container->header_list){
229 belle_sip_list_t *to_be_removed=headers_container->header_list;
230 headers_container->header_list=belle_sip_list_remove_link(headers_container->header_list,to_be_removed);
231 belle_sip_list_free_with_data(to_be_removed,belle_sip_object_unref);
232 }
233 }
234
belle_sip_message_remove_last(belle_sip_message_t * msg,const char * header_name)235 void belle_sip_message_remove_last(belle_sip_message_t *msg, const char *header_name){
236 headers_container_t* headers_container = belle_sip_headers_container_get(msg,header_name);
237 if (headers_container && headers_container->header_list){
238 belle_sip_list_t *to_be_removed=belle_sip_list_last_elem(headers_container->header_list);
239 headers_container->header_list=belle_sip_list_remove_link(headers_container->header_list,to_be_removed);
240 belle_sip_list_free_with_data(to_be_removed,belle_sip_object_unref);
241 }
242 }
243
belle_sip_message_remove_header(belle_sip_message_t * msg,const char * header_name)244 void belle_sip_message_remove_header(belle_sip_message_t *msg, const char *header_name){
245 headers_container_t* headers_container = belle_sip_headers_container_get(msg,header_name);
246 if (headers_container){
247 msg->header_list = belle_sip_list_remove(msg->header_list,headers_container);
248 belle_sip_headers_container_delete(headers_container);
249 }
250 }
belle_sip_message_remove_header_from_ptr(belle_sip_message_t * msg,belle_sip_header_t * header)251 void belle_sip_message_remove_header_from_ptr(belle_sip_message_t *msg, belle_sip_header_t* header) {
252 headers_container_t* headers_container = belle_sip_headers_container_get(msg,belle_sip_header_get_name(header));
253 belle_sip_list_t* it;
254 it=belle_sip_list_find(headers_container->header_list,header);
255 if (it) {
256 belle_sip_object_unref(header);
257 headers_container->header_list=belle_sip_list_delete_link(headers_container->header_list,it);
258 if (belle_sip_list_size(headers_container->header_list) == 0) {
259 msg->header_list = belle_sip_list_remove(msg->header_list,headers_container);
260 belle_sip_headers_container_delete(headers_container);
261 }
262 }
263 }
264 /*
265 belle_sip_error_code belle_sip_message_named_headers_marshal(belle_sip_message_t *message, const char* header_name, char* buff, size_t buff_size, size_t *offset) {
266 belle_sip_error_code error=BELLE_SIP_OK;
267 belle_sip_list_t* header_list = belle_sip_message_get_headers(message,header_name);
268 if (!header_list) {
269 belle_sip_error("headers [%s] not found",header_name);
270 return 0;
271 }
272 for(;header_list!=NULL;header_list=header_list->next){
273 belle_sip_header_t *h=BELLE_SIP_HEADER(header_list->data);
274 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(h),buff,buff_size,offset);
275 if (error!=BELLE_SIP_OK) return error;
276 error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
277 if (error!=BELLE_SIP_OK) return error;
278 }
279 return error;
280 }
281
282 #define MARSHAL_AND_CHECK_HEADER(header) \
283 if (current_offset == (current_offset+=(header))) {\
284 belle_sip_error("missing mandatory header");\
285 return current_offset;\
286 } else {\
287 current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s","\r\n");\
288 }
289 */
290 typedef void (*each_header_cb)(const belle_sip_header_t* header,void* userdata);
291
belle_sip_message_for_each_header(const belle_sip_message_t * message,each_header_cb cb,void * user_data)292 static void belle_sip_message_for_each_header(const belle_sip_message_t *message,each_header_cb cb,void* user_data) {
293 belle_sip_list_t* headers_list;
294 belle_sip_list_t* header_list;
295 for(headers_list=message->header_list;headers_list!=NULL;headers_list=headers_list->next){
296 for(header_list=((headers_container_t*)(headers_list->data))->header_list
297 ;header_list!=NULL
298 ;header_list=header_list->next) {
299 cb(BELLE_SIP_HEADER(header_list->data),user_data);
300 }
301 }
302 return;
303 }
append_header(const belle_sip_header_t * header,void * user_data)304 static void append_header(const belle_sip_header_t* header,void* user_data) {
305 *(belle_sip_list_t**)user_data=belle_sip_list_append((*(belle_sip_list_t**)user_data),(void*)header);
306 }
307
belle_sip_message_get_all_headers(const belle_sip_message_t * message)308 belle_sip_list_t* belle_sip_message_get_all_headers(const belle_sip_message_t *message) {
309 belle_sip_list_t* headers=NULL;
310 belle_sip_message_for_each_header(message,append_header,&headers);
311 return headers;
312 }
313
belle_sip_headers_marshal(belle_sip_message_t * message,char * buff,size_t buff_size,size_t * offset)314 belle_sip_error_code belle_sip_headers_marshal(belle_sip_message_t *message, char* buff, size_t buff_size, size_t *offset) {
315 /*FIXME, replace this code by belle_sip_message_for_each_header*/
316 belle_sip_list_t* headers_list;
317 belle_sip_list_t* header_list;
318 belle_sip_error_code error=BELLE_SIP_OK;
319 #ifdef BELLE_SIP_WORKAROUND_TECHNICOLOR_SIP_ALG_ROUTER_BUG
320 belle_sip_header_t *content_length=NULL;
321 #endif
322
323 for(headers_list=message->header_list;headers_list!=NULL;headers_list=headers_list->next){
324 for(header_list=((headers_container_t*)(headers_list->data))->header_list
325 ;header_list!=NULL
326 ;header_list=header_list->next) {
327 belle_sip_header_t *h=BELLE_SIP_HEADER(header_list->data);
328 #ifdef BELLE_SIP_WORKAROUND_TECHNICOLOR_SIP_ALG_ROUTER_BUG
329 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(h,belle_sip_header_content_length_t)){
330 content_length=h;
331 }else
332 #endif
333 {
334 while (h!=NULL) { /*header can be chained*/
335 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(h),buff,buff_size,offset);
336 if (error!=BELLE_SIP_OK) return error;
337 error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
338 if (error!=BELLE_SIP_OK) return error;
339 h= belle_sip_header_get_next(h);
340 }
341 }
342 }
343 }
344 #ifdef BELLE_SIP_WORKAROUND_TECHNICOLOR_SIP_ALG_ROUTER_BUG
345 if (content_length){
346 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(content_length),buff,buff_size,offset);
347 if (error!=BELLE_SIP_OK) return error;
348 error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
349 if (error!=BELLE_SIP_OK) return error;
350 }
351 #endif
352 error=belle_sip_snprintf(buff,buff_size,offset,"%s","\r\n");
353 if (error!=BELLE_SIP_OK) return error;
354 return error;
355 }
356
belle_sip_request_destroy(belle_sip_request_t * request)357 static void belle_sip_request_destroy(belle_sip_request_t* request) {
358 if (request->method) belle_sip_free(request->method);
359 if (request->uri) belle_sip_object_unref(request->uri);
360 if (request->absolute_uri) belle_sip_object_unref(request->absolute_uri);
361 if (request->dialog) belle_sip_object_unref(request->dialog);
362 if (request->rfc2543_branch) belle_sip_free(request->rfc2543_branch);
363 }
364
belle_sip_request_init(belle_sip_request_t * message)365 static void belle_sip_request_init(belle_sip_request_t *message){
366 }
367
belle_sip_request_clone(belle_sip_request_t * request,const belle_sip_request_t * orig)368 static void belle_sip_request_clone(belle_sip_request_t *request, const belle_sip_request_t *orig){
369 if (orig->method) request->method=belle_sip_strdup(orig->method);
370 if (orig->uri) request->uri=(belle_sip_uri_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)orig->uri));
371 if (orig->absolute_uri) request->absolute_uri=(belle_generic_uri_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)orig->absolute_uri));
372 if (orig->rfc2543_branch) request->rfc2543_branch=belle_sip_strdup(orig->rfc2543_branch);
373 }
374
belle_sip_request_marshal(belle_sip_request_t * request,char * buff,size_t buff_size,size_t * offset)375 belle_sip_error_code belle_sip_request_marshal(belle_sip_request_t* request, char* buff, size_t buff_size, size_t *offset) {
376 belle_sip_error_code error=belle_sip_snprintf(buff,buff_size,offset,"%s ",belle_sip_request_get_method(request) ? belle_sip_request_get_method(request) : "");
377
378 if (error!=BELLE_SIP_OK) return error;
379 if (request->uri)
380 error=belle_sip_uri_marshal(belle_sip_request_get_uri(request),buff,buff_size,offset);
381 else if (request->absolute_uri)
382 error=belle_generic_uri_marshal(belle_sip_request_get_absolute_uri(request),buff,buff_size,offset);
383 else {
384 belle_sip_error("Missing uri for marshaling request [%p]",request);
385 /*fixme better to have an error code*/
386 error=BELLE_SIP_OK;
387 }
388
389 if (error!=BELLE_SIP_OK) return error;
390 error=belle_sip_snprintf(buff,buff_size,offset," %s","SIP/2.0\r\n");
391 if (error!=BELLE_SIP_OK) return error;
392 error=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(request),buff,buff_size,offset);
393 if (error!=BELLE_SIP_OK) return error;
394
395 return error;
396 }
397
398 BELLE_SIP_NEW(request,message)
399 BELLE_SIP_PARSE(request)
400 GET_SET_STRING(belle_sip_request,method);
401 GET_SET_STRING(belle_sip_request,rfc2543_branch);
402
403 /*caching of the dialog in the request, used when creating a request in dialog to avoid dialog lookup*/
belle_sip_request_set_dialog(belle_sip_request_t * req,belle_sip_dialog_t * dialog)404 void belle_sip_request_set_dialog(belle_sip_request_t *req, belle_sip_dialog_t *dialog){
405 SET_OBJECT_PROPERTY(req,dialog,dialog);
406 }
407
belle_sip_request_set_uri(belle_sip_request_t * request,belle_sip_uri_t * uri)408 void belle_sip_request_set_uri(belle_sip_request_t* request,belle_sip_uri_t* uri) {
409 SET_OBJECT_PROPERTY(request,uri,uri);
410 if (request->absolute_uri && uri) {
411 belle_sip_warning("absolute uri [%p] already set for request [%p], cleaning it",request->absolute_uri, request);
412 belle_sip_request_set_absolute_uri(request,NULL);
413 }
414 }
415
belle_sip_request_get_uri(const belle_sip_request_t * request)416 belle_sip_uri_t * belle_sip_request_get_uri(const belle_sip_request_t *request){
417 return request->uri;
418 }
419
belle_sip_request_set_absolute_uri(belle_sip_request_t * request,belle_generic_uri_t * absolute_uri)420 void belle_sip_request_set_absolute_uri(belle_sip_request_t* request,belle_generic_uri_t* absolute_uri) {
421 SET_OBJECT_PROPERTY(request,absolute_uri,absolute_uri);
422 if (request->uri && absolute_uri) {
423 belle_sip_warning("sip uri [%p] already set for request [%p], cleaning it",request->uri, request);
424 belle_sip_request_set_uri(request,NULL);
425 }
426 }
427
belle_sip_request_get_absolute_uri(const belle_sip_request_t * request)428 belle_generic_uri_t * belle_sip_request_get_absolute_uri(const belle_sip_request_t *request){
429 return request->absolute_uri;
430 }
431
432
belle_sip_request_extract_origin(const belle_sip_request_t * req)433 belle_sip_uri_t* belle_sip_request_extract_origin(const belle_sip_request_t* req) {
434 belle_sip_header_via_t* via_header = belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
435 belle_sip_uri_t* uri=NULL;
436 const char* received = belle_sip_header_via_get_received(via_header);
437 int rport = belle_sip_header_via_get_rport(via_header);
438 uri = belle_sip_uri_new();
439 if (received!=NULL) {
440 belle_sip_uri_set_host(uri,received);
441 } else {
442 belle_sip_uri_set_host(uri,belle_sip_header_via_get_host(via_header));
443 }
444 if (rport>0) {
445 belle_sip_uri_set_port(uri,rport);
446 } else if (belle_sip_header_via_get_port(via_header)) {
447 belle_sip_uri_set_port(uri,belle_sip_header_via_get_port(via_header));
448 }
449 if (belle_sip_header_via_get_transport(via_header)) {
450 belle_sip_uri_set_transport_param(uri,belle_sip_header_via_get_transport_lowercase(via_header));
451 }
452 return uri;
453 }
454
belle_sip_message_is_request(belle_sip_message_t * msg)455 int belle_sip_message_is_request(belle_sip_message_t *msg){
456 return BELLE_SIP_IS_INSTANCE_OF(BELLE_SIP_OBJECT(msg),belle_sip_request_t);
457 }
458
belle_sip_message_is_response(const belle_sip_message_t * msg)459 int belle_sip_message_is_response(const belle_sip_message_t *msg){
460 return BELLE_SIP_IS_INSTANCE_OF(BELLE_SIP_OBJECT(msg),belle_sip_response_t);
461 }
462
belle_sip_message_get_header(const belle_sip_message_t * msg,const char * header_name)463 belle_sip_header_t *belle_sip_message_get_header(const belle_sip_message_t *msg, const char *header_name){
464 const belle_sip_list_t *l=belle_sip_message_get_headers(msg,header_name);
465 if (l!=NULL)
466 return (belle_sip_header_t*)l->data;
467 return NULL;
468 }
469
belle_sip_message_to_string(belle_sip_message_t * msg)470 char *belle_sip_message_to_string(belle_sip_message_t *msg){
471 return belle_sip_object_to_string(BELLE_SIP_OBJECT(msg));
472 }
473
belle_sip_message_get_body_handler(const belle_sip_message_t * msg)474 belle_sip_body_handler_t *belle_sip_message_get_body_handler(const belle_sip_message_t *msg){
475 return msg->body_handler;
476 }
477
belle_sip_message_set_body_handler(belle_sip_message_t * msg,belle_sip_body_handler_t * body_handler)478 void belle_sip_message_set_body_handler(belle_sip_message_t *msg, belle_sip_body_handler_t *body_handler){
479 belle_sip_header_content_length_t *content_length_header = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_length_t);
480 belle_sip_header_content_type_t *content_type_header = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
481
482 /* In case of multipart message, we must add the message Content-Type header containing the boundary */
483 if (body_handler != NULL) {
484 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(body_handler, belle_sip_multipart_body_handler_t)){
485 belle_sip_multipart_body_handler_t *multipart_body_handler = BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler);
486 belle_sip_header_content_type_t * content_type = belle_sip_header_content_type_new();
487 belle_sip_header_content_type_set_type(content_type, "multipart");
488 if (belle_sip_multipart_body_handler_is_related(multipart_body_handler)) {
489 const belle_sip_list_t *parts = belle_sip_multipart_body_handler_get_parts(multipart_body_handler);
490 if (parts) {
491 belle_sip_body_handler_t *first_part=BELLE_SIP_BODY_HANDLER(parts->data);
492 const belle_sip_list_t *first_part_headers = belle_sip_body_handler_get_headers(first_part);
493 belle_sip_list_t *it;
494 belle_sip_header_content_type_t *first_part_content_type=NULL;;
495 for(it = (belle_sip_list_t *)first_part_headers;it!=NULL;it=it->next) {
496 belle_sip_header_t *header = BELLE_SIP_HEADER(it->data);
497 if(strcasecmp("Content-Type",belle_sip_header_get_name(header)) == 0) {
498 first_part_content_type=BELLE_SIP_HEADER_CONTENT_TYPE(header);
499 break;
500 }
501 }
502 if (first_part_content_type) {
503 char *type_slash_subtype = belle_sip_strdup_printf("%s/%s"
504 , belle_sip_header_content_type_get_type(first_part_content_type)
505 , belle_sip_header_content_type_get_subtype(first_part_content_type));
506 belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(content_type), "type", type_slash_subtype);
507 belle_sip_free(type_slash_subtype);
508 } else {
509 belle_sip_error("Multipart related body handler [%p] cannot be set without first part content type header",body_handler);
510 }
511 } else {
512 belle_sip_error("Multipart related body handler [%p] cannot be set without first part",body_handler);
513 }
514 belle_sip_header_content_type_set_subtype(content_type, "related");
515
516 } else {
517 belle_sip_header_content_type_set_subtype(content_type, "form-data");
518 }
519 belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(content_type), "boundary", BELLESIP_MULTIPART_BOUNDARY);
520 belle_sip_message_add_header(BELLE_SIP_MESSAGE(msg), BELLE_SIP_HEADER(content_type));
521 } else {
522 const belle_sip_list_t *headers = belle_sip_body_handler_get_headers(body_handler);
523 for(; headers != NULL; headers = headers->next) {
524 belle_sip_header_t *header = BELLE_SIP_HEADER(headers->data);
525 if (strcasecmp(belle_sip_header_get_name(header),BELLE_SIP_CONTENT_LENGTH ) == 0 && content_length_header)
526 belle_sip_message_remove_header_from_ptr(msg, BELLE_SIP_HEADER(content_length_header));
527
528 if (strcasecmp(belle_sip_header_get_name(header),BELLE_SIP_CONTENT_TYPE ) == 0 && content_type_header)
529 belle_sip_message_remove_header_from_ptr(msg, BELLE_SIP_HEADER(content_type_header));
530
531 belle_sip_message_add_header(BELLE_SIP_MESSAGE(msg), header);
532 }
533 }
534 } else {
535 if (content_length_header != NULL) belle_sip_message_remove_header_from_ptr(msg, BELLE_SIP_HEADER(content_length_header));
536 if (content_type_header != NULL) belle_sip_message_remove_header_from_ptr(msg, BELLE_SIP_HEADER(content_type_header));
537 }
538
539 SET_OBJECT_PROPERTY(msg,body_handler,body_handler);
540 }
541
belle_sip_message_get_body(belle_sip_message_t * msg)542 const char* belle_sip_message_get_body(belle_sip_message_t *msg) {
543 if (msg->body_handler==NULL) return NULL;
544 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg->body_handler, belle_sip_memory_body_handler_t)){
545 return (const char*)belle_sip_memory_body_handler_get_buffer(
546 BELLE_SIP_MEMORY_BODY_HANDLER(msg->body_handler)
547 );
548 }
549 belle_sip_error("belle_sip_message_get_body(): body cannot be returned as pointer.");
550 return NULL;
551 }
552
belle_sip_message_get_body_size(const belle_sip_message_t * msg)553 size_t belle_sip_message_get_body_size(const belle_sip_message_t *msg){
554 if (msg->body_handler==NULL) return 0;
555 return belle_sip_body_handler_get_size(msg->body_handler);
556 }
557
belle_sip_message_set_body(belle_sip_message_t * msg,const char * body,size_t size)558 void belle_sip_message_set_body(belle_sip_message_t *msg, const char* body, size_t size) {
559 belle_sip_body_handler_t *bh=NULL;
560 if (body && size) bh=(belle_sip_body_handler_t*)belle_sip_memory_body_handler_new_copy_from_buffer(body,size,NULL,NULL);
561 belle_sip_message_set_body_handler(msg,bh);
562 }
563
belle_sip_message_assign_body(belle_sip_message_t * msg,char * body,size_t size)564 void belle_sip_message_assign_body(belle_sip_message_t *msg, char* body, size_t size) {
565 belle_sip_body_handler_t *bh=(belle_sip_body_handler_t*)belle_sip_memory_body_handler_new_from_buffer(body,size,NULL,NULL);
566 belle_sip_message_set_body_handler(msg,bh);
567 }
568
569 struct _belle_sip_response{
570 belle_sip_message_t base;
571 char *sip_version;
572 int status_code;
573 char *reason_phrase;
574 };
575
576 typedef struct code_phrase{
577 int code;
578 const char *phrase;
579 } code_phrase_t;
580
581 static code_phrase_t well_known_codes[]={
582 { 100 , "Trying" },
583 { 101 , "Dialog establishment" },
584 { 180 , "Ringing" },
585 { 181 , "Call is being forwarded" },
586 { 182 , "Queued" },
587 { 183 , "Session progress" },
588 { 200 , "Ok" },
589 { 202 , "Accepted" },
590 { 300 , "Multiple choices" },
591 { 301 , "Moved permanently" },
592 { 302 , "Moved temporarily" },
593 { 305 , "Use proxy" },
594 { 380 , "Alternate contact" },
595 { 400 , "Bad request" },
596 { 401 , "Unauthorized" },
597 { 402 , "Payment required" },
598 { 403 , "Forbidden" },
599 { 404 , "Not found" },
600 { 405 , "Method not allowed" },
601 { 406 , "Not acceptable" },
602 { 407 , "Proxy authentication required" },
603 { 408 , "Request timeout" },
604 { 410 , "Gone" },
605 { 412 , "Conditional Request Failed" }, /*rfc3903*/
606 { 413 , "Request entity too large" },
607 { 414 , "Request-URI too long" },
608 { 415 , "Unsupported media type" },
609 { 416 , "Unsupported URI scheme" },
610 { 420 , "Bad extension" },
611 { 421 , "Extension required" },
612 { 423 , "Interval too brief" },
613 { 480 , "Temporarily unavailable" },
614 { 481 , "Call/transaction does not exist" },
615 { 482 , "Loop detected" },
616 { 483 , "Too many hops" },
617 { 484 , "Address incomplete" },
618 { 485 , "Ambiguous" },
619 { 486 , "Busy here" },
620 { 487 , "Request terminated" },
621 { 488 , "Not acceptable here" },
622 { 489 , "Bad Event" }, /*rfc3265*/
623 { 491 , "Request pending" },
624 { 493 , "Undecipherable" },
625 { 500 , "Server internal error" },
626 { 501 , "Not implemented" },
627 { 502 , "Bad gateway" },
628 { 503 , "Service unavailable" },
629 { 504 , "Server time-out" },
630 { 505 , "Version not supported" },
631 { 513 , "Message too large" },
632 { 600 , "Busy everywhere" },
633 { 603 , "Decline" },
634 { 604 , "Does not exist anywhere" },
635 { 606 , "Not acceptable" },
636 { 0 , NULL }
637 };
638
belle_sip_get_well_known_reason_phrase(int status_code)639 const char *belle_sip_get_well_known_reason_phrase(int status_code){
640 int i;
641 for(i=0;well_known_codes[i].code!=0;++i){
642 if (well_known_codes[i].code==status_code)
643 return well_known_codes[i].phrase;
644 }
645 return "Unknown reason";
646 }
647
belle_sip_response_destroy(belle_sip_response_t * resp)648 void belle_sip_response_destroy(belle_sip_response_t *resp){
649 if (resp->sip_version) belle_sip_free(resp->sip_version);
650 if (resp->reason_phrase) belle_sip_free(resp->reason_phrase);
651 }
652
belle_sip_response_init(belle_sip_response_t * resp)653 static void belle_sip_response_init(belle_sip_response_t *resp){
654 }
655
belle_sip_response_clone(belle_sip_response_t * resp,const belle_sip_response_t * orig)656 static void belle_sip_response_clone(belle_sip_response_t *resp, const belle_sip_response_t *orig){
657 if (orig->sip_version) resp->sip_version=belle_sip_strdup(orig->sip_version);
658 if (orig->reason_phrase) resp->reason_phrase=belle_sip_strdup(orig->reason_phrase);
659 }
660
belle_sip_response_marshal(belle_sip_response_t * resp,char * buff,size_t buff_size,size_t * offset)661 belle_sip_error_code belle_sip_response_marshal(belle_sip_response_t *resp, char* buff, size_t buff_size, size_t *offset) {
662 belle_sip_error_code error=belle_sip_snprintf( buff
663 ,buff_size
664 ,offset
665 ,"SIP/2.0 %i %s\r\n"
666 ,belle_sip_response_get_status_code(resp)
667 ,belle_sip_response_get_reason_phrase(resp)?belle_sip_response_get_reason_phrase(resp):"");
668
669 if (error!=BELLE_SIP_OK) return error;
670 error=belle_sip_headers_marshal(BELLE_SIP_MESSAGE(resp),buff,buff_size,offset);
671 if (error!=BELLE_SIP_OK) return error;
672 return error;
673 }
674
675 BELLE_SIP_NEW(response,message);
676 BELLE_SIP_PARSE(response)
677 GET_SET_STRING(belle_sip_response,reason_phrase);
GET_SET_INT(belle_sip_response,status_code,int)678 GET_SET_INT(belle_sip_response,status_code,int)
679
680 static int is_authorized_uri_header(const char* header_name) {
681 /*From, Call-ID, CSeq, Via, and Record-Route*/
682 /*Accept, Accept-Encoding, Accept-Language, Allow,
683 Contact (in its dialog usage), Organization, Supported, and User-Agent*/
684 return (strcasecmp("From",header_name) != 0
685 && strcasecmp("Call-ID",header_name) != 0
686 && strcasecmp("CSeq",header_name) != 0
687 && strcasecmp("Via",header_name) != 0
688 && strcasecmp("Record-Route",header_name) != 0
689 && strcasecmp("Accept",header_name) != 0
690 && strcasecmp("Accept-Encoding",header_name) != 0
691 && strcasecmp("Accept-Language",header_name) != 0
692 && strcasecmp("Allow",header_name) != 0
693 && strcasecmp("Contact",header_name) != 0
694 && strcasecmp("Organization",header_name) != 0
695 && strcasecmp("Supported",header_name) != 0
696 && strcasecmp("User-Agent",header_name) != 0);
697
698 }
699
belle_sip_request_create(belle_sip_uri_t * requri,const char * method,belle_sip_header_call_id_t * callid,belle_sip_header_cseq_t * cseq,belle_sip_header_from_t * from,belle_sip_header_to_t * to,belle_sip_header_via_t * via,int max_forward)700 belle_sip_request_t* belle_sip_request_create(belle_sip_uri_t *requri, const char* method,
701 belle_sip_header_call_id_t *callid,
702 belle_sip_header_cseq_t * cseq,
703 belle_sip_header_from_t *from,
704 belle_sip_header_to_t *to,
705 belle_sip_header_via_t *via,
706 int max_forward)
707 {
708 belle_sip_request_t *ret=belle_sip_request_new();
709 belle_sip_header_max_forwards_t *mf=belle_sip_header_max_forwards_new();
710 belle_sip_list_t* iterator;
711 if (max_forward==0) max_forward=70;
712 belle_sip_header_max_forwards_set_max_forwards(mf,max_forward);
713
714 belle_sip_request_set_method(ret,method);
715 belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(via));
716 belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(from));
717 if (to) belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(to)); /*to might be in header uri*/
718 belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(cseq));
719 belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(callid));
720 if (!belle_sip_message_get_header_by_type(ret,belle_sip_header_max_forwards_t))
721 belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(mf));
722 else
723 belle_sip_object_unref(mf);
724
725 /*
726 19.1.5 Forming Requests from a URI
727
728 An implementation needs to take care when forming requests directly
729 from a URI. URIs from business cards, web pages, and even from
730 sources inside the protocol such as registered contacts may contain
731 inappropriate header fields or body parts.
732
733 An implementation MUST include any provided transport, maddr, ttl, or
734 user parameter in the Request-URI of the formed request. If the URI
735 contains a method parameter, its value MUST be used as the method of
736 the request. The method parameter MUST NOT be placed in the
737 Request-URI. Unknown URI parameters MUST be placed in the message's
738 Request-URI.
739
740 An implementation SHOULD treat the presence of any headers or body
741 parts in the URI as a desire to include them in the message, and
742 choose to honor the request on a per-component basis.
743
744 An implementation SHOULD NOT honor these obviously dangerous header
745 fields: From, Call-ID, CSeq, Via, and Record-Route.
746
747 An implementation SHOULD NOT honor any requested Route header field
748 values in order to not be used as an unwitting agent in malicious
749 attacks.
750
751 An implementation SHOULD NOT honor requests to include header fields
752 that may cause it to falsely advertise its location or capabilities.
753 These include: Accept, Accept-Encoding, Accept-Language, Allow,
754 Contact (in its dialog usage), Organization, Supported, and User-
755 Agent.
756
757 An implementation SHOULD verify the accuracy of any requested
758 descriptive header fields, including: Content-Disposition, Content-
759 Encoding, Content-Language, Content-Length, Content-Type, Date,
760 Mime-Version, and Timestamp.*/
761
762 if (belle_sip_uri_get_header_names(requri)) {
763 for (iterator=(belle_sip_list_t*)belle_sip_uri_get_header_names(requri);iterator!=NULL;iterator=iterator->next) {
764 const char* header_name=(const char*)iterator->data;
765 /*1 check header name*/
766 if (is_authorized_uri_header(header_name)) {
767 belle_sip_header_extension_t* extended_header = belle_sip_header_extension_create(header_name, belle_sip_uri_get_header(requri, header_name));
768 if (extended_header) {
769 belle_sip_message_add_header((belle_sip_message_t*)ret,BELLE_SIP_HEADER(extended_header));
770 }
771 } else {
772 belle_sip_warning("Skiping uri header [%s] for request [%p]",header_name,requri);
773 }
774 }
775 }
776 belle_sip_uri_headers_clean(requri); /*remove all headers*/
777
778 belle_sip_request_set_uri(ret,requri);
779
780
781 return ret;
782 }
783
belle_sip_response_init_default(belle_sip_response_t * resp,int status_code,const char * phrase)784 static void belle_sip_response_init_default(belle_sip_response_t *resp, int status_code, const char *phrase){
785 resp->status_code=status_code;
786 resp->sip_version=belle_sip_strdup("SIP/2.0");
787 if (phrase==NULL) phrase=belle_sip_get_well_known_reason_phrase(status_code);
788 resp->reason_phrase=belle_sip_strdup(phrase);
789 }
790
791 /*
792 * note: we must not assume the request to be well formed because this function may be used to generate 400 Bad request response.
793 */
belle_sip_response_create_from_request(belle_sip_request_t * req,int status_code)794 belle_sip_response_t *belle_sip_response_create_from_request(belle_sip_request_t *req, int status_code){
795 belle_sip_response_t *resp=belle_sip_response_new();
796 belle_sip_header_t *h;
797 belle_sip_header_to_t *to;
798 const belle_sip_list_t *vias;
799
800 belle_sip_response_init_default(resp,status_code,NULL);
801 if (status_code==100 && (h=belle_sip_message_get_header((belle_sip_message_t*)req,"timestamp"))){
802 belle_sip_message_add_header((belle_sip_message_t*)resp,h);
803 }
804 vias=belle_sip_message_get_headers ((belle_sip_message_t*)req,"via");
805 belle_sip_message_add_headers((belle_sip_message_t*)resp,vias);
806 h=belle_sip_message_get_header((belle_sip_message_t*)req,"from");
807 if (h) belle_sip_message_add_header((belle_sip_message_t*)resp,h);
808 h=belle_sip_message_get_header((belle_sip_message_t*)req,"to");
809 if (h){
810 if (status_code!=100){
811 //so that to tag can be added
812 to=(belle_sip_header_to_t*)belle_sip_object_clone((belle_sip_object_t*)h);
813 }else{
814 to=(belle_sip_header_to_t*)h;
815 }
816 belle_sip_message_add_header((belle_sip_message_t*)resp,(belle_sip_header_t*)to);
817 }
818 h=belle_sip_message_get_header((belle_sip_message_t*)req,"call-id");
819 if (h) belle_sip_message_add_header((belle_sip_message_t*)resp,h);
820 h=belle_sip_message_get_header((belle_sip_message_t*)req,"cseq");
821 if (h){
822 belle_sip_message_add_header((belle_sip_message_t*)resp,h);
823 }
824 return resp;
825 }
826 /*
827 12.1.1 UAS behavior
828
829 When a UAS responds to a request with a response that establishes a
830 dialog (such as a 2xx to INVITE), the UAS MUST copy all Record-Route
831 header field values from the request into the response (including the
832 URIs, URI parameters, and any Record-Route header field parameters,
833 whether they are known or unknown to the UAS) and MUST maintain the
834 order of those values.
835 */
belle_sip_response_fill_for_dialog(belle_sip_response_t * obj,belle_sip_request_t * req)836 void belle_sip_response_fill_for_dialog(belle_sip_response_t *obj, belle_sip_request_t *req){
837 const belle_sip_list_t *rr=belle_sip_message_get_headers((belle_sip_message_t*)req,BELLE_SIP_RECORD_ROUTE);
838 belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(obj,belle_sip_header_contact_t);
839 belle_sip_message_remove_header((belle_sip_message_t*)obj,BELLE_SIP_RECORD_ROUTE);
840 if (rr)
841 belle_sip_message_add_headers((belle_sip_message_t*)obj,rr);
842 if (belle_sip_response_get_status_code(obj)>=200 && belle_sip_response_get_status_code(obj)<300 && !ct){
843 const char *method=belle_sip_request_get_method(req);
844 if (strcmp(method,"INVITE")==0 || strcmp(method,"SUBSCRIBE")==0){
845 /*add a dummy contact to be filled by channel later*/
846 belle_sip_message_add_header((belle_sip_message_t*)obj,(belle_sip_header_t*)belle_sip_header_contact_new());
847 }
848 }
849 }
850
belle_sip_response_get_return_hop(belle_sip_response_t * msg)851 belle_sip_hop_t* belle_sip_response_get_return_hop(belle_sip_response_t *msg){
852 belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header(BELLE_SIP_MESSAGE(msg),"via"));
853 if (via){
854 const char *host=belle_sip_header_via_get_received(via) ? belle_sip_header_via_get_received(via) : belle_sip_header_via_get_host(via);
855 int port=belle_sip_header_via_get_rport(via)>0 ? belle_sip_header_via_get_rport(via) : belle_sip_header_via_get_listening_port(via);
856 return belle_sip_hop_new(belle_sip_header_via_get_transport_lowercase(via),NULL,host,port);
857 }
858 return NULL;
859 }
860
belle_sip_response_fix_contact(const belle_sip_response_t * response,belle_sip_header_contact_t * contact)861 int belle_sip_response_fix_contact(const belle_sip_response_t* response,belle_sip_header_contact_t* contact) {
862 belle_sip_header_via_t* via_header;
863 belle_sip_uri_t* contact_uri;
864 const char* received;
865 int rport;
866 int contact_port;
867 /*first check received/rport*/
868 via_header= (belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA);
869 received = belle_sip_header_via_get_received(via_header);
870 rport = belle_sip_header_via_get_rport(via_header);
871 contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact));
872 if (received) {
873 /*need to update host*/
874 belle_sip_uri_set_host(contact_uri,received);
875 } else {
876 belle_sip_uri_set_host(contact_uri,belle_sip_header_via_get_host(via_header));
877 }
878 contact_port = belle_sip_uri_get_port(contact_uri);
879 if (rport>0 ) {
880 /*need to update port*/
881 if ((rport+contact_port)!=5060) belle_sip_uri_set_port(contact_uri,rport);
882 } else if ((belle_sip_header_via_get_port(via_header)+contact_port)!=5060) {
883 belle_sip_uri_set_port(contact_uri,belle_sip_header_via_get_port(via_header));
884 }
885 /*try to fix transport if needed (very unlikely)*/
886 if (strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0) {
887 if (!belle_sip_uri_get_transport_param(contact_uri)
888 ||strcasecmp(belle_sip_uri_get_transport_param(contact_uri),belle_sip_header_via_get_transport(via_header))!=0) {
889 belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header));
890 }
891 } else {
892 if (belle_sip_uri_get_transport_param(contact_uri)) {
893 belle_sip_uri_set_transport_param(contact_uri,NULL);
894 }
895 }
896 return 0;
897 }
898
belle_sip_request_clone_with_body(const belle_sip_request_t * initial_req)899 belle_sip_request_t * belle_sip_request_clone_with_body(const belle_sip_request_t *initial_req) {
900 belle_sip_request_t* req=BELLE_SIP_REQUEST(belle_sip_object_clone(BELLE_SIP_OBJECT(initial_req)));
901 if (initial_req->base.body_handler) req->base.body_handler=BELLE_SIP_BODY_HANDLER(belle_sip_object_clone_and_ref(
902 (belle_sip_object_t*)initial_req->base.body_handler));
903 return req;
904 }
905
906 typedef struct message_header_list {
907 const char* method;
908 const char* headers[10]; /*MAX headers*/
909 } message_header_list_t;
910 /**
911 RFC 3261 SIP: Session Initiation Protocol June 2002
912
913 Header field where proxy ACK BYE CAN INV OPT REG
914 __________________________________________________________________
915 Accept R - o - o m* o
916 Accept 2xx - - - o m* o
917 Accept 415 - c - c c c
918 Accept-Encoding R - o - o o o
919 Accept-Encoding 2xx - - - o m* o
920 Accept-Encoding 415 - c - c c c
921 Accept-Language R - o - o o o
922 Accept-Language 2xx - - - o m* o
923 Accept-Language 415 - c - c c c
924 Alert-Info R ar - - - o - -
925 Alert-Info 180 ar - - - o - -
926 Allow R - o - o o o
927 Allow 2xx - o - m* m* o
928 Allow r - o - o o o
929 Allow 405 - m - m m m
930 Authentication-Info 2xx - o - o o o
931 Authorization R o o o o o o
932 Call-ID c r m m m m m m
933 Call-Info ar - - - o o o
934 Contact R o - - m o o
935 Contact 1xx - - - o - -
936 Contact 2xx - - - m o o
937 Contact 3xx d - o - o o o
938 Contact 485 - o - o o o
939 Content-Disposition o o - o o o
940 Content-Encoding o o - o o o
941 Content-Language o o - o o o
942 Content-Length ar t t t t t t
943 Content-Type * * - * * *
944 CSeq c r m m m m m m
945 Date a o o o o o o
946 Error-Info 300-699 a - o o o o o
947 Expires - - - o - o
948 From c r m m m m m m
949 In-Reply-To R - - - o - -
950 Max-Forwards R amr m m m m m m
951 Min-Expires 423 - - - - - m
952 MIME-Version o o - o o o
953 Organization ar - - - o o o
954 Priority R ar - - - o - -
955 Proxy-Authenticate 407 ar - m - m m m
956 Proxy-Authenticate 401 ar - o o o o o
957 Proxy-Authorization R dr o o - o o o
958 Proxy-Require R ar - o - o o o
959 Record-Route R ar o o o o o -
960 Record-Route 2xx,18x mr - o o o o -
961 Reply-To - - - o - -
962 Require ar - c - c c c
963 Retry-After 404,413,480,486 - o o o o o
964 500,503 - o o o o o
965 600,603 - o o o o o
966 Route R adr c c c c c c
967 Server r - o o o o o
968 Subject R - - - o - -
969 Supported R - o o m* o o
970 Supported 2xx - o o m* m* o
971 Timestamp o o o o o o
972 To c(1) r m m m m m m
973 Unsupported 420 - m - m m m
974 User-Agent o o o o o o
975 Via R amr m m m m m m
976 Via rc dr m m m m m m
977 Warning r - o o o o o
978 WWW-Authenticate 401 ar - m - m m m
979 WWW-Authenticate 407 ar - o - o o o
980
981 Table 3: Summary of header fields, A--Z; (1): copied with possible
982 addition of tag
983
984 */
985 static message_header_list_t mandatory_headers[] = {
986 {"REGISTER",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
987 {"INVITE",{"Contact","Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
988 {"CANCEL",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
989 {"BYE",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
990 {"ACK",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
991 {"*", { "To", "From", "CSeq", "Via", NULL}}, /* catch-all, these fields are required all the time. */
992 {NULL,{NULL}}
993 };
994
995 /*static int belle_sip_message_is_mandatody_header(const char* method, const char* header_name) {
996 int i;
997 for (i=0;mandatory_headers[i].method!=NULL;i++) {
998 if (strcasecmp(method,mandatory_headers[i].method)==0) {
999 int j;
1000 for(j=0;mandatory_headers[i].headers[j]!=NULL;j++) {
1001 if (strcasecmp(header_name,mandatory_headers[i].headers[j])==0) {
1002 return 1;
1003 }
1004 }
1005 }
1006 }
1007 return 0;
1008 }
1009 */
belle_sip_message_check_headers(const belle_sip_message_t * message)1010 int belle_sip_message_check_headers(const belle_sip_message_t* message) {
1011 if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(message,belle_sip_request_t)) {
1012 int i;
1013 belle_sip_header_via_t *via;
1014 const char * method = belle_sip_request_get_method(BELLE_SIP_REQUEST(message));
1015
1016 for (i=0;mandatory_headers[i].method!=NULL;i++) {
1017 if ( (strcasecmp(method,mandatory_headers[i].method)==0) ||
1018 (mandatory_headers[i].method[0] == '*') ){
1019 int j;
1020 for(j=0;mandatory_headers[i].headers[j]!=NULL;j++) {
1021 if (belle_sip_message_get_header(message,mandatory_headers[i].headers[j])==NULL) {
1022 belle_sip_error("Missing mandatory header [%s] for message [%s]",mandatory_headers[i].headers[j],method);
1023 return 0;
1024 }
1025 }
1026 return 1;
1027 }
1028 }
1029 via=belle_sip_message_get_header_by_type(message,belle_sip_header_via_t);
1030 if (!via || belle_sip_header_via_get_branch(via)==NULL) return 0;
1031 }
1032 /*else fixme should also check responses*/
1033 return 1;
1034
1035 }
1036
belle_sip_request_check_uris_components(const belle_sip_request_t * request)1037 int belle_sip_request_check_uris_components(const belle_sip_request_t* request) {
1038 belle_sip_list_t* new_list = belle_sip_message_get_all_headers(BELLE_SIP_MESSAGE(request));
1039 belle_sip_list_t* iterator = new_list;
1040
1041 for (;iterator!=NULL;iterator=iterator->next) {
1042 belle_sip_header_t* header=(belle_sip_header_t*)iterator->data;
1043 if (BELLE_SIP_IS_INSTANCE_OF(header,belle_sip_header_address_t)) {
1044 belle_sip_uri_t* uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(header));
1045 if (uri && !belle_sip_uri_check_components_from_context(uri,belle_sip_request_get_method(request),belle_sip_header_get_name(header))) {
1046 char* header_string=belle_sip_object_to_string(header);
1047 belle_sip_error("Malformed header [%s] for request [%p]",header_string,request);
1048 belle_sip_free(header_string);
1049 belle_sip_list_free(new_list);
1050 return FALSE;
1051 }
1052 }
1053 }
1054
1055 belle_sip_list_free(new_list);
1056 return belle_sip_uri_check_components_from_request_uri(belle_sip_request_get_uri((const belle_sip_request_t*)request));
1057 }
1058