2
0

msg.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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. /**@internal @file msg.c Message object implementation.
  25. *
  26. * @author Pekka Pessi <Pekka.Pessi@nokia.com>
  27. *
  28. * @date Created: Thu Jun 8 19:28:55 2000 ppessi
  29. */
  30. #include "config.h"
  31. #include <stddef.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <stdarg.h>
  35. #include <stdio.h>
  36. #include <limits.h>
  37. #include <errno.h>
  38. #include <assert.h>
  39. #include <sofia-sip/su_alloc.h> /* XXX */
  40. #include <sofia-sip/su.h>
  41. #include "msg_internal.h"
  42. #include "sofia-sip/msg_parser.h"
  43. #include "sofia-sip/msg_mclass.h"
  44. /**
  45. * Create a message.
  46. *
  47. * @relatesalso msg_s
  48. *
  49. * @param mc message class
  50. * @param flags message control flags
  51. */
  52. msg_t *msg_create(msg_mclass_t const *mc, int flags)
  53. {
  54. msg_t *msg = su_home_new(sizeof(*msg) + mc->mc_msize);
  55. if (msg) {
  56. if ((flags & MSG_FLG_THRDSAFE) &&
  57. su_home_threadsafe(msg->m_home) < 0) {
  58. su_home_unref(msg->m_home);
  59. return NULL;
  60. }
  61. msg->m_refs++;
  62. msg->m_tail = &msg->m_chain;
  63. msg->m_addrinfo.ai_addrlen = sizeof(msg->m_addr);
  64. msg->m_addrinfo.ai_addr = &msg->m_addr->su_sa;
  65. msg->m_maxsize = 0;
  66. flags &= MSG_FLG_USERMASK;
  67. msg->m_class = mc;
  68. msg->m_oflags = flags;
  69. msg->m_object = (void *)(msg + 1);
  70. msg->m_object->msg_size = mc->mc_msize;
  71. msg->m_object->msg_flags = mc->mc_flags | flags;
  72. msg->m_object->msg_common->h_class = (void *)mc;
  73. }
  74. return msg;
  75. }
  76. /**Increment a message reference count.
  77. *
  78. * @relatesalso msg_s
  79. *
  80. * Creates a reference to a message. The
  81. * referenced message is not freed until all the references have been
  82. * destroyed.
  83. *
  84. * @param msg message of which a reference is created
  85. *
  86. * @return
  87. * A pointer to a message.
  88. */
  89. msg_t *msg_ref_create(msg_t *msg)
  90. {
  91. if (msg) {
  92. su_home_mutex_lock(msg->m_home);
  93. msg->m_refs++;
  94. su_home_mutex_unlock(msg->m_home);
  95. }
  96. return msg;
  97. }
  98. /**Set a message parent.
  99. *
  100. * @relatesalso msg_s
  101. *
  102. * Set a parent for a message. The parent message is not destroyed until all
  103. * its kids have been destroyed - each kid keeps a reference to its parent
  104. * message.
  105. *
  106. * @param kid child message
  107. * @param dad parent message
  108. */
  109. void msg_set_parent(msg_t *kid, msg_t *dad)
  110. {
  111. if (kid) {
  112. msg_t *step_dad = kid->m_parent;
  113. if (dad && step_dad && step_dad != dad)
  114. msg_ref_destroy(step_dad);
  115. kid->m_parent = msg_ref_create(dad);
  116. }
  117. }
  118. /** Destroy a reference to a message.
  119. *
  120. * @relatesalso msg_s
  121. *
  122. * @param ref pointer to msg object
  123. *
  124. * @deprecated Use msg_destroy() instead.
  125. */
  126. void msg_ref_destroy(msg_t *ref)
  127. {
  128. msg_destroy(ref);
  129. }
  130. /**Deinitialize and free a message.
  131. *
  132. * @relatesalso msg_s
  133. *
  134. * @param msg message to be destroyed
  135. */
  136. void msg_destroy(msg_t *msg)
  137. {
  138. msg_t *parent;
  139. for (; msg; msg = parent) {
  140. int refs;
  141. su_home_mutex_lock(msg->m_home);
  142. parent = msg->m_parent;
  143. if (msg->m_refs)
  144. msg->m_refs--;
  145. refs = msg->m_refs;
  146. su_home_mutex_unlock(msg->m_home);
  147. if (refs)
  148. break;
  149. su_home_zap(msg->m_home);
  150. }
  151. }
  152. /* Message object routines */
  153. /**Retrieve public message structure.
  154. *
  155. * Get a pointer to the public message structure.
  156. *
  157. * @param msg pointer to msg object
  158. *
  159. * @returns
  160. * A pointer to the public message structure, or NULL if none.
  161. */
  162. msg_pub_t *msg_object(msg_t const *msg)
  163. {
  164. if (msg)
  165. return msg->m_object;
  166. else
  167. return NULL;
  168. }
  169. /**Retrieve public message structure of given type.
  170. *
  171. * @relatesalso msg_s
  172. *
  173. * Get a pointer to the public message structure of the
  174. * given protocol.
  175. *
  176. * @param msg pointer to msg object
  177. * @param tag tag of public message structure
  178. *
  179. * @returns
  180. * A pointer to the public message structure, or NULL if there is none or
  181. * the message is not for desired protocol.
  182. */
  183. msg_pub_t *msg_public(msg_t const *msg, void *tag)
  184. {
  185. if (msg && msg->m_class->mc_tag == tag)
  186. return msg->m_object;
  187. else
  188. return NULL;
  189. }
  190. /**Retrieve message class.
  191. *
  192. * @relatesalso msg_s
  193. *
  194. * Get a pointer to the message class object
  195. * (factory object for the message).
  196. *
  197. * @param msg pointer to msg object
  198. *
  199. * @returns
  200. * A pointer to the message class, or NULL if none.
  201. */
  202. msg_mclass_t const *msg_mclass(msg_t const *msg)
  203. {
  204. if (msg)
  205. return msg->m_class;
  206. else
  207. return NULL;
  208. }
  209. /* Address management */
  210. /** Zero the message address.
  211. *
  212. * @relatesalso msg_s
  213. *
  214. * Zero the address and addressinfo structures associated with the message.
  215. *
  216. * @sa msg_addrinfo(), msg_set_address(), msg_get_address(), msg_addr_copy().
  217. */
  218. void msg_addr_zero(msg_t *msg)
  219. {
  220. memset(&msg->m_addr, 0, sizeof(msg->m_addr));
  221. memset(&msg->m_addrinfo, 0, sizeof(msg->m_addrinfo));
  222. msg->m_addrinfo.ai_addrlen = sizeof(msg->m_addr);
  223. msg->m_addrinfo.ai_addr = &msg->m_addr->su_sa;
  224. }
  225. /** Get pointer to socket address structure.
  226. *
  227. * @relatesalso msg_s
  228. *
  229. * @deprecated Use msg_get_address() or msg_set_address() instead.
  230. */
  231. su_sockaddr_t *msg_addr(msg_t *msg)
  232. {
  233. return msg ? msg->m_addr : 0;
  234. }
  235. /** Get message address.
  236. *
  237. * @relatesalso msg_s
  238. *
  239. * Copy the socket address associated with the message to the supplied
  240. * socket address struture.
  241. *
  242. * @param msg pointer to msg object
  243. * @param su pointer to socket address structure
  244. * @param return_len return parameter value for length
  245. * of socket address structure
  246. *
  247. * @sa msg_addrinfo(), msg_set_address(), msg_addr_zero(), msg_addr_copy().
  248. */
  249. int msg_get_address(msg_t *msg, su_sockaddr_t *su, socklen_t *return_len)
  250. {
  251. if (msg && return_len && *return_len >= msg->m_addrinfo.ai_addrlen) {
  252. *return_len = (socklen_t)msg->m_addrinfo.ai_addrlen;
  253. if (su)
  254. memcpy(su, msg->m_addr, msg->m_addrinfo.ai_addrlen);
  255. return 0;
  256. }
  257. if (msg)
  258. msg->m_errno = EFAULT;
  259. return -1;
  260. }
  261. /** Set message address.
  262. *
  263. * @relatesalso msg_s
  264. *
  265. * Copy the supplied socket address to the socket address structure
  266. * associated with the message.
  267. *
  268. * @param msg pointer to msg object
  269. * @param su pointer to socket address structure
  270. * @param sulen length of socket address structure
  271. *
  272. * @sa msg_addrinfo(), msg_get_address(), msg_addr_zero(), msg_addr_copy().
  273. */
  274. int msg_set_address(msg_t *msg, su_sockaddr_t const *su, socklen_t sulen)
  275. {
  276. if (sulen < (sizeof msg->m_addr) && msg && su) {
  277. memcpy(msg->m_addr, su, msg->m_addrinfo.ai_addrlen = sulen);
  278. msg->m_addrinfo.ai_family = su->su_family;
  279. return 0;
  280. }
  281. if (msg)
  282. msg->m_errno = EFAULT;
  283. return -1;
  284. }
  285. /** Get addrinfo structure.
  286. *
  287. * @relatesalso msg_s
  288. *
  289. * Get pointer to the addrinfo structure associated with the message.
  290. *
  291. * @param msg pointer to msg object
  292. *
  293. * @retval pointer to addrinfo structure
  294. * @retval NULL if msg is NULL
  295. *
  296. * @sa msg_get_address(), msg_set_address(), msg_addr_zero(), msg_addr_copy().
  297. */
  298. su_addrinfo_t *msg_addrinfo(msg_t *msg)
  299. {
  300. return msg ? &msg->m_addrinfo : 0;
  301. }
  302. /**Copy message address.
  303. *
  304. * @relatesalso msg_s
  305. *
  306. * Copy the addrinfo and socket address structures from @a src to the @a dst
  307. * message object.
  308. *
  309. * @param dst pointer to destination message object
  310. * @param src pointer to source message object
  311. *
  312. * @sa msg_addrinfo(), msg_get_address(), msg_set_address(), msg_addr_zero().
  313. */
  314. void msg_addr_copy(msg_t *dst, msg_t const *src)
  315. {
  316. dst->m_addrinfo = src->m_addrinfo;
  317. dst->m_addrinfo.ai_next = NULL;
  318. dst->m_addrinfo.ai_canonname = NULL;
  319. memcpy(dst->m_addrinfo.ai_addr = &dst->m_addr->su_sa,
  320. src->m_addr, src->m_addrinfo.ai_addrlen);
  321. if (dst->m_addrinfo.ai_addrlen < sizeof(dst->m_addr))
  322. memset((char *)dst->m_addr + dst->m_addrinfo.ai_addrlen, 0,
  323. sizeof(dst->m_addr) - dst->m_addrinfo.ai_addrlen);
  324. }
  325. /** Get error classification flags.
  326. *
  327. * @relatesalso msg_s
  328. *
  329. * If the message parser fails to parse certain headers in the message, it
  330. * sets the corresponding extract error flags. The flags corresponding to
  331. * each header are stored in the message parser (msg_mclass_t) structure.
  332. * They are set when the header is added to the parser table.
  333. *
  334. * The SIP flags are defined in <sofia-sip/sip_headers.h>. For well-known
  335. * SIP headers, the flags for each header are listed in a separate text file
  336. * (sip_bad_mask) read by msg_parser.awk.
  337. *
  338. * The flags can be used directly by NTA (the mask triggering 400 response
  339. * is set with NTATAG_BAD_REQ_MASK(), the mask triggering response messages
  340. * to be dropped is set with NTATAG_BAD_RESP_MASK()). Alternatively the
  341. * application can check them based on the method or required SIP features.
  342. *
  343. * @sa msg_mclass_insert_with_mask(), NTATAG_BAD_REQ_MASK(),
  344. * NTATAG_BAD_RESP_MASK().
  345. */
  346. unsigned msg_extract_errors(msg_t const *msg)
  347. {
  348. return msg ? msg->m_extract_err : (unsigned)-1;
  349. }
  350. /** Get error number associated with message.
  351. *
  352. * @relatesalso msg_s
  353. *
  354. * @param msg pointer to msg object
  355. *
  356. */
  357. int msg_errno(msg_t const *msg)
  358. {
  359. return msg ? msg->m_errno : EINVAL;
  360. }
  361. /** Set error number associated with message.
  362. *
  363. * @relatesalso msg_s
  364. *
  365. * @param msg pointer to msg object
  366. * @param err error value (as defined in <sofia-sip/su_errno.h>).
  367. *
  368. */
  369. void msg_set_errno(msg_t *msg, int err)
  370. {
  371. if (msg)
  372. msg->m_errno = err;
  373. }