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