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