sip_parser.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@ingroup sip_parser
  25. * @CFILE sip_parser.c
  26. *
  27. * SIP parser.
  28. *
  29. * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
  30. *
  31. * @date Created: Thu Oct 5 14:01:24 2000 ppessi
  32. */
  33. #include "config.h"
  34. /* Avoid casting sip_t to msg_pub_t and sip_header_t to msg_header_t */
  35. #define MSG_PUB_T struct sip_s
  36. #define MSG_HDR_T union sip_header_u
  37. #include <sofia-sip/su_tagarg.h>
  38. #include <sofia-sip/su_string.h>
  39. #include "sofia-sip/sip_parser.h"
  40. #include <sofia-sip/msg_mclass.h>
  41. #include <stddef.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <stdio.h>
  45. #include <assert.h>
  46. #include <limits.h>
  47. #ifndef UINT32_MAX
  48. #define UINT32_MAX (0xffffffffU)
  49. #endif
  50. /** Version of the SIP module */
  51. char const sip_parser_version[] = VERSION;
  52. /** SIP version 2.0. */
  53. char const sip_version_2_0[] = "SIP/2.0";
  54. /** Default message class */
  55. extern msg_mclass_t sip_mclass[];
  56. static msg_mclass_t const *_default = sip_mclass;
  57. static msg_mclass_t *_default_parser_cloned = NULL;
  58. /** Return a built-in SIP parser object. */
  59. msg_mclass_t const *sip_default_mclass(void)
  60. {
  61. return _default;
  62. }
  63. /** Restore default SIP parser to non-extended */
  64. void sip_default_mclass_restore(void) {
  65. _default = sip_mclass;
  66. }
  67. /** Destroy SIP parser object */
  68. void sip_destroy_mclass(msg_mclass_t *mclass) {
  69. if (mclass && mclass != sip_mclass) {
  70. if (mclass == _default_parser_cloned) {
  71. sip_cloned_parser_destroy();
  72. } else {
  73. if (mclass == _default) {
  74. sip_default_mclass_restore();
  75. }
  76. free(mclass);
  77. }
  78. }
  79. }
  80. /** Release SIP parser object if it was cloned. */
  81. void sip_cloned_parser_destroy(void)
  82. {
  83. if (_default_parser_cloned) {
  84. if (_default_parser_cloned == _default) {
  85. sip_default_mclass_restore();
  86. }
  87. free(_default_parser_cloned);
  88. _default_parser_cloned = NULL;
  89. }
  90. }
  91. /** Update the default SIP parser.
  92. *
  93. * Use the extended SIP parser as default one.
  94. *
  95. * If the applications want to use headers added after @VERSION_1_12_5,
  96. * they should call this function before doing any other initialization, e.g.,
  97. * @code
  98. * su_init();
  99. * if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
  100. * su_deinit();
  101. * exit(2);
  102. * }
  103. * @endcode
  104. * When finish don't forget to call
  105. * @code
  106. * sip_destroy_mclass(sip_default_mclass());
  107. * @endcode
  108. * as return of sip_extend_mclass(NULL) requires to be freed.
  109. *
  110. * The default parser is not extended because it may break the old
  111. * applications looking for extension headers from sip_unknown list.
  112. *
  113. * @retval 0 when successful
  114. * @retval -1 upon an error
  115. *
  116. * @sa sip_extend_mclass()
  117. *
  118. * @NEW_1_12_7.
  119. */
  120. int sip_update_default_mclass(msg_mclass_t const *mclass)
  121. {
  122. if (mclass == NULL)
  123. return -1;
  124. _default = mclass;
  125. return 0;
  126. }
  127. /**Extend SIP parser class with extension headers.
  128. *
  129. * Extend given SIP parser class with extension headers. If the given parser
  130. * (message class) is the default one or NULL, make a clone of default
  131. * parser before extending it.
  132. *
  133. * @param input pointer to a SIP message class (may be NULL)
  134. *
  135. * @return Pointer to extended mclass, or NULL upon an error.
  136. *
  137. * @sa
  138. * @AlertInfo,
  139. * @ReplyTo,
  140. * @RemotePartyId,
  141. * @PAssertedIdentity,
  142. * @PPreferredIdentity,
  143. * @SuppressBodyIfMatch,
  144. * @SuppressNotifyIfMatch
  145. *
  146. * @NEW_1_12_7.
  147. */
  148. msg_mclass_t *sip_extend_mclass(msg_mclass_t *input)
  149. {
  150. msg_mclass_t *mclass;
  151. if (input == NULL || input == _default) {
  152. _default_parser_cloned = msg_mclass_clone(_default, 0, 0);
  153. mclass = _default_parser_cloned;
  154. } else {
  155. mclass = input;
  156. }
  157. if (mclass) {
  158. extern msg_hclass_t * const sip_extensions[];
  159. int i;
  160. for (i = 0; sip_extensions[i]; i++) {
  161. msg_hclass_t *hclass = sip_extensions[i];
  162. if (mclass->mc_unknown != msg_find_hclass(mclass, hclass->hc_name, NULL))
  163. continue;
  164. if (msg_mclass_insert_header(mclass, hclass, 0) < 0) {
  165. if (input != mclass) {
  166. sip_destroy_mclass(mclass);
  167. }
  168. return mclass = NULL;
  169. }
  170. }
  171. }
  172. return mclass;
  173. }
  174. /** Extract the SIP message body, including separator line.
  175. *
  176. * @param msg message object [IN]
  177. * @param sip public SIP message structure [IN/OUT]
  178. * @param b buffer containing unparsed data [IN]
  179. * @param bsiz buffer size [IN]
  180. * @param eos true if buffer contains whole message [IN]
  181. *
  182. * @retval -1 error
  183. * @retval 0 cannot proceed
  184. * @retval m
  185. */
  186. issize_t sip_extract_body(msg_t *msg, sip_t *sip, char b[], isize_t bsiz, int eos)
  187. {
  188. ssize_t m = 0;
  189. size_t body_len;
  190. if (!(sip->sip_flags & MSG_FLG_BODY)) {
  191. /* We are looking at a potential empty line */
  192. m = msg_extract_separator(msg, (msg_pub_t *)sip, b, bsiz, eos);
  193. if (m <= 0)
  194. return m;
  195. sip->sip_flags |= MSG_FLG_BODY;
  196. b += m;
  197. bsiz -= m;
  198. }
  199. if (sip->sip_content_length)
  200. body_len = sip->sip_content_length->l_length;
  201. else if (MSG_IS_MAILBOX(sip->sip_flags)) /* message fragments */
  202. body_len = 0;
  203. else if (eos)
  204. body_len = bsiz;
  205. else if (bsiz == 0)
  206. return m;
  207. else
  208. return -1;
  209. if (body_len == 0) {
  210. sip->sip_flags |= MSG_FLG_COMPLETE;
  211. return m;
  212. }
  213. if (m)
  214. return m;
  215. if (eos && body_len > bsiz) {
  216. sip->sip_flags |= MSG_FLG_TRUNC | MSG_FLG_ERROR;
  217. return bsiz;
  218. }
  219. if ((m = msg_extract_payload(msg, (msg_pub_t *)sip,
  220. NULL, body_len, b, bsiz, eos)) == -1)
  221. return -1;
  222. sip->sip_flags |= MSG_FLG_FRAGS;
  223. if (bsiz >= body_len)
  224. sip->sip_flags |= MSG_FLG_COMPLETE;
  225. return m;
  226. }
  227. /** Parse SIP version.
  228. *
  229. * Parse a SIP version string. Update the
  230. * pointer at @a ss to first non-LWS character after the version string.
  231. *
  232. * @param ss string to be parsed [IN/OUT]
  233. * @param ver value result for version [OUT]
  234. *
  235. * @retval 0 when successful,
  236. * @retval -1 upon an error.
  237. */
  238. int sip_version_d(char **ss, char const **ver)
  239. {
  240. char *s = *ss;
  241. char const *result;
  242. size_t const version_size = sizeof(sip_version_2_0) - 1;
  243. if (su_casenmatch(s, sip_version_2_0, version_size) &&
  244. !IS_TOKEN(s[version_size])) {
  245. result = sip_version_2_0;
  246. s += version_size;
  247. }
  248. else {
  249. /* Version consists of two tokens, separated by / */
  250. size_t l1 = 0, l2 = 0, n;
  251. result = s;
  252. l1 = span_token(s);
  253. for (n = l1; IS_LWS(s[n]); n++)
  254. {}
  255. if (s[n] == '/') {
  256. for (n++; IS_LWS(s[n]); n++)
  257. {}
  258. l2 = span_token(s + n);
  259. n += l2;
  260. }
  261. if (l1 == 0 || l2 == 0)
  262. return -1;
  263. /* If there is extra ws between tokens, compact version */
  264. if (n > l1 + 1 + l2) {
  265. s[l1] = '/';
  266. memmove(s + l1 + 1, s + n - l2, l2);
  267. s[l1 + 1 + l2] = 0;
  268. /* Compare again with compacted version */
  269. if (su_casematch(s, sip_version_2_0))
  270. result = sip_version_2_0;
  271. }
  272. s += n;
  273. }
  274. while (IS_WS(*s)) *s++ = '\0';
  275. *ss = s;
  276. if (ver)
  277. *ver = result;
  278. return 0;
  279. }
  280. /** Calculate extra space required by version string */
  281. isize_t sip_version_xtra(char const *version)
  282. {
  283. if (version == SIP_VERSION_CURRENT)
  284. return 0;
  285. return MSG_STRING_SIZE(version);
  286. }
  287. /** Duplicate a transport string */
  288. void sip_version_dup(char **pp, char const **dd, char const *s)
  289. {
  290. if (s == SIP_VERSION_CURRENT)
  291. *dd = s;
  292. else
  293. MSG_STRING_DUP(*pp, *dd, s);
  294. }
  295. char const sip_method_name_invite[] = "INVITE";
  296. char const sip_method_name_ack[] = "ACK";
  297. char const sip_method_name_cancel[] = "CANCEL";
  298. char const sip_method_name_bye[] = "BYE";
  299. char const sip_method_name_options[] = "OPTIONS";
  300. char const sip_method_name_register[] = "REGISTER";
  301. char const sip_method_name_info[] = "INFO";
  302. char const sip_method_name_prack[] = "PRACK";
  303. char const sip_method_name_update[] = "UPDATE";
  304. char const sip_method_name_message[] = "MESSAGE";
  305. char const sip_method_name_subscribe[] = "SUBSCRIBE";
  306. char const sip_method_name_notify[] = "NOTIFY";
  307. char const sip_method_name_refer[] = "REFER";
  308. char const sip_method_name_publish[] = "PUBLISH";
  309. /** Well-known SIP method names. */
  310. char const * const sip_method_names[] = {
  311. "<UNKNOWN>",
  312. sip_method_name_invite,
  313. sip_method_name_ack,
  314. sip_method_name_cancel,
  315. sip_method_name_bye,
  316. sip_method_name_options,
  317. sip_method_name_register,
  318. sip_method_name_info,
  319. sip_method_name_prack,
  320. sip_method_name_update,
  321. sip_method_name_message,
  322. sip_method_name_subscribe,
  323. sip_method_name_notify,
  324. sip_method_name_refer,
  325. sip_method_name_publish,
  326. /* If you add something here, add also them to sip_method_d! */
  327. NULL
  328. };
  329. /** Get canonic method name. */
  330. char const *sip_method_name(sip_method_t method, char const *name)
  331. {
  332. const size_t N = sizeof(sip_method_names)/sizeof(sip_method_names[0]);
  333. if (method > 0 && (size_t)method < N)
  334. return sip_method_names[method];
  335. else if (method == 0)
  336. return name;
  337. else
  338. return NULL;
  339. }
  340. /**Parse a SIP method name.
  341. *
  342. * Parse a SIP method name and return a code corresponding to the method.
  343. * The address of the first non-LWS character after method name is stored in
  344. * @a *ss.
  345. *
  346. * @param ss pointer to pointer to string to be parsed
  347. * @param return_name value-result parameter for method name
  348. *
  349. * @note
  350. * If there is no whitespace after method name, the value in @a *return_name
  351. * may not be NUL-terminated. The calling function @b must NUL terminate
  352. * the value by setting the @a **ss to NUL after first examining its value.
  353. *
  354. * @return The method code if method
  355. * was identified, 0 (sip_method_unknown()) if method is not known, or @c -1
  356. * (sip_method_invalid()) if an error occurred.
  357. *
  358. * If the value-result argument @a return_name is not @c NULL,
  359. * a pointer to the method name is stored to it.
  360. */
  361. sip_method_t sip_method_d(char **ss, char const **return_name)
  362. {
  363. char *s = *ss, c = *s;
  364. char const *name;
  365. int code = sip_method_unknown;
  366. size_t n = 0;
  367. #define MATCH(s, m) (strncmp(s, m, n = sizeof(m) - 1) == 0)
  368. switch (c) {
  369. case 'A': if (MATCH(s, "ACK")) code = sip_method_ack; break;
  370. case 'B': if (MATCH(s, "BYE")) code = sip_method_bye; break;
  371. case 'C':
  372. if (MATCH(s, "CANCEL"))
  373. code = sip_method_cancel;
  374. break;
  375. case 'I':
  376. if (MATCH(s, "INVITE"))
  377. code = sip_method_invite;
  378. else if (MATCH(s, "INFO"))
  379. code = sip_method_info;
  380. break;
  381. case 'M': if (MATCH(s, "MESSAGE")) code = sip_method_message; break;
  382. case 'N': if (MATCH(s, "NOTIFY")) code = sip_method_notify; break;
  383. case 'O': if (MATCH(s, "OPTIONS")) code = sip_method_options; break;
  384. case 'P':
  385. if (MATCH(s, "PRACK")) code = sip_method_prack;
  386. else if (MATCH(s, "PUBLISH")) code = sip_method_publish;
  387. break;
  388. case 'R':
  389. if (MATCH(s, "REGISTER"))
  390. code = sip_method_register;
  391. else if (MATCH(s, "REFER"))
  392. code = sip_method_refer;
  393. break;
  394. case 'S':
  395. if (MATCH(s, "SUBSCRIBE"))
  396. code = sip_method_subscribe;
  397. break;
  398. case 'U':
  399. if (MATCH(s, "UPDATE"))
  400. code = sip_method_update;
  401. break;
  402. }
  403. #undef MATCH
  404. if (strlen(s) < n) {
  405. return sip_method_invalid;
  406. }
  407. if (IS_NON_WS(s[n]))
  408. /* Unknown method */
  409. code = sip_method_unknown;
  410. if (code == sip_method_unknown) {
  411. name = s;
  412. for (n = 0; IS_UNRESERVED(s[n]); n++)
  413. ;
  414. if (s[n]) {
  415. if (!IS_LWS(s[n]))
  416. return sip_method_invalid;
  417. if (return_name)
  418. s[n++] = '\0';
  419. }
  420. }
  421. else {
  422. name = sip_method_names[code];
  423. }
  424. while (IS_LWS(s[n]))
  425. n++;
  426. *ss = (s + n);
  427. if (return_name) *return_name = name;
  428. return (sip_method_t)code;
  429. }
  430. /** Get method enum corresponding to method name */
  431. sip_method_t sip_method_code(char const *name)
  432. {
  433. /* Note that sip_method_d() does not change string if return_name is NULL */
  434. return sip_method_d((char **)&name, NULL);
  435. }
  436. char const sip_transport_udp[] = "SIP/2.0/UDP";
  437. char const sip_transport_tcp[] = "SIP/2.0/TCP";
  438. char const sip_transport_sctp[] = "SIP/2.0/SCTP";
  439. char const sip_transport_ws[] = "SIP/2.0/WS";
  440. char const sip_transport_wss[] = "SIP/2.0/WSS";
  441. char const sip_transport_tls[] = "SIP/2.0/TLS";
  442. /** Decode transport */
  443. issize_t sip_transport_d(char **ss, char const **ttransport)
  444. {
  445. char const *transport;
  446. char *pn, *pv, *pt;
  447. size_t pn_len, pv_len, pt_len;
  448. char *s = *ss;
  449. #define TRANSPORT_MATCH(t) \
  450. (su_casenmatch(s + 7, t + 7, (sizeof t) - 8) && \
  451. (!s[sizeof(t) - 1] || IS_LWS(s[sizeof(t) - 1])) \
  452. && (transport = t, s += sizeof(t) - 1))
  453. if (!su_casenmatch(s, "SIP/2.0", 7) ||
  454. (!TRANSPORT_MATCH(sip_transport_udp) &&
  455. !TRANSPORT_MATCH(sip_transport_tcp) &&
  456. !TRANSPORT_MATCH(sip_transport_sctp) &&
  457. !TRANSPORT_MATCH(sip_transport_ws) &&
  458. !TRANSPORT_MATCH(sip_transport_wss) &&
  459. !TRANSPORT_MATCH(sip_transport_tls))) {
  460. /* Protocol name */
  461. transport = pn = s;
  462. skip_token(&s);
  463. pn_len = s - pn;
  464. skip_lws(&s);
  465. if (pn_len == 0 || *s++ != '/') return -1;
  466. skip_lws(&s);
  467. /* Protocol version */
  468. pv = s;
  469. skip_token(&s);
  470. pv_len = s - pv;
  471. skip_lws(&s);
  472. if (pv_len == 0 || *s++ != '/') return -1;
  473. skip_lws(&s);
  474. /* Transport protocol */
  475. pt = s;
  476. skip_token(&s);
  477. pt_len = s - pt;
  478. if (pt_len == 0) return -1;
  479. /* Remove whitespace between protocol name and version */
  480. if (pn + pn_len + 1 != pv) {
  481. pn[pn_len] = '/';
  482. pv = memmove(pn + pn_len + 1, pv, pv_len);
  483. }
  484. /* Remove whitespace between protocol version and transport */
  485. if (pv + pv_len + 1 != pt) {
  486. pv[pv_len] = '/';
  487. pt = memmove(pv + pv_len + 1, pt, pt_len);
  488. pt[pt_len] = '\0';
  489. /* extra whitespace? */
  490. if (su_casematch(transport, sip_transport_udp))
  491. transport = sip_transport_udp;
  492. else if (su_casematch(transport, sip_transport_tcp))
  493. transport = sip_transport_tcp;
  494. else if (su_casematch(transport, sip_transport_sctp))
  495. transport = sip_transport_sctp;
  496. else if (su_casematch(transport, sip_transport_ws))
  497. transport = sip_transport_ws;
  498. else if (su_casematch(transport, sip_transport_wss))
  499. transport = sip_transport_wss;
  500. else if (su_casematch(transport, sip_transport_tls))
  501. transport = sip_transport_tls;
  502. }
  503. }
  504. if (IS_LWS(*s)) { *s++ = '\0'; skip_lws(&s); }
  505. *ss = s;
  506. *ttransport = transport;
  507. return 0;
  508. }
  509. /** Calculate extra space required by sip_transport_dup() */
  510. isize_t sip_transport_xtra(char const *transport)
  511. {
  512. if (transport == sip_transport_udp ||
  513. transport == sip_transport_tcp ||
  514. transport == sip_transport_sctp ||
  515. transport == sip_transport_ws ||
  516. transport == sip_transport_wss ||
  517. transport == sip_transport_tls ||
  518. su_casematch(transport, sip_transport_udp) ||
  519. su_casematch(transport, sip_transport_tcp) ||
  520. su_casematch(transport, sip_transport_sctp) ||
  521. su_casematch(transport, sip_transport_ws) ||
  522. su_casematch(transport, sip_transport_wss) ||
  523. su_casematch(transport, sip_transport_tls))
  524. return 0;
  525. return MSG_STRING_SIZE(transport);
  526. }
  527. /** Duplicate a transport string */
  528. void sip_transport_dup(char **pp, char const **dd, char const *s)
  529. {
  530. if (s == sip_transport_udp)
  531. *dd = s;
  532. else if (s == sip_transport_tcp)
  533. *dd = s;
  534. else if (s == sip_transport_sctp)
  535. *dd = s;
  536. else if (s == sip_transport_tls)
  537. *dd = s;
  538. else if (s == sip_transport_ws)
  539. *dd = s;
  540. else if (s == sip_transport_wss)
  541. *dd = s;
  542. else if (su_casematch(s, sip_transport_udp))
  543. *dd = sip_transport_udp;
  544. else if (su_casematch(s, sip_transport_tcp))
  545. *dd = sip_transport_tcp;
  546. else if (su_casematch(s, sip_transport_sctp))
  547. *dd = sip_transport_sctp;
  548. else if (su_casematch(s, sip_transport_tls))
  549. *dd = sip_transport_tls;
  550. else if (su_casematch(s, sip_transport_ws))
  551. *dd = sip_transport_ws;
  552. else if (su_casematch(s, sip_transport_wss))
  553. *dd = sip_transport_wss;
  554. else
  555. MSG_STRING_DUP(*pp, *dd, s);
  556. }
  557. /** Parse SIP <word "@" word> construct used in @CallID. */
  558. char *sip_word_at_word_d(char **ss)
  559. {
  560. char *rv = *ss, *s0 = *ss;
  561. skip_word(ss);
  562. if (s0 == *ss)
  563. return NULL;
  564. if (**ss == '@') {
  565. (*ss)++;
  566. s0 = *ss;
  567. skip_word(ss);
  568. if (s0 == *ss)
  569. return NULL;
  570. }
  571. if (IS_LWS(**ss))
  572. (*ss)++;
  573. skip_lws(ss);
  574. return rv;
  575. }
  576. /**Add message separator, then test if message is complete.
  577. *
  578. * Add sip_content_length and sip_separator if they are missing.
  579. * The test that all necessary message components ( @From, @To,
  580. * @CSeq, @CallID, @ContentLength and message separator are present.
  581. *
  582. * @retval 0 when successful
  583. * @retval -1 upon an error: headers are missing and they could not be added
  584. */
  585. int sip_complete_message(msg_t *msg)
  586. {
  587. sip_t *sip = sip_object(msg);
  588. su_home_t *home = msg_home(msg);
  589. size_t len = 0;
  590. ssize_t mplen;
  591. if (sip == NULL)
  592. return -1;
  593. if (!sip->sip_separator)
  594. sip->sip_separator = sip_separator_create(msg_home(msg));
  595. if (sip->sip_multipart) {
  596. sip_content_type_t *c = sip->sip_content_type;
  597. msg_multipart_t *mp = sip->sip_multipart;
  598. sip_common_t *head;
  599. if (!c || msg_multipart_complete(msg_home(msg), c, mp) < 0)
  600. return -1;
  601. if (sip->sip_payload)
  602. head = sip->sip_payload->pl_common;
  603. else
  604. head = sip->sip_separator->sep_common;
  605. if (!head || !msg_multipart_serialize(&head->h_succ, mp))
  606. return -1;
  607. mplen = msg_multipart_prepare(msg, mp, sip->sip_flags);
  608. if (mplen == -1)
  609. return -1;
  610. len = (size_t)mplen;
  611. }
  612. if (sip->sip_payload)
  613. len += sip->sip_payload->pl_len;
  614. if (len > UINT32_MAX)
  615. return -1;
  616. if (!sip->sip_content_length) {
  617. msg_header_insert(msg, (msg_pub_t *)sip, (msg_header_t*)
  618. sip_content_length_create(home, (uint32_t)len));
  619. }
  620. else {
  621. if (sip->sip_content_length->l_length != len) {
  622. sip->sip_content_length->l_length = (uint32_t)len;
  623. sip_fragment_clear(sip->sip_content_length->l_common);
  624. }
  625. }
  626. if (!sip->sip_cseq ||
  627. !sip->sip_call_id ||
  628. !sip->sip_to ||
  629. !sip->sip_from ||
  630. !sip->sip_separator ||
  631. !sip->sip_content_length)
  632. return -1;
  633. return 0;
  634. }