xref: /titanic_41/usr/src/lib/libsip/common/sip_msg.c (revision 2c2c41837e330b002c4220a39638150db504fe0e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <pthread.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sip.h>
36 
37 #include "sip_msg.h"
38 #include "sip_miscdefs.h"
39 #include "sip_parse_generic.h"
40 
41 /*
42  * Response consists of SIP version, response code, response phrase and CRLF.
43  */
44 #define	SIP_RESPONSE	"%s %d %s%s"
45 
46 void sip_free_content(_sip_msg_t *);
47 
48 /*
49  * Allocate a new sip msg struct.
50  */
51 sip_msg_t
sip_new_msg()52 sip_new_msg()
53 {
54 	_sip_msg_t *sip_msg;
55 
56 	sip_msg = calloc(1, sizeof (_sip_msg_t));
57 	if (sip_msg != NULL) {
58 		sip_msg->sip_msg_ref_cnt = 1;
59 		(void) pthread_mutex_init(&sip_msg->sip_msg_mutex, NULL);
60 	}
61 	return ((sip_msg_t)sip_msg);
62 }
63 
64 /*
65  * Free all resources. The lock is taken by SIP_MSG_REFCNT_DECR. The
66  * thread that decrements the last refcount should take care that
67  * the message is not accessible to other threads before doing so.
68  * Else, if the message is still accessible to others, it is
69  * possible that the other thread could be waiting to take the
70  * lock when we proceed to destroy it.
71  */
72 void
sip_destroy_msg(_sip_msg_t * _sip_msg)73 sip_destroy_msg(_sip_msg_t *_sip_msg)
74 {
75 #ifdef	__solaris__
76 	assert(mutex_held(&_sip_msg->sip_msg_mutex));
77 #endif
78 	(void) sip_delete_start_line_locked(_sip_msg);
79 	assert(_sip_msg->sip_msg_ref_cnt == 0);
80 	sip_delete_all_headers((sip_msg_t)_sip_msg);
81 	sip_free_content(_sip_msg);
82 	if (_sip_msg->sip_msg_buf != NULL)
83 		free(_sip_msg->sip_msg_buf);
84 
85 	if (_sip_msg->sip_msg_old_buf != NULL)
86 		free(_sip_msg->sip_msg_old_buf);
87 
88 	while (_sip_msg->sip_msg_req_res != NULL) {
89 		sip_message_type_t	*sip_msg_type_ptr;
90 
91 		sip_msg_type_ptr = _sip_msg->sip_msg_req_res->sip_next;
92 		if (_sip_msg->sip_msg_req_res->is_request) {
93 			sip_request_t	*reqline;
94 
95 			reqline = &_sip_msg->sip_msg_req_res->U.sip_request;
96 			if (reqline->sip_parse_uri != NULL) {
97 				sip_free_parsed_uri(reqline->sip_parse_uri);
98 				reqline->sip_parse_uri = NULL;
99 			}
100 		}
101 		free(_sip_msg->sip_msg_req_res);
102 		_sip_msg->sip_msg_req_res = sip_msg_type_ptr;
103 	}
104 	(void) pthread_mutex_destroy(&_sip_msg->sip_msg_mutex);
105 	free(_sip_msg);
106 }
107 
108 /*
109  * Free a sip msg struct.
110  */
111 void
sip_free_msg(sip_msg_t sip_msg)112 sip_free_msg(sip_msg_t sip_msg)
113 {
114 	if (sip_msg == NULL)
115 		return;
116 
117 	SIP_MSG_REFCNT_DECR((_sip_msg_t *)sip_msg);
118 }
119 
120 /*
121  * Hold a sip msg struct.
122  */
123 void
sip_hold_msg(sip_msg_t sip_msg)124 sip_hold_msg(sip_msg_t sip_msg)
125 {
126 
127 	if (sip_msg == NULL)
128 		return;
129 
130 	SIP_MSG_REFCNT_INCR((_sip_msg_t *)sip_msg);
131 }
132 
133 /*
134  * Clone a message
135  */
136 sip_msg_t
sip_clone_msg(sip_msg_t sip_msg)137 sip_clone_msg(sip_msg_t sip_msg)
138 {
139 	_sip_msg_t	*new_msg;
140 	_sip_msg_t	*_sip_msg;
141 	sip_content_t	*sip_content;
142 	sip_content_t	*msg_content;
143 	sip_content_t	*new_content = NULL;
144 	int		len;
145 
146 	if (sip_msg == NULL)
147 		return (NULL);
148 	new_msg = (_sip_msg_t *)sip_new_msg();
149 	if (new_msg == NULL)
150 		return (NULL);
151 	_sip_msg = (_sip_msg_t *)sip_msg;
152 	/*
153 	 * Get start line
154 	 */
155 	if (sip_copy_start_line(_sip_msg, new_msg) != 0) {
156 		sip_free_msg((sip_msg_t)new_msg);
157 		return (NULL);
158 	}
159 	if (sip_copy_all_headers(_sip_msg, new_msg) != 0) {
160 		sip_free_msg((sip_msg_t)new_msg);
161 		return (NULL);
162 	}
163 	(void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
164 	sip_content = _sip_msg->sip_msg_content;
165 	while (sip_content != NULL) {
166 		msg_content = calloc(1, sizeof (sip_content_t));
167 		if (msg_content == NULL) {
168 			sip_free_msg((sip_msg_t)new_msg);
169 			(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
170 			return (NULL);
171 		}
172 		len = sip_content->sip_content_end -
173 		    sip_content->sip_content_start;
174 		msg_content->sip_content_start = malloc(len + 1);
175 		if (msg_content->sip_content_start == NULL) {
176 			sip_free_msg((sip_msg_t)new_msg);
177 			(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
178 			return (NULL);
179 		}
180 		(void) strncpy(msg_content->sip_content_start,
181 		    sip_content->sip_content_start, len);
182 		msg_content->sip_content_start[len] = '\0';
183 		msg_content->sip_content_current =
184 		    msg_content->sip_content_start;
185 		msg_content->sip_content_end =  msg_content->sip_content_start +
186 		    len;
187 		msg_content->sip_content_allocated = B_TRUE;
188 		new_msg->sip_msg_content_len += len;
189 		new_msg->sip_msg_len += len;
190 		if (new_msg->sip_msg_content == NULL)
191 			new_msg->sip_msg_content = msg_content;
192 		else
193 			new_content->sip_content_next = msg_content;
194 		new_content = msg_content;
195 		sip_content = sip_content->sip_content_next;
196 	}
197 	(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
198 	/*
199 	 * Since this is a new message, no threads should be referring
200 	 * to this, so it is not necessary to take the lock, however,
201 	 * since sip_msg_to_msgbuf() expects the lock to be held, we'll
202 	 * take it here.
203 	 */
204 	(void) pthread_mutex_lock(&new_msg->sip_msg_mutex);
205 	new_msg->sip_msg_buf = sip_msg_to_msgbuf((sip_msg_t)new_msg, NULL);
206 	if (new_msg->sip_msg_buf == NULL) {
207 		(void) pthread_mutex_unlock(&new_msg->sip_msg_mutex);
208 		sip_free_msg((sip_msg_t)new_msg);
209 		return (NULL);
210 	}
211 	new_msg->sip_msg_cannot_be_modified = B_TRUE;
212 	(void) pthread_mutex_unlock(&new_msg->sip_msg_mutex);
213 
214 	return ((sip_msg_t)new_msg);
215 }
216 
217 /*
218  * Return the SIP message as a string. Caller frees the string
219  */
220 char *
sip_msg_to_str(sip_msg_t sip_msg,int * error)221 sip_msg_to_str(sip_msg_t sip_msg, int *error)
222 {
223 	_sip_msg_t	*msg;
224 	char		*msgstr;
225 
226 	if (sip_msg == NULL) {
227 		if (error != NULL)
228 			*error = EINVAL;
229 		return (NULL);
230 	}
231 	msg = (_sip_msg_t *)sip_msg;
232 	(void) pthread_mutex_lock(&msg->sip_msg_mutex);
233 	msgstr = sip_msg_to_msgbuf(msg, error);
234 	(void) pthread_mutex_unlock(&msg->sip_msg_mutex);
235 	return (msgstr);
236 }
237 
238 /*
239  * Given a message generate a string that includes all the headers and the
240  * content.
241  */
242 char *
sip_msg_to_msgbuf(_sip_msg_t * msg,int * error)243 sip_msg_to_msgbuf(_sip_msg_t *msg, int *error)
244 {
245 	_sip_header_t	*header;
246 	int		len = 0;
247 	char		*p;
248 	char		*e;
249 	sip_content_t	*sip_content;
250 #ifdef	_DEBUG
251 	int		tlen = 0;
252 	int		clen = 0;
253 #endif
254 
255 	if (error != NULL)
256 		*error = 0;
257 
258 	if (msg == NULL) {
259 		if (error != NULL)
260 			*error = EINVAL;
261 		return (NULL);
262 	}
263 #ifdef	__solaris__
264 	assert(mutex_held(&msg->sip_msg_mutex));
265 #endif
266 
267 	p = (char *)malloc(msg->sip_msg_len + 1);
268 	if (p == NULL) {
269 		if (error != 0)
270 			*error = ENOMEM;
271 		return (NULL);
272 	}
273 	e = p;
274 
275 	/*
276 	 * Get the start line
277 	 */
278 	if (msg->sip_msg_start_line != NULL) {
279 		len = msg->sip_msg_start_line->sip_hdr_end -
280 		    msg->sip_msg_start_line->sip_hdr_start;
281 		(void) strncpy(e, msg->sip_msg_start_line->sip_hdr_start, len);
282 		e += len;
283 #ifdef	_DEBUG
284 		tlen += len;
285 #endif
286 	}
287 	header = sip_search_for_header(msg, NULL, NULL);
288 	while (header != NULL) {
289 		if (header->sip_header_state != SIP_HEADER_DELETED) {
290 			if (header->sip_header_state ==
291 			    SIP_HEADER_DELETED_VAL) {
292 				len = sip_copy_values(e, header);
293 			} else {
294 				len = header->sip_hdr_end -
295 				    header->sip_hdr_start;
296 				(void) strncpy(e, header->sip_hdr_start, len);
297 			}
298 #ifdef	_DEBUG
299 			tlen += len;
300 			assert(tlen <= msg->sip_msg_len);
301 #endif
302 		}
303 		header = sip_search_for_header(msg, NULL, header);
304 		e += len;
305 	}
306 	sip_content = msg->sip_msg_content;
307 	while (sip_content != NULL) {
308 		len = sip_content->sip_content_end -
309 		    sip_content->sip_content_start;
310 #ifdef	_DEBUG
311 		clen += len;
312 		assert(clen <= msg->sip_msg_content_len);
313 		tlen += len;
314 		assert(tlen <= msg->sip_msg_len);
315 #endif
316 		(void) strncpy(e, sip_content->sip_content_start, len);
317 		e += len;
318 		sip_content = sip_content->sip_content_next;
319 	}
320 	p[msg->sip_msg_len] = '\0';
321 	return (p);
322 }
323 
324 /*
325  * This is called just before sending the message to the transport. It
326  * creates the sip_msg_buf from the SIP headers.
327  */
328 int
sip_adjust_msgbuf(_sip_msg_t * msg)329 sip_adjust_msgbuf(_sip_msg_t *msg)
330 {
331 	_sip_header_t	*header;
332 	int		ret;
333 #ifdef	_DEBUG
334 	int		tlen = 0;
335 	int		clen = 0;
336 #endif
337 
338 	if (msg == NULL)
339 		return (EINVAL);
340 
341 	(void) pthread_mutex_lock(&msg->sip_msg_mutex);
342 	if ((msg->sip_msg_buf != NULL) && (!msg->sip_msg_modified)) {
343 		/*
344 		 * We could just be forwarding the message we
345 		 * received.
346 		 */
347 		(void) pthread_mutex_unlock(&msg->sip_msg_mutex);
348 		return (0);
349 	}
350 
351 	/*
352 	 * We are sending a new message or a message that we received
353 	 * but have modified it. We keep the old
354 	 * msgbuf till the message is freed as some
355 	 * headers still point to it.
356 	 */
357 
358 	assert(msg->sip_msg_old_buf == NULL);
359 	msg->sip_msg_old_buf = msg->sip_msg_buf;
360 	/*
361 	 * We add the content-length header here, if it has not
362 	 * already been added.
363 	 */
364 	header = sip_search_for_header(msg, SIP_CONTENT_LENGTH, NULL);
365 	if (header != NULL) {
366 		/*
367 		 * Mark the previous header as deleted.
368 		 */
369 		header->sip_header_state = SIP_HEADER_DELETED;
370 		header->sip_hdr_sipmsg->sip_msg_len -= header->sip_hdr_end -
371 		    header->sip_hdr_start;
372 	}
373 	(void) pthread_mutex_unlock(&msg->sip_msg_mutex);
374 	ret = sip_add_content_length(msg, msg->sip_msg_content_len);
375 	if (ret != 0) {
376 		(void) pthread_mutex_unlock(&msg->sip_msg_mutex);
377 		return (ret);
378 	}
379 	(void) pthread_mutex_lock(&msg->sip_msg_mutex);
380 	msg->sip_msg_modified = B_FALSE;
381 
382 	msg->sip_msg_buf = sip_msg_to_msgbuf((sip_msg_t)msg, &ret);
383 	if (msg->sip_msg_buf == NULL) {
384 		(void) pthread_mutex_unlock(&msg->sip_msg_mutex);
385 		return (ret);
386 	}
387 	/*
388 	 * Once the message has been sent it can not be modified
389 	 * any furthur as we keep a pointer to it for retransmission
390 	 */
391 	msg->sip_msg_cannot_be_modified = B_TRUE;
392 
393 	(void) pthread_mutex_unlock(&msg->sip_msg_mutex);
394 	return (0);
395 }
396 
397 /*
398  * Copy header values into ptr
399  */
400 int
sip_copy_values(char * ptr,_sip_header_t * header)401 sip_copy_values(char *ptr, _sip_header_t *header)
402 {
403 	sip_header_value_t	value;
404 	int			tlen = 0;
405 	int			len = 0;
406 	boolean_t		first = B_TRUE;
407 	char			*p = ptr;
408 	char			*s;
409 	boolean_t		crlf_present = B_FALSE;
410 
411 	if (sip_parse_goto_values(header) != 0)
412 		return (0);
413 
414 	len = header->sip_hdr_current - header->sip_hdr_start;
415 	(void) strncpy(p, header->sip_hdr_start, len);
416 	tlen += len;
417 	p += len;
418 	value = header->sip_hdr_parsed->value;
419 	while (value != NULL) {
420 		if (value->value_state != SIP_VALUE_DELETED) {
421 			crlf_present = B_FALSE;
422 			len = value->value_end - value->value_start;
423 			if (first) {
424 				(void) strncpy(p, value->value_start, len);
425 				first = B_FALSE;
426 			} else {
427 				s = value->value_start;
428 				while (*s != SIP_COMMA)
429 					s--;
430 				len += value->value_start - s;
431 				(void) strncpy(p, s, len);
432 			}
433 			tlen += len;
434 			p += len;
435 			s = value->value_end;
436 			while (s != value->value_start) {
437 				if (*s == '\r' && strncmp(s, SIP_CRLF,
438 				    strlen(SIP_CRLF)) == 0) {
439 					crlf_present = B_TRUE;
440 					break;
441 				}
442 				s--;
443 			}
444 		} else {
445 			if (value->next == NULL && !first && !crlf_present) {
446 				s = value->value_end;
447 				while (*s != '\r')
448 					s--;
449 				len = value->value_end - s;
450 				(void) strncpy(p, s, len);
451 				tlen += len;
452 				p += len;
453 			}
454 		}
455 		value = value->next;
456 	}
457 	return (tlen);
458 }
459 
460 
461 /*
462  * Add content (message body) to sip_msg
463  */
464 int
sip_add_content(sip_msg_t sip_msg,char * content)465 sip_add_content(sip_msg_t sip_msg, char *content)
466 {
467 	size_t		len;
468 	sip_content_t	**loc;
469 	sip_content_t	*msg_content;
470 	_sip_msg_t	*_sip_msg;
471 
472 	if (sip_msg == NULL || content == NULL || strlen(content) == 0)
473 		return (EINVAL);
474 	len = strlen(content);
475 	_sip_msg = (_sip_msg_t *)sip_msg;
476 	(void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
477 
478 	if (_sip_msg->sip_msg_cannot_be_modified) {
479 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
480 		return (ENOTSUP);
481 	}
482 
483 	msg_content = calloc(1, sizeof (sip_content_t));
484 	if (msg_content == NULL) {
485 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
486 		return (ENOMEM);
487 	}
488 	msg_content->sip_content_start = malloc(strlen(content) + 1);
489 	if (msg_content->sip_content_start == NULL) {
490 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
491 		free(msg_content);
492 		return (ENOMEM);
493 	}
494 	(void) strncpy(msg_content->sip_content_start, content,
495 	    strlen(content));
496 	msg_content->sip_content_start[strlen(content)] = '\0';
497 	msg_content->sip_content_current = msg_content->sip_content_start;
498 	msg_content->sip_content_end = msg_content->sip_content_start +
499 	    strlen(msg_content->sip_content_start);
500 	msg_content->sip_content_allocated = B_TRUE;
501 
502 	loc = &_sip_msg->sip_msg_content;
503 	while (*loc != NULL)
504 		loc = &((*loc)->sip_content_next);
505 	*loc = msg_content;
506 
507 	_sip_msg->sip_msg_content_len += len;
508 	_sip_msg->sip_msg_len += len;
509 	if (_sip_msg->sip_msg_buf != NULL)
510 		_sip_msg->sip_msg_modified = B_TRUE;
511 	(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
512 	return (0);
513 }
514 
515 /*
516  * Free the message content
517  */
518 void
sip_free_content(_sip_msg_t * sip_msg)519 sip_free_content(_sip_msg_t *sip_msg)
520 {
521 	sip_content_t *content;
522 
523 	if (sip_msg == NULL)
524 		return;
525 	content = sip_msg->sip_msg_content;
526 	while (content != NULL) {
527 		sip_content_t *content_tmp;
528 
529 		content_tmp = content;
530 		content = content->sip_content_next;
531 		if (content_tmp->sip_content_allocated)
532 			free(content_tmp->sip_content_start);
533 		free(content_tmp);
534 	}
535 	sip_msg->sip_msg_content = NULL;
536 }
537 
538 
539 /*
540  * Add a response line to sip_response
541  */
542 int
sip_add_response_line(sip_msg_t sip_response,int response,char * response_code)543 sip_add_response_line(sip_msg_t sip_response, int response, char *response_code)
544 {
545 	_sip_header_t	*new_header;
546 	int		header_size;
547 	_sip_msg_t	*_sip_response;
548 	int		ret;
549 
550 	if (sip_response == NULL || response < 0 || response_code == NULL)
551 		return (EINVAL);
552 	_sip_response = (_sip_msg_t *)sip_response;
553 	(void) pthread_mutex_lock(&_sip_response->sip_msg_mutex);
554 	if (_sip_response->sip_msg_cannot_be_modified) {
555 		(void) pthread_mutex_unlock(&_sip_response->sip_msg_mutex);
556 		return (ENOTSUP);
557 	}
558 	header_size = strlen(SIP_VERSION) + SIP_SPACE_LEN +
559 	    SIP_SIZE_OF_STATUS_CODE + SIP_SPACE_LEN + strlen(response_code) +
560 	    strlen(SIP_CRLF);
561 
562 	new_header = sip_new_header(header_size);
563 	if (new_header == NULL) {
564 		(void) pthread_mutex_unlock(&_sip_response->sip_msg_mutex);
565 		return (ENOMEM);
566 	}
567 	new_header->sip_hdr_sipmsg = _sip_response;
568 
569 	(void) snprintf(new_header->sip_hdr_start, header_size + 1,
570 	    SIP_RESPONSE, SIP_VERSION, response, response_code, SIP_CRLF);
571 
572 	new_header->sip_hdr_next = _sip_response->sip_msg_start_line;
573 	_sip_response->sip_msg_start_line = new_header;
574 	_sip_response->sip_msg_len += header_size;
575 	ret = sip_parse_first_line(_sip_response->sip_msg_start_line,
576 	    &_sip_response->sip_msg_req_res);
577 	if (_sip_response->sip_msg_buf != NULL)
578 		_sip_response->sip_msg_modified = B_TRUE;
579 	(void) pthread_mutex_unlock(&_sip_response->sip_msg_mutex);
580 	return (ret);
581 }
582 
583 /*
584  * create a response based on the sip_request.
585  * Copies Call-ID, CSeq, From, To and Via headers from the request.
586  */
587 sip_msg_t
sip_create_response(sip_msg_t sip_request,int response,char * response_code,char * totag,char * mycontact)588 sip_create_response(sip_msg_t sip_request, int response, char *response_code,
589     char *totag, char *mycontact)
590 {
591 	_sip_msg_t	*new_msg;
592 	_sip_msg_t	*_sip_request;
593 	boolean_t	ttag_present;
594 
595 	if (sip_request == NULL || response_code == NULL)
596 		return (NULL);
597 
598 	ttag_present =  sip_get_to_tag(sip_request, NULL) != NULL;
599 
600 	new_msg = (_sip_msg_t *)sip_new_msg();
601 	if (new_msg == NULL)
602 		return (NULL);
603 	_sip_request = (_sip_msg_t *)sip_request;
604 
605 	(void) pthread_mutex_lock(&_sip_request->sip_msg_mutex);
606 
607 	/*
608 	 * Add response line.
609 	 */
610 	if (sip_add_response_line(new_msg, response, response_code) != 0)
611 		goto error;
612 
613 	/*
614 	 * Copy Via headers
615 	 */
616 	if (_sip_find_and_copy_all_header(_sip_request, new_msg, SIP_VIA) != 0)
617 		goto error;
618 
619 	/*
620 	 * Copy From header.
621 	 */
622 	if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_FROM,
623 	    NULL, B_FALSE)) {
624 		goto error;
625 	}
626 	/*
627 	 * Copy To header. If To tag is present, copy it, if not then
628 	 * add one if the repsonse is not provisional.
629 	 */
630 	if (ttag_present || (totag == NULL && response == SIP_TRYING)) {
631 		if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_TO,
632 		    NULL, B_FALSE)) {
633 			goto error;
634 		}
635 	} else {
636 		char		*xtra_param;
637 		boolean_t	tag_alloc = B_FALSE;
638 		int		taglen;
639 
640 		if (totag == NULL) {
641 			totag = sip_guid();
642 			if (totag == NULL)
643 				goto error;
644 			tag_alloc = B_TRUE;
645 		}
646 		taglen = strlen(SIP_TAG) + strlen(totag) + 1;
647 		xtra_param = (char *)malloc(taglen);
648 		if (xtra_param == NULL) {
649 			if (tag_alloc)
650 				free(totag);
651 			goto error;
652 		}
653 		(void) snprintf(xtra_param, taglen, "%s%s", SIP_TAG, totag);
654 		if (tag_alloc)
655 			free(totag);
656 		if (_sip_find_and_copy_header(_sip_request, new_msg,
657 		    SIP_TO, xtra_param, B_FALSE)) {
658 			free(xtra_param);
659 			goto error;
660 		}
661 		free(xtra_param);
662 	}
663 
664 	/*
665 	 * Copy Call-ID header.
666 	 */
667 	if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_CALL_ID, NULL,
668 	    B_FALSE)) {
669 		goto error;
670 	}
671 	/*
672 	 * Copy CSEQ header
673 	 */
674 	if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_CSEQ, NULL,
675 	    B_FALSE)) {
676 		goto error;
677 	}
678 	/*
679 	 * Copy RECORD-ROUTE header, if present.
680 	 */
681 	if (sip_search_for_header(_sip_request, SIP_RECORD_ROUTE, NULL) !=
682 	    NULL) {
683 		if (_sip_find_and_copy_all_header(_sip_request, new_msg,
684 		    SIP_RECORD_ROUTE) != 0) {
685 			goto error;
686 		}
687 	}
688 	if (mycontact != NULL) {
689 		if (sip_add_contact(new_msg, NULL, mycontact, B_FALSE,
690 		    NULL) != 0) {
691 			goto error;
692 		}
693 	}
694 	(void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex);
695 	return ((sip_msg_t)new_msg);
696 error:
697 	sip_free_msg((sip_msg_t)new_msg);
698 	(void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex);
699 	return (NULL);
700 }
701 
702 /*
703  * NON OK ACK : MUST contain values for the Call-ID, From, and Request-URI
704  * that are equal to the values of those header fields in the orig request
705  * passed to the transport. The To header field in the ACK MUST equal the To
706  * header field in the response being acknowledged. The ACK MUST contain the
707  * top Via header field of the original request.  The CSeq header field in
708  * the ACK MUST contain the same value for the sequence number as was
709  * present in the original request, but the method parameter MUST be equal
710  * to "ACK".
711  */
712 int
sip_create_nonOKack(sip_msg_t request,sip_msg_t response,sip_msg_t ack_msg)713 sip_create_nonOKack(sip_msg_t request, sip_msg_t response, sip_msg_t ack_msg)
714 {
715 	int		seqno;
716 	char		*uri;
717 	_sip_msg_t	*_request;
718 	_sip_msg_t	*_response;
719 	_sip_msg_t	*_ack_msg;
720 	int		ret;
721 
722 	if (request == NULL || response == NULL || ack_msg == NULL ||
723 	    request == ack_msg) {
724 		return (EINVAL);
725 	}
726 	_request = (_sip_msg_t *)request;
727 	_response = (_sip_msg_t *)response;
728 	_ack_msg = (_sip_msg_t *)ack_msg;
729 
730 	(void) pthread_mutex_lock(&_request->sip_msg_mutex);
731 	if (_request->sip_msg_req_res == NULL) {
732 		if ((ret = sip_parse_first_line(_request->sip_msg_start_line,
733 		    &_request->sip_msg_req_res)) != 0) {
734 			(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
735 			return (ret);
736 		}
737 	}
738 	if (_request->sip_msg_req_res->U.sip_request.sip_request_uri.
739 	    sip_str_ptr == NULL) {
740 		(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
741 		return (EINVAL);
742 	}
743 	uri = (char *)malloc(_request->sip_msg_req_res->U.sip_request.
744 	    sip_request_uri.sip_str_len + 1);
745 	if (uri == NULL) {
746 		(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
747 		return (EINVAL);
748 	}
749 	(void) strncpy(uri,
750 	    _request->sip_msg_req_res->U.sip_request.sip_request_uri.
751 	    sip_str_ptr, _request->sip_msg_req_res->U.sip_request.
752 	    sip_request_uri.sip_str_len);
753 	uri[_request->sip_msg_req_res->U.sip_request.
754 	    sip_request_uri.sip_str_len] = '\0';
755 	if ((ret = sip_add_request_line(_ack_msg, ACK, uri)) != 0) {
756 		(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
757 		return (ret);
758 	}
759 	free(uri);
760 	if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_VIA,
761 	    NULL, B_TRUE)) != 0) {
762 		(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
763 		return (ret);
764 	}
765 	(void) _sip_find_and_copy_header(_request, _ack_msg,
766 	    SIP_MAX_FORWARDS, NULL, B_TRUE);
767 
768 	(void) pthread_mutex_lock(&_response->sip_msg_mutex);
769 	if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_TO,
770 	    NULL, B_TRUE)) != 0) {
771 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
772 		return (ret);
773 	}
774 	(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
775 	if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_FROM,
776 	    NULL, B_TRUE)) != 0) {
777 		(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
778 		return (ret);
779 	}
780 	if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_CALL_ID,
781 	    NULL, B_TRUE)) != 0) {
782 		(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
783 		return (ret);
784 	}
785 	(void) pthread_mutex_unlock(&_request->sip_msg_mutex);
786 	seqno = sip_get_callseq_num(_request, &ret);
787 	if (ret != 0)
788 		return (ret);
789 	if ((ret = sip_add_cseq(_ack_msg, ACK, seqno)) != 0)
790 		return (ret);
791 	if ((ret = sip_adjust_msgbuf(_ack_msg)) != 0)
792 		return (ret);
793 	return (0);
794 }
795 
796 /*
797  * This is a 2XX ACK, for others ACK is constructed differently,
798  * esp. the branch id is retained.
799  */
800 int
sip_create_OKack(sip_msg_t response,sip_msg_t ack_msg,char * transport,char * sent_by,int sent_by_port,char * via_params)801 sip_create_OKack(sip_msg_t response, sip_msg_t ack_msg, char *transport,
802     char *sent_by, int sent_by_port, char *via_params)
803 {
804 	int			seqno;
805 	char			*uri;
806 	sip_parsed_header_t	*parsed_header;
807 	sip_hdr_value_t		*contact_value;
808 	_sip_header_t		*header;
809 	_sip_msg_t		*_response;
810 	_sip_msg_t		*_ack_msg;
811 	int			ret;
812 
813 	if (response == NULL || response == NULL || transport == NULL)
814 		return (EINVAL);
815 	_response = (_sip_msg_t *)response;
816 	_ack_msg = (_sip_msg_t *)ack_msg;
817 
818 	/*
819 	 * Get URI from the response, Contact field
820 	 */
821 	(void) pthread_mutex_lock(&_response->sip_msg_mutex);
822 	if ((header = sip_search_for_header(_response, SIP_CONTACT,
823 	    NULL)) == NULL) {
824 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
825 		return (EINVAL);
826 	}
827 	if ((ret = sip_parse_cftr_header(header, (void *)&parsed_header)) !=
828 	    0) {
829 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
830 		return (ret);
831 	}
832 	contact_value = (sip_hdr_value_t *)parsed_header->value;
833 	if (contact_value->cftr_uri.sip_str_ptr == NULL) {
834 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
835 		return (EINVAL);
836 	}
837 	uri = (char *)malloc(contact_value->cftr_uri.sip_str_len + 1);
838 	if (uri == NULL) {
839 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
840 		return (ENOMEM);
841 	}
842 	(void) strncpy(uri, contact_value->cftr_uri.sip_str_ptr,
843 	    contact_value->cftr_uri.sip_str_len);
844 	uri[contact_value->cftr_uri.sip_str_len] = '\0';
845 	if ((ret = sip_add_request_line(_ack_msg, ACK, uri)) != 0) {
846 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
847 		return (ret);
848 	}
849 	free(uri);
850 	if ((ret = sip_add_via(_ack_msg, transport, sent_by, sent_by_port,
851 	    via_params)) != 0) {
852 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
853 		return (ret);
854 	}
855 
856 	if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_TO,
857 	    NULL, B_TRUE)) != 0) {
858 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
859 		return (ret);
860 	}
861 	if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_FROM,
862 	    NULL, B_TRUE)) != 0) {
863 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
864 		return (ret);
865 	}
866 	if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_CALL_ID,
867 	    NULL, B_TRUE)) != 0) {
868 		(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
869 		return (ret);
870 	}
871 	/*
872 	 * Copy Max-Forward if present
873 	 */
874 	if (sip_search_for_header(_response, SIP_MAX_FORWARDS, NULL) != NULL) {
875 		if ((ret = _sip_find_and_copy_header(_response, _ack_msg,
876 		    SIP_MAX_FORWARDS, NULL, B_TRUE)) != 0) {
877 			(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
878 			return (ret);
879 		}
880 	}
881 	(void) pthread_mutex_unlock(&_response->sip_msg_mutex);
882 	seqno = sip_get_callseq_num(_response, &ret);
883 	if (ret != 0)
884 		return (ret);
885 	if ((ret = sip_add_cseq(_ack_msg, ACK, seqno)) != 0)
886 		return (ret);
887 
888 	return (0);
889 }
890 
891 /*
892  * Request-Line   =  Method SP Request-URI SP SIP-Version CRLF
893  */
894 int
sip_add_request_line(sip_msg_t sip_request,sip_method_t method,char * request_uri)895 sip_add_request_line(sip_msg_t sip_request, sip_method_t method,
896     char *request_uri)
897 {
898 	_sip_header_t	*new_header;
899 	int		 header_size;
900 	_sip_msg_t	*_sip_request;
901 
902 	if (method < INVITE || method >= MAX_SIP_METHODS ||
903 	    request_uri == NULL || sip_request == NULL) {
904 		return (EINVAL);
905 	}
906 
907 	_sip_request = (_sip_msg_t *)sip_request;
908 	(void) pthread_mutex_lock(&_sip_request->sip_msg_mutex);
909 	if (_sip_request->sip_msg_cannot_be_modified) {
910 		(void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex);
911 		return (ENOTSUP);
912 	}
913 
914 	header_size = strlen(sip_methods[method].name) + SIP_SPACE_LEN +
915 	    strlen(request_uri) + SIP_SPACE_LEN + strlen(SIP_VERSION) +
916 	    strlen(SIP_CRLF);
917 
918 	new_header = sip_new_header(header_size);
919 	if (new_header == NULL) {
920 		(void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex);
921 		return (ENOMEM);
922 	}
923 	new_header->sip_hdr_sipmsg = _sip_request;
924 
925 	(void) snprintf(new_header->sip_hdr_start, header_size + 1,
926 	    "%s %s %s%s", sip_methods[method].name, request_uri,
927 	    SIP_VERSION, SIP_CRLF);
928 
929 	new_header->sip_hdr_next = _sip_request->sip_msg_start_line;
930 	_sip_request->sip_msg_start_line = new_header;
931 	_sip_request->sip_msg_len += header_size;
932 	(void) sip_parse_first_line(_sip_request->sip_msg_start_line,
933 	    &_sip_request->sip_msg_req_res);
934 	if (_sip_request->sip_msg_buf != NULL)
935 		_sip_request->sip_msg_modified = B_TRUE;
936 	(void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex);
937 	return (0);
938 }
939