sip_basic.c 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018
  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. /**@CFILE sip_basic.c
  25. * @brief Basic SIP headers.
  26. *
  27. * Implementation of header classes for basic SIP headers, like request and
  28. * status lines, payload, @CallID, @CSeq, @Contact, @ContentLength, @Date,
  29. * @Expires, @From, @Route, @RecordRoute, @To, and @Via.
  30. *
  31. * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
  32. *
  33. * @date Created: Tue Jun 13 02:57:51 2000 ppessi
  34. */
  35. #include "config.h"
  36. /* Avoid casting sip_t to msg_pub_t and sip_header_t to msg_header_t */
  37. #define MSG_PUB_T struct sip_s
  38. #define MSG_HDR_T union sip_header_u
  39. #include <sofia-sip/su_alloc.h>
  40. #include <sofia-sip/su_string.h>
  41. #include "sofia-sip/sip_parser.h"
  42. #include <sofia-sip/sip_util.h>
  43. #include <sofia-sip/sip_status.h>
  44. #include <sofia-sip/msg_date.h>
  45. #include <sofia-sip/su_uniqueid.h>
  46. #include <stddef.h>
  47. #include <stdlib.h>
  48. #include <assert.h>
  49. #include <stdio.h>
  50. #include <stdarg.h>
  51. #include <limits.h>
  52. /* ====================================================================== */
  53. /**@SIP_HEADER sip_request Request Line
  54. *
  55. * The request line is first line in a SIP request message. Its syntax defined
  56. * in @RFC3261 as follows:
  57. *
  58. * @code
  59. * Request-Line = Method SP Request-URI SP SIP-Version CRLF
  60. * Request-URI = SIP-URI / SIPS-URI / absoluteURI
  61. * absoluteURI = scheme ":" ( hier-part / opaque-part )
  62. * hier-part = ( net-path / abs-path ) [ "?" query ]
  63. * net-path = "//" authority [ abs-path ]
  64. * abs-path = "/" path-segments
  65. * opaque-part = uric-no-slash *uric
  66. * uric = reserved / unreserved / escaped
  67. * uric-no-slash = unreserved / escaped / ";" / "?" / ":" / "@"
  68. * / "&" / "=" / "+" / "$" / ","
  69. * path-segments = segment *( "/" segment )
  70. * segment = *pchar *( ";" param )
  71. * param = *pchar
  72. * pchar = unreserved / escaped /
  73. * ":" / "@" / "&" / "=" / "+" / "$" / ","
  74. * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
  75. * authority = srvr / reg-name
  76. * srvr = [ [ userinfo "@" ] hostport ]
  77. * reg-name = 1*( unreserved / escaped / "$" / ","
  78. * / ";" / ":" / "@" / "&" / "=" / "+" )
  79. * query = *uric
  80. * SIP-Version = "SIP" "/" 1*DIGIT "." 1*DIGIT
  81. * @endcode
  82. *
  83. * The parsed request-line is stored in #sip_request_t structure.
  84. */
  85. /**@ingroup sip_request
  86. * @typedef typedef struct sip_request_s sip_request_t;
  87. *
  88. * The structure #sip_request_t contains representation of SIP request line.
  89. *
  90. * The #sip_request_t is defined as follows:
  91. * @code
  92. * typedef struct sip_request_s {
  93. * sip_common_t rq_common[1]; // Common fragment info
  94. * sip_unknown_t *rq_next; // Link to next (dummy)
  95. * sip_method_t rq_method; // Method enum
  96. * char const *rq_method_name; // Method name
  97. * url_t rq_url[1]; // RequestURI
  98. * char const *rq_version; // Protocol version
  99. * } sip_request_t;
  100. * @endcode
  101. */
  102. #define sip_request_insert msg_request_insert
  103. static msg_xtra_f sip_request_dup_xtra;
  104. static msg_dup_f sip_request_dup_one;
  105. #define sip_request_update NULL
  106. msg_hclass_t sip_request_class[] =
  107. SIP_HEADER_CLASS(request, NULL, "", rq_common, single_critical, request);
  108. /**Parse @ref sip_request "request line" from a a SIP message. */
  109. issize_t sip_request_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  110. {
  111. sip_request_t *rq = (sip_request_t *)h;
  112. char *uri, *version;
  113. if (msg_firstline_d(s, &uri, &version) < 0 || !uri || !version ||
  114. (rq->rq_method = sip_method_d(&s, &rq->rq_method_name)) < 0 || *s ||
  115. url_d(rq->rq_url, uri) < 0 ||
  116. sip_version_d(&version, &rq->rq_version) < 0 || *version)
  117. return -1;
  118. return 0;
  119. }
  120. /**Encode @ref sip_request "request line" of a a SIP message. */
  121. issize_t sip_request_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  122. {
  123. sip_request_t const *rq = (sip_request_t *)h;
  124. return snprintf(b, bsiz, "%s " URL_FORMAT_STRING " %s" CRLF,
  125. rq->rq_method_name,
  126. URL_PRINT_ARGS(rq->rq_url),
  127. rq->rq_version);
  128. }
  129. isize_t sip_request_dup_xtra(sip_header_t const *h, isize_t offset)
  130. {
  131. sip_request_t const *rq = (sip_request_t *)h;
  132. offset += url_xtra(rq->rq_url);
  133. if (!rq->rq_method)
  134. offset += MSG_STRING_SIZE(rq->rq_method_name);
  135. offset += sip_version_xtra(rq->rq_version);
  136. return offset;
  137. }
  138. /** Duplicate one request header. */
  139. char *sip_request_dup_one(sip_header_t *dst, sip_header_t const *src,
  140. char *b, isize_t xtra)
  141. {
  142. sip_request_t *rq = (sip_request_t *)dst;
  143. sip_request_t const *o = (sip_request_t *)src;
  144. char *end = b + xtra;
  145. URL_DUP(b, end, rq->rq_url, o->rq_url);
  146. if (!(rq->rq_method = o->rq_method))
  147. MSG_STRING_DUP(b, rq->rq_method_name, o->rq_method_name);
  148. else
  149. rq->rq_method_name = o->rq_method_name;
  150. sip_version_dup(&b, &rq->rq_version, o->rq_version);
  151. assert(b <= end);
  152. return b;
  153. }
  154. /**@ingroup sip_request
  155. *
  156. * Create a @ref sip_request "request line" object.
  157. *
  158. * Create a request line object with
  159. * method enum @a method, method name @a name, request URI @a uri, and
  160. * protocol version @a version. The memory for the header object is
  161. * allocated from the memory home @a home.
  162. *
  163. * @param home memory home used to allocate #sip_request_t object
  164. * @param method method enum
  165. * @param name method name (required if method is not well-known)
  166. * @param uri request URI
  167. * @param version version string (defaults to "SIP/2.0" if NULL)
  168. *
  169. * @par Example
  170. * The following code fragment creates an OPTIONS request object:
  171. * @code
  172. * sip_request_t *rq;
  173. * rq = sip_request_create(home, SIP_METHOD_OPTIONS, requestURI, NULL);
  174. * @endcode
  175. * @note
  176. * If you provide an non-NULL @a version string, it is not copied. The
  177. * version string @b MUST remain constant.
  178. */
  179. sip_request_t *sip_request_create(su_home_t *home,
  180. sip_method_t method, char const *name,
  181. url_string_t const *uri,
  182. char const *version)
  183. {
  184. size_t xtra;
  185. sip_request_t *rq;
  186. if (method)
  187. name = sip_method_name(method, name);
  188. if (!name)
  189. return NULL;
  190. if (!method)
  191. method = sip_method_code(name);
  192. xtra = url_xtra(uri->us_url) + (method ? 0 : strlen(name) + 1);
  193. rq = (sip_request_t *)sip_header_alloc(home, sip_request_class, xtra);
  194. if (rq) {
  195. char *b = (char *)(rq + 1), *end = b + xtra;
  196. rq->rq_method = method;
  197. rq->rq_method_name = name;
  198. if (!method)
  199. MSG_STRING_DUP(b, rq->rq_method_name, name);
  200. URL_DUP(b, end, rq->rq_url, uri->us_url);
  201. rq->rq_version = version ? version : SIP_VERSION_CURRENT;
  202. assert(b == end);
  203. }
  204. return rq;
  205. }
  206. /* ====================================================================== */
  207. /**@SIP_HEADER sip_status Status Line
  208. *
  209. * The status line is first line in a response message. It is defined in
  210. * @RFC3261 as follows:
  211. *
  212. * @code
  213. * Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
  214. * Status-Code = Informational
  215. * / Redirection
  216. * / Success
  217. * / Client-Error
  218. * / Server-Error
  219. * / Global-Failure
  220. * / extension-code
  221. * extension-code = 3DIGIT
  222. * Reason-Phrase = *(reserved / unreserved / escaped
  223. * / UTF8-NONASCII / UTF8-CONT / SP / HTAB)
  224. * @endcode
  225. *
  226. * The parsed status line is stored in #sip_status_t structure.
  227. */
  228. /**@ingroup sip_status
  229. * @typedef typedef struct sip_status_s sip_status_t;
  230. *
  231. * The structure #sip_status_t contains representation of SIP
  232. * @ref sip_status "status line".
  233. *
  234. * The #sip_status_t is defined as follows:
  235. * @code
  236. * typedef struct sip_status_s {
  237. * sip_common_t st_common[1]; // Common fragment info
  238. * sip_unknown_t *st_next; // Link to next (dummy)
  239. * char const *st_version; // Protocol version
  240. * int st_status; // Status code
  241. * char const *st_phrase; // Status phrase
  242. * } sip_status_t;
  243. * @endcode
  244. */
  245. static msg_xtra_f sip_status_dup_xtra;
  246. static msg_dup_f sip_status_dup_one;
  247. #define sip_status_insert msg_status_insert
  248. #define sip_status_update NULL
  249. msg_hclass_t sip_status_class[] =
  250. SIP_HEADER_CLASS(status, NULL, "", st_common, single_critical, status);
  251. /** Parse status line */
  252. issize_t sip_status_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  253. {
  254. sip_status_t *st = (sip_status_t *)h;
  255. char *status, *phrase;
  256. unsigned long code;
  257. if (msg_firstline_d(s, &status, &phrase) < 0 ||
  258. sip_version_d(&s, &st->st_version) < 0 || *s ||
  259. (code = strtoul(status, &status, 10)) >= INT_MAX || *status)
  260. return -1;
  261. st->st_status = code;
  262. st->st_phrase = phrase;
  263. return 0;
  264. }
  265. issize_t sip_status_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  266. {
  267. sip_status_t const *st = (sip_status_t *)h;
  268. int status;
  269. assert(sip_is_status(h));
  270. status = st->st_status;
  271. if (status > 999 || status < 100)
  272. status = 0;
  273. return snprintf(b, bsiz, "%s %03u %s" CRLF,
  274. st->st_version,
  275. status,
  276. st->st_phrase);
  277. }
  278. /** Extra size of a #sip_status_t object. */
  279. isize_t sip_status_dup_xtra(sip_header_t const *h, isize_t offset)
  280. {
  281. sip_status_t const *st = (sip_status_t *)h;
  282. offset += sip_version_xtra(st->st_version);
  283. offset += MSG_STRING_SIZE(st->st_phrase);
  284. return offset;
  285. }
  286. /** Duplicate one status header. */
  287. char *sip_status_dup_one(sip_header_t *dst, sip_header_t const *src,
  288. char *b, isize_t xtra)
  289. {
  290. sip_status_t *st = (sip_status_t *)dst;
  291. sip_status_t const *o = (sip_status_t *)src;
  292. char *end = b + xtra;
  293. sip_version_dup(&b, &st->st_version, o->st_version);
  294. st->st_status = o->st_status;
  295. MSG_STRING_DUP(b, st->st_phrase, o->st_phrase);
  296. assert(b <= end); (void)end;
  297. return b;
  298. }
  299. /**@ingroup sip_status
  300. *
  301. * Create a @ref sip_status "status line" object.
  302. *
  303. * @param home memory home used to allocate #sip_status_t object
  304. * @param status status code (in range 100 - 699)
  305. * @param phrase status phrase (may be NULL)
  306. * @param version version string (defaults to "SIP/2.0" if NULL)
  307. *
  308. * @note
  309. * If you provide an non-NULL @a version string, it is not copied. The
  310. * string @b MUST remain constant.
  311. *
  312. * @return
  313. * A pointer to newly created @ref sip_status "status line"
  314. * structure when successful, or NULL upon an error.
  315. */
  316. sip_status_t *sip_status_create(su_home_t *home,
  317. unsigned status,
  318. char const *phrase,
  319. char const *version)
  320. {
  321. sip_status_t *st;
  322. if (status < 100 || status > 699)
  323. return NULL;
  324. if (phrase == NULL && (phrase = sip_status_phrase(status)) == NULL)
  325. phrase = "";
  326. if ((st = (sip_status_t *)sip_header_alloc(home, sip_status_class, 0))) {
  327. st->st_status = status;
  328. st->st_phrase = phrase;
  329. st->st_version = version ? version : SIP_VERSION_CURRENT;
  330. }
  331. return st;
  332. }
  333. /* ====================================================================== */
  334. /**@SIP_HEADER sip_payload Message Body
  335. *
  336. * The payload structure contains the optional message body. The message
  337. * body stored in the #sip_payload_t structure has no internal structure,
  338. * but it is accessed as a byte array. Use @ref sdp_parser "SDP parser" to
  339. * parse SDP content, for instance.
  340. *
  341. * The message body is stored in a #sip_payload_t structure.
  342. */
  343. /**@ingroup sip_payload
  344. * @typedef typedef struct sip_payload_s sip_payload_t;
  345. *
  346. * The structure #sip_payload_t contains representation of SIP message payload.
  347. *
  348. * The #sip_payload_t is defined as follows:
  349. * @code
  350. * typedef struct sip_payload_s {
  351. * msg_common_t pl_common[1]; // Common fragment info
  352. * msg_header_t *pl_next; // Next payload (if multipart message)
  353. * char *pl_data; // Data - may contain NUL
  354. * unsigned pl_len; // Length of message payload
  355. * } sip_payload_t;
  356. * @endcode
  357. */
  358. #define sip_payload_d msg_payload_d
  359. #define sip_payload_e msg_payload_e
  360. #define sip_payload_dup_xtra msg_payload_dup_xtra
  361. #define sip_payload_dup_one msg_payload_dup_one
  362. #define sip_payload_update NULL
  363. msg_hclass_t sip_payload_class[] =
  364. SIP_HEADER_CLASS(payload, NULL, "", pl_common, single, payload);
  365. /**@ingroup sip_payload
  366. *
  367. * Create a @ref sip_payload "SIP payload" structure.
  368. *
  369. * Create a new SIP payload structure. it
  370. * copies the given data to the the payload data, and NUL terminates it (it
  371. * allocates one extra byte for NUL). If a NULL pointer is given as @a data,
  372. * sip_payload_create() allocates and zeroes a data buffer of @a len bytes.
  373. *
  374. * @param home memory home
  375. * @param data payload data
  376. * @param len payload length
  377. *
  378. * @return A pointer to newly created
  379. * payload structure, if successful, and NULL upon an error.
  380. */
  381. sip_payload_t *sip_payload_create(su_home_t *home, void const *data, isize_t len)
  382. {
  383. msg_hclass_t *hc = sip_payload_class;
  384. sip_header_t *h = sip_header_alloc(home, hc, len + 1);
  385. sip_payload_t *pl = (sip_payload_t *)h;
  386. if (pl) {
  387. char *b = sip_header_data(h);
  388. if (data) {
  389. memcpy(b, data, len);
  390. b[len] = 0;
  391. }
  392. else {
  393. memset(b, 0, len + 1);
  394. }
  395. h->sh_data = pl->pl_data = b;
  396. h->sh_len = pl->pl_len = len;
  397. }
  398. return pl;
  399. }
  400. /* ====================================================================== */
  401. /**@SIP_HEADER sip_separator Separator Line
  402. *
  403. * An empty line separates message headers from the message body (payload).
  404. * In order to avoid modifying messages with integrity protection, the
  405. * separator line has its own header structure which is included in the
  406. * #sip_t structure.
  407. *
  408. * The parsed separator line is stored in #sip_separator_t structure.
  409. */
  410. /**@ingroup sip_separator
  411. * @typedef typedef struct sip_separator_s sip_separator_t;
  412. *
  413. * The structure #sip_separator_t contains representation of separator line
  414. * between message headers and body.
  415. *
  416. * The #sip_separator_t is defined as follows:
  417. * @code
  418. * typedef struct sip_separator_s {
  419. * msg_common_t sep_common[1]; // Common fragment info
  420. * msg_header_t *sep_next; // Pointer to next header
  421. * char sep_data[4]; // NUL-terminated separator
  422. * } sip_separator_t;
  423. * @endcode
  424. */
  425. #define sip_separator_d msg_separator_d
  426. #define sip_separator_e msg_separator_e
  427. #define sip_separator_insert msg_separator_insert
  428. msg_hclass_t sip_separator_class[] =
  429. SIP_HEADER_CLASS(separator, NULL, "", sep_common, single, any);
  430. /**@ingroup sip_separator
  431. *
  432. * Create a @ref sip_separator "SIP separator line" structure.
  433. */
  434. sip_separator_t *sip_separator_create(su_home_t *home)
  435. {
  436. sip_separator_t *sep = (sip_separator_t *)
  437. sip_header_alloc(home, sip_separator_class, 0);
  438. if (sep)
  439. strcpy(sep->sep_data, CRLF);
  440. return sep;
  441. }
  442. /* ====================================================================== */
  443. /**@SIP_HEADER sip_unknown Unknown Headers
  444. *
  445. * The unknown headers are handled with #sip_unknown_t structure. The
  446. * unknown header name is stored in @a un_name field and the header field
  447. * following the colon is stored in @a un_value field.
  448. *
  449. * @note It is possible to speed up parsing process by creating a parser
  450. * which does understand only a minimum number of headers. If such a parser
  451. * is used, some well-known headers are regarded as unknown and put into
  452. * list of unknown headers.
  453. */
  454. /**@ingroup sip_unknown
  455. * @typedef typedef struct sip_unknown_s sip_unknown_t;
  456. *
  457. * The structure #sip_unknown_t contains representation of unknown headers.
  458. *
  459. * The #sip_unknown_t is defined as follows:
  460. * @code
  461. * typedef struct msg_unknown_s {
  462. * msg_common_t un_common[1]; // Common fragment info
  463. * msg_unknown_t *un_next; // Link to next unknown header
  464. * char const *un_name; // Header name
  465. * char const *un_value; // Header field value
  466. * } sip_unknown_t;
  467. * @endcode
  468. */
  469. #define sip_unknown_dup_xtra msg_unknown_dup_xtra
  470. #define sip_unknown_dup_one msg_unknown_dup_one
  471. #define sip_unknown_update NULL
  472. msg_hclass_t sip_unknown_class[] =
  473. SIP_HEADER_CLASS(unknown, "", "", un_common, append, unknown);
  474. issize_t sip_unknown_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  475. {
  476. return msg_unknown_d(home, h, s, slen);
  477. }
  478. issize_t sip_unknown_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  479. {
  480. return msg_unknown_e(b, bsiz, h, flags);
  481. }
  482. /* ====================================================================== */
  483. /**@SIP_HEADER sip_error Erroneous Headers
  484. *
  485. * The erroneous headers are stored in #sip_error_t structure.
  486. *
  487. * @note Other headers (like duplicate @ContentLength headers) may be put
  488. * into the list of erroneous headers (@c sip->sip_error). If the list of
  489. * erroneous headers is processed, the header type must be validated first
  490. * by calling sip_is_error() (or by other relevant tests).
  491. */
  492. /**@ingroup sip_error
  493. * @typedef typedef msg_error_t sip_error_t;
  494. * The structure #sip_error_t contains representation of error headers.
  495. *
  496. * The #sip_error_t is defined as follows:
  497. * @code
  498. * typedef struct msg_error_s {
  499. * msg_common_t er_common[1]; // Common fragment info
  500. * msg_error_t *er_next; // Link to next header
  501. * char const *er_name; // Name of bad header (if any)
  502. * } sip_error_t;
  503. * @endcode
  504. */
  505. msg_hclass_t sip_error_class[] =
  506. SIP_HEADER_CLASS(error, NULL, "", er_common, append, any);
  507. issize_t sip_error_d(su_home_t *home, msg_header_t *h, char *s, isize_t slen)
  508. {
  509. return 0;
  510. }
  511. issize_t sip_error_e(char b[], isize_t bsiz, msg_header_t const *h, int flags)
  512. {
  513. /* There is no way to encode an erroneous header */
  514. return 0;
  515. }
  516. /* ====================================================================== */
  517. /*
  518. * addr = ("To" | "t" | "From" | "f") ":"
  519. * ( name-addr | addr-spec ) *( ";" addr-params )
  520. * name-addr = [ display-name ] "<" addr-spec ">"
  521. * addr-spec = SIP-URL | URI
  522. * display-name = *token | quoted-string
  523. */
  524. /**Parse @e name-addr.
  525. *
  526. * Parses <i>( name-addr | addr-spec )</i> construct on @Contact, @From,
  527. * @To, and other compatible headers. It splits the argument string in
  528. * four parts:
  529. *
  530. * @par
  531. * @e [display-name] @e addr-spec @e [parameters] @e [comment] @e [ss]
  532. *
  533. * @param home pointer to memory home
  534. * @param inout_s pointer to pointer to string to be parsed
  535. * @param return_display value-result parameter for @e display-name
  536. * @param return_url value-result parameter for @e addr-spec
  537. * @param return_params value-result paramater for @e parameters
  538. * @param return_comment value-result parameter for @e comment
  539. *
  540. * @note After succesful call to the function @c sip_name_addr_d(), *ss
  541. * contains pointer to the first character not beloging to @e name-addr,
  542. * most probably a comma. If that character is a separator, the last parameter
  543. * may not be NUL (zero) terminated. So, after examining value of @a **ss,
  544. * the calling function @b MUST set it to NUL.
  545. *
  546. * @retval 0 if successful
  547. * @retval -1 upon an error
  548. *
  549. * @sa @From, @To, @Contact
  550. */
  551. issize_t sip_name_addr_d(su_home_t *home,
  552. char **inout_s,
  553. char const **return_display,
  554. url_t *return_url,
  555. msg_param_t const **return_params,
  556. char const **return_comment)
  557. {
  558. char c, *s = *inout_s;
  559. char *display = NULL, *addr_spec = NULL;
  560. size_t n;
  561. if (*s == '\0') /* Empty string */
  562. return -1;
  563. if (return_display && *s == '"') {
  564. /* Quoted string */
  565. if (msg_quoted_d(&s, &display) == -1)
  566. return -1;
  567. /* Now, we should have a '<' in s[0] */
  568. if (s[0] != '<')
  569. return -1;
  570. s++[0] = '\0'; /* NUL terminate quoted string... */
  571. n = strcspn(s, ">");
  572. addr_spec = s; s += n;
  573. if (*s) *s++ = '\0'; else return -1;
  574. }
  575. else {
  576. if (return_display)
  577. n = span_token_lws(s);
  578. else
  579. n = 0;
  580. if (s[n] == '<') {
  581. /* OK, we got a display name */
  582. display = s; s += n + 1;
  583. /* NUL terminate display name */
  584. while (n > 0 && IS_LWS(display[n - 1]))
  585. n--;
  586. if (n > 0)
  587. display[n] = '\0';
  588. else
  589. display = "";
  590. n = strcspn(s, ">");
  591. addr_spec = s; s += n; if (*s) *s++ = '\0'; else return -1;
  592. }
  593. else {
  594. /* addr-spec only */
  595. addr_spec = s;
  596. /**@sa
  597. * Discussion about comma, semicolon and question mark in
  598. * @RFC3261 section 20.10.
  599. */
  600. if (return_params)
  601. n = strcspn(s, " \t,;?"); /* DO NOT accept ,;? in URL */
  602. else
  603. /* P-Asserted-Identity and friends */
  604. n = strcspn(s, " ,"); /* DO NOT accept , in URL */
  605. s += n;
  606. if (IS_LWS(*s))
  607. *s++ = '\0';
  608. }
  609. }
  610. skip_lws(&s);
  611. if (return_display)
  612. *return_display = display;
  613. /* Now, url may still not be NUL terminated, e.g., if
  614. * it is like "Contact: url:foo,sip:bar,sip:zunk"
  615. */
  616. c = *s; *s = '\0'; /* terminate temporarily */
  617. /* Do not accept an empty URL */
  618. if (addr_spec[0] == '\0')
  619. return -1;
  620. if (url_d(return_url, addr_spec) == -1)
  621. return -1;
  622. *s = c; /* return terminator */
  623. *inout_s = s;
  624. if (c == ';' && return_params)
  625. if (msg_params_d(home, inout_s, return_params) == -1)
  626. return -1;
  627. if (**inout_s == '(' && return_comment)
  628. if (msg_comment_d(inout_s, return_comment) == -1)
  629. return -1;
  630. return 0;
  631. }
  632. /**Encode @e name-addr and parameter list.
  633. *
  634. * Encodes @e name-addr headers, like @From, @To, @CallInfo, @ErrorInfo,
  635. * @Route, and @RecordRoute.
  636. *
  637. * @param b buffer to store the encoding result
  638. * @param bsiz size of the buffer @a b
  639. * @param flags encoding flags
  640. * @param display display name encoded before the @a url (may be NULL)
  641. * @param brackets if true, use always brackets around @a url
  642. * @param url pointer to URL structure
  643. * @param params pointer to parameter list (may be NULL)
  644. * @param comment comment string encoded after others (may be NULL)
  645. *
  646. * @return
  647. * Returns number of characters in encoding, excluding the
  648. * final NUL.
  649. *
  650. * @note
  651. * The encoding result may be incomplete if the buffer size is not large
  652. * enough to store the whole encoding result.
  653. */
  654. issize_t sip_name_addr_e(char b[], isize_t bsiz,
  655. int flags,
  656. char const *display,
  657. int brackets, url_t const url[],
  658. msg_param_t const params[],
  659. char const *comment)
  660. {
  661. int const compact = MSG_IS_COMPACT(flags);
  662. char const *u;
  663. char *b0 = b, *end = b + bsiz;
  664. brackets = brackets || display ||
  665. (url && (url->url_params ||
  666. url->url_headers ||
  667. ((u = url->url_user) && u[strcspn(u, ";,?")]) ||
  668. ((u = url->url_password) && u[strcspn(u, ",")])));
  669. if (display && display[0]) {
  670. MSG_STRING_E(b, end, display);
  671. if (!compact) MSG_CHAR_E(b, end, ' ');
  672. }
  673. if (url) {
  674. if (brackets) MSG_CHAR_E(b, end, '<');
  675. URL_E(b, end, url);
  676. if (brackets) MSG_CHAR_E(b, end, '>');
  677. }
  678. MSG_PARAMS_E(b, end, params, flags);
  679. if (comment) {
  680. if (!compact) MSG_CHAR_E(b, end, ' ');
  681. MSG_CHAR_E(b, end, '(');
  682. MSG_STRING_E(b, end, comment);
  683. MSG_CHAR_E(b, end, ')');
  684. }
  685. MSG_TERM_E(b, end);
  686. return b - b0;
  687. }
  688. /** Calculate the extra size needed to duplicate a name-addr-params construct.
  689. *
  690. * @param display display name (may be NULL)
  691. * @param addr pointer to URL structure
  692. * @param params pointer to parameter list (may be NULL)
  693. * @param offset base offset
  694. *
  695. * @retval Size of duplicated name-addr-params construct, including base offset.
  696. *
  697. * @NEW_1_12_7.
  698. */
  699. isize_t sip_name_addr_xtra(char const *display, url_t const *addr,
  700. msg_param_t const params[],
  701. isize_t offset)
  702. {
  703. SIP_PARAMS_SIZE(offset, params);
  704. offset += SIP_STRING_SIZE(display);
  705. offset += url_xtra(addr);
  706. return offset;
  707. }
  708. /**Duplicate a name-addr-params construct.
  709. *
  710. * @param d_display value-result parameter for copied @e name (may be NULL)
  711. * @param display display name (may be NULL)
  712. * @param d_addr value-result parameter for copied @e address
  713. * @param addr pointer to URL address structure
  714. * @param d_params value-result parameter for copied parameters (may be NULL)
  715. * @param params pointer to parameter list (may be NULL)
  716. * @param b pointer to memory pool
  717. * @param xtra size of the memory pool
  718. *
  719. * @retval End of the memory area used.
  720. *
  721. * @NEW_1_12_7.
  722. */
  723. char *sip_name_addr_dup(char const **d_display, char const *display,
  724. url_t *d_addr, url_t const *addr,
  725. msg_param_t const **d_params, msg_param_t const params[],
  726. char *b, isize_t xtra)
  727. {
  728. char *end = b + xtra;
  729. if (d_params)
  730. b = msg_params_dup(d_params, params, b, xtra);
  731. URL_DUP(b, end, d_addr, addr);
  732. if (d_display)
  733. MSG_STRING_DUP(b, *d_display, display);
  734. assert(b <= end);
  735. return b;
  736. }
  737. /** Parse @To or @From headers */
  738. static issize_t sip_addr_d(su_home_t *home,
  739. sip_header_t *h,
  740. char *s,
  741. isize_t slen)
  742. {
  743. sip_addr_t *a = (sip_addr_t *)h;
  744. char const *comment = NULL;
  745. if (sip_name_addr_d(home,
  746. &s,
  747. &a->a_display,
  748. a->a_url,
  749. &a->a_params,
  750. &comment) == -1
  751. || *s /* XXX - something extra? */)
  752. return -1;
  753. a->a_tag = msg_params_find(a->a_params, "tag=");
  754. return 0;
  755. }
  756. static int sip_addr_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  757. {
  758. sip_addr_t const *a = (sip_addr_t const *)h;
  759. return sip_name_addr_e(b, bsiz,
  760. flags,
  761. a->a_display,
  762. MSG_IS_CANONIC(flags), a->a_url,
  763. a->a_params,
  764. NULL);
  765. }
  766. /**
  767. * Extra dup size of a sip_addr_t object.
  768. *
  769. * This function calculates extra size required when duplicating a
  770. * sip_addr_t object.
  771. *
  772. * @param a pointer to a sip_addr_t object
  773. *
  774. * @return
  775. * Size of strings related to sip_addr_t object.
  776. */
  777. static
  778. isize_t sip_addr_dup_xtra(sip_header_t const *h, isize_t offset)
  779. {
  780. sip_addr_t const *a = (sip_addr_t const *)h;
  781. return sip_name_addr_xtra(a->a_display,
  782. a->a_url,
  783. a->a_params,
  784. offset);
  785. }
  786. /**@internal
  787. * Duplicate one sip_addr_t object.
  788. */
  789. static char *sip_addr_dup_one(sip_header_t *dst, sip_header_t const *src,
  790. char *b, isize_t xtra)
  791. {
  792. sip_addr_t *a = (sip_addr_t *)dst;
  793. sip_addr_t const *o = (sip_addr_t *)src;
  794. return sip_name_addr_dup(&a->a_display, o->a_display,
  795. a->a_url, o->a_url,
  796. &a->a_params, o->a_params,
  797. b, xtra);
  798. }
  799. /** Update parameters in sip_addr_t object */
  800. static int sip_addr_update(msg_common_t *h,
  801. char const *name, isize_t namelen,
  802. char const *value)
  803. {
  804. sip_addr_t *a = (sip_addr_t *)h;
  805. if (name == NULL) {
  806. a->a_tag = NULL;
  807. }
  808. else if (namelen == strlen("tag") && su_casenmatch(name, "tag", namelen)) {
  809. a->a_tag = value;
  810. }
  811. return 0;
  812. }
  813. /** Create an address header object from URL */
  814. static sip_addr_t *
  815. sip_addr_make_url(su_home_t *home, msg_hclass_t *hc, url_string_t const *us)
  816. {
  817. size_t n;
  818. sip_header_t *h;
  819. n = url_xtra(us->us_url);
  820. h = sip_header_alloc(home, hc, n);
  821. if (h) {
  822. sip_addr_t *a = (sip_to_t *)h;
  823. char *s2 = sip_header_data(h);
  824. if ((size_t)url_dup(s2, n, a->a_url, us->us_url) == n)
  825. return a;
  826. su_free(home, h);
  827. }
  828. return NULL;
  829. }
  830. /** Add a tag to address structure. */
  831. static
  832. int sip_addr_tag(su_home_t *home, sip_addr_t *a, char const *tag)
  833. {
  834. if (a && tag) {
  835. msg_param_t value = strchr(tag, '=');
  836. if (value)
  837. value = strchr(value, '=') + 1;
  838. else
  839. value = tag;
  840. if (a->a_tag) {
  841. if (su_casematch(a->a_tag, value))
  842. return 0;
  843. else
  844. return -1;
  845. }
  846. if (tag == value)
  847. tag = su_sprintf(home, "tag=%s", tag);
  848. else
  849. tag = su_strdup(home, tag);
  850. if (tag)
  851. if (msg_header_replace_param(home, a->a_common, tag) >= 0)
  852. return 0;
  853. }
  854. return -1;
  855. }
  856. /* ====================================================================== */
  857. /**@SIP_HEADER sip_call_id Call-ID Header
  858. *
  859. * The @b Call-ID header uniquely identifies a particular invitation or all
  860. * registrations of a particular client. It is defined in @RFC3261 as
  861. * follows:
  862. *
  863. * @code
  864. * Call-ID = ( "Call-ID" / "i" ) HCOLON callid
  865. * callid = word [ "@" word ]
  866. * word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
  867. * "_" / "+" / "`" / "'" / "~" / "(" / ")" / "<" / ">" /
  868. * ":" / "\" / DQUOTE / "/" / "[" / "]" / "?" / "{" / "}" )
  869. * @endcode
  870. *
  871. * The parsed Call-ID Header is stored in #sip_call_id_t structure.
  872. */
  873. /**@ingroup sip_call_id
  874. * @typedef typedef struct sip_call_id_s sip_call_id_t;
  875. *
  876. * The structure #sip_call_id_t contains representation of SIP @CallID
  877. * header.
  878. *
  879. * The #sip_call_id_t is defined as follows:
  880. * @code
  881. * typedef struct sip_call_id_s {
  882. * sip_common_t i_common[1]; // Common fragment info
  883. * sip_call_id_t *i_next; // Link to next (dummy)
  884. * char const *i_id; // ID value
  885. * uint32_t i_hash; // Hash value (always nonzero)
  886. * } sip_call_id_t;
  887. * @endcode
  888. */
  889. static msg_xtra_f sip_call_id_dup_xtra;
  890. static msg_dup_f sip_call_id_dup_one;
  891. #define sip_call_id_update NULL
  892. msg_hclass_t sip_call_id_class[] =
  893. SIP_HEADER_CLASS(call_id, "Call-ID", "i", i_common, single, call_id);
  894. issize_t sip_call_id_d(su_home_t *home,
  895. sip_header_t *h,
  896. char *s,
  897. isize_t slen)
  898. {
  899. sip_call_id_t *i = (sip_call_id_t *)h;
  900. i->i_id = s; /* XXX - why not sip_word_at_word_d(&s); */
  901. i->i_hash = msg_hash_string(s);
  902. return 0;
  903. }
  904. issize_t sip_call_id_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  905. {
  906. sip_call_id_t const *i = (sip_call_id_t *)h;
  907. size_t n = strlen(i->i_id);
  908. if (bsiz > n)
  909. strcpy(b, i->i_id);
  910. return (issize_t)n;
  911. }
  912. /** Extra size of a #sip_call_id_t object. */
  913. isize_t sip_call_id_dup_xtra(sip_header_t const *h, isize_t offset)
  914. {
  915. sip_call_id_t const *i = (sip_call_id_t *)h;
  916. return offset + MSG_STRING_SIZE(i->i_id);
  917. }
  918. /**Duplicate a sip_call_id object.
  919. *
  920. * Duplicate (copy deeply) a single #sip_call_id_t header object.
  921. *
  922. * @param dst pointer to newly allocated header object
  923. * @param src pointer to a header object to be duplicated
  924. * @param b memory buffer used to copy external references
  925. * @param xtra number bytes in buffer @a b
  926. *
  927. * @return Pointer to the new copy of #sip_call_id_t object, or @c NULL
  928. * upon an error.
  929. */
  930. char *sip_call_id_dup_one(sip_header_t *dst, sip_header_t const *src,
  931. char *b, isize_t xtra)
  932. {
  933. sip_call_id_t *i = (sip_call_id_t *)dst;
  934. sip_call_id_t const *o = (sip_call_id_t *)src;
  935. char *end = b + xtra;
  936. MSG_STRING_DUP(b, i->i_id, o->i_id);
  937. if (!(i->i_hash = o->i_hash))
  938. i->i_hash = msg_hash_string(i->i_id);
  939. assert(b <= end); (void)end;
  940. return b;
  941. }
  942. /**@ingroup sip_call_id
  943. *
  944. * Create a @CallID header object.
  945. *
  946. * Create a Call-ID header object with a new unique value. It uses
  947. * su_guid_generate() function to generate the value. If the local host name
  948. * @a domain is specified, it is prepended to the generated value instead of
  949. * local MAC address.
  950. * @param home memory home
  951. * @param domain local domain name
  952. *
  953. * @return A pointer to newly created @CallID header object when
  954. * successful or NULL upon an error.
  955. *
  956. * @sa su_guid_generate(), su_guid_sprintf()
  957. */
  958. sip_call_id_t *sip_call_id_create(su_home_t *home, char const *domain)
  959. {
  960. sip_call_id_t *i;
  961. size_t xtra = su_guid_strlen + 1 + (domain ? strlen(domain) + 1 : 0);
  962. i = (sip_call_id_t *)sip_header_alloc(home, sip_call_id_class, xtra);
  963. if (i) {
  964. char *b;
  965. su_guid_t guid[1];
  966. i->i_id = b = (char *)(i + 1);
  967. su_guid_generate(guid);
  968. /*
  969. * Guid looks like "NNNNNNNN-NNNN-NNNN-NNNN-XXXXXXXXXXXX"
  970. * where NNNNNNNN-NNNN-NNNN-NNNN is timestamp and XX is MAC address
  971. * (but we use usually random ID for MAC because we do not have
  972. * guid generator available for all processes within node)
  973. */
  974. su_guid_sprintf(b, su_guid_strlen + 1, guid);
  975. /* If we have a domain name don't include MAC address at the end of guid */
  976. if (domain) {
  977. b[8 + 5 + 5 + 5] = '@';
  978. strcpy(b + 8 + 5 + 5 + 5 + 1, domain);
  979. }
  980. i->i_hash = msg_hash_string(i->i_id);
  981. }
  982. return i;
  983. }
  984. /* ====================================================================== */
  985. /**@SIP_HEADER sip_cseq CSeq Header
  986. *
  987. * The CSeq header (command sequence) uniquely identifies transactions
  988. * within a dialog. It is defined in @RFC3261 as follows:
  989. *
  990. * @code
  991. * CSeq = "CSeq" HCOLON 1*DIGIT LWS Method
  992. * Method = INVITEm / ACKm / OPTIONSm / BYEm
  993. * / CANCELm / REGISTERm
  994. * / extension-method
  995. * extension-method = token
  996. * @endcode
  997. *
  998. * The parsed CSeq header is stored in #sip_cseq_t structure.
  999. */
  1000. /**@ingroup sip_cseq
  1001. * @typedef typedef struct sip_cseq_s sip_cseq_t;
  1002. *
  1003. * The structure #sip_cseq_t contains representation of SIP @CSeq header.
  1004. *
  1005. * The #sip_cseq_t is defined as follows:
  1006. * @code
  1007. * typedef struct sip_cseq_s {
  1008. * sip_common_t cs_common[1]; // Common fragment info
  1009. * sip_error_t *cs_next; // Link to next (dummy)
  1010. * uint32_t cs_seq; // Sequence number
  1011. * sip_method_t cs_method; // Method enum
  1012. * char const *cs_method_name; // Method name
  1013. * } sip_cseq_t;
  1014. * @endcode
  1015. */
  1016. static msg_xtra_f sip_cseq_dup_xtra;
  1017. static msg_dup_f sip_cseq_dup_one;
  1018. #define sip_cseq_update NULL
  1019. msg_hclass_t sip_cseq_class[] =
  1020. SIP_HEADER_CLASS(cseq, "CSeq", "", cs_common, single, cseq);
  1021. issize_t sip_cseq_d(su_home_t *home,
  1022. sip_header_t *h,
  1023. char *s,
  1024. isize_t slen)
  1025. {
  1026. sip_cseq_t *cs = (sip_cseq_t *)h;
  1027. if (msg_uint32_d(&s, &cs->cs_seq) < 0)
  1028. return -1;
  1029. if (*s) {
  1030. if ((cs->cs_method = sip_method_d(&s, &cs->cs_method_name)) >= 0)
  1031. return 0;
  1032. }
  1033. return -1;
  1034. }
  1035. issize_t sip_cseq_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  1036. {
  1037. sip_cseq_t const *cs = (sip_cseq_t *)h;
  1038. assert(sip_is_cseq(h));
  1039. return snprintf(b, bsiz, "%u %s", cs->cs_seq, cs->cs_method_name);
  1040. }
  1041. isize_t sip_cseq_dup_xtra(sip_header_t const *h, isize_t offset)
  1042. {
  1043. sip_cseq_t const *cs = (sip_cseq_t *)h;
  1044. if (!cs->cs_method)
  1045. return offset + MSG_STRING_SIZE(cs->cs_method_name);
  1046. else
  1047. return offset;
  1048. }
  1049. char *sip_cseq_dup_one(sip_header_t *dst, sip_header_t const *src,
  1050. char *b, isize_t xtra)
  1051. {
  1052. sip_cseq_t *cs = (sip_cseq_t *)dst;
  1053. sip_cseq_t const *o = (sip_cseq_t *)src;
  1054. char *end = b + xtra;
  1055. if (!(cs->cs_method = o->cs_method))
  1056. MSG_STRING_DUP(b, cs->cs_method_name, o->cs_method_name);
  1057. else
  1058. cs->cs_method_name = o->cs_method_name;
  1059. cs->cs_seq = o->cs_seq;
  1060. assert(b <= end); (void)end;
  1061. return b;
  1062. }
  1063. /**@ingroup sip_cseq
  1064. *
  1065. * Create a @CSeq header object.
  1066. *
  1067. * Create a @CSeq header object with the
  1068. * sequence number @a seq, method enum @a method and method name @a
  1069. * method_name. The memory for the header object is allocated from the
  1070. * memory home @a home.
  1071. *
  1072. * @param home memory home
  1073. * @param seq sequence number
  1074. * @param method method enum
  1075. * @param method_name method name (required if method is not well-known)
  1076. *
  1077. * @par Example
  1078. * The following code fragment creates a cseq object for OPTIONS request:
  1079. * @code
  1080. * sip_cseq_t *cseq;
  1081. * cseq = sip_cseq_create(home, agent->seq++, SIP_METHOD_OPTIONS);
  1082. * @endcode
  1083. *
  1084. * @return
  1085. * A pointer to newly created @CSeq
  1086. * header object when successful or NULL upon an error.
  1087. */
  1088. sip_cseq_t *sip_cseq_create(su_home_t *home,
  1089. uint32_t seq,
  1090. unsigned method,
  1091. char const *method_name)
  1092. {
  1093. size_t xtra;
  1094. sip_cseq_t *cs;
  1095. if (method)
  1096. method_name = sip_method_name((sip_method_t)method, method_name);
  1097. if (method_name == NULL)
  1098. return NULL;
  1099. xtra = (method ? 0 : (strlen(method_name) + 1));
  1100. cs = (sip_cseq_t *)sip_header_alloc(home, sip_cseq_class, xtra);
  1101. if (cs) {
  1102. cs->cs_seq = seq;
  1103. cs->cs_method = (sip_method_t)method;
  1104. if (!method)
  1105. method_name = strcpy((char *)(cs + 1), method_name);
  1106. cs->cs_method_name = method_name;
  1107. }
  1108. return cs;
  1109. }
  1110. /* ====================================================================== */
  1111. /**@SIP_HEADER sip_contact Contact Header
  1112. *
  1113. * The Contact header contain a list of URLs used to redirect future
  1114. * requests. Its syntax is defined in @RFC3261 as follows:
  1115. *
  1116. * @code
  1117. * Contact = ("Contact" / "m" ) HCOLON
  1118. * ( STAR / (contact-param *(COMMA contact-param)))
  1119. * contact-param = (name-addr / addr-spec) *(SEMI contact-params)
  1120. * name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
  1121. * addr-spec = SIP-URI / SIPS-URI / absoluteURI
  1122. * display-name = *(token LWS)/ quoted-string
  1123. * contact-params = c-p-q / c-p-expires
  1124. * / contact-extension
  1125. * c-p-q = "q" EQUAL qvalue
  1126. * c-p-expires = "expires" EQUAL delta-seconds
  1127. * contact-extension = generic-param
  1128. * delta-seconds = 1*DIGIT
  1129. * @endcode
  1130. *
  1131. * @note
  1132. * The @RFC2543 syntax allowed <comment>. We accept it, but don't encode it.
  1133. *
  1134. * Each parsed Contact header field is stored in #sip_contact_t structure.
  1135. */
  1136. /**@ingroup sip_contact
  1137. * @typedef typedef struct sip_contact_s sip_contact_t;
  1138. *
  1139. * The structure #sip_contact_t contains representation of SIP @Contact
  1140. * header.
  1141. *
  1142. * The #sip_contact_t is defined as follows:
  1143. * @code
  1144. * typedef struct sip_contact_s {
  1145. * sip_common_t m_common[1]; // Common fragment info
  1146. * sip_contact_t *m_next; // Link to next
  1147. * char const *m_display; // Display name
  1148. * url_t m_url[1]; // SIP URL
  1149. * msg_param_t const *m_params; // List of contact-params
  1150. * char const *m_comment; // Comment
  1151. *
  1152. * char const *m_q; // Priority
  1153. * char const *m_expires; // Expiration time
  1154. * } sip_contact_t;
  1155. * @endcode
  1156. *
  1157. * @note The <comment> field @ref sip_contact_s::m_comment "m_comment" is
  1158. * deprecated: it is parsed but not included in encoding.
  1159. */
  1160. static msg_xtra_f sip_contact_dup_xtra;
  1161. static msg_dup_f sip_contact_dup_one;
  1162. static msg_update_f sip_contact_update;
  1163. /** @showinitializer */
  1164. msg_hclass_t sip_contact_class[] =
  1165. /*
  1166. * Cut through the fog of macros
  1167. * SIP_HEADER_CLASS(contact, "Contact", "m", m_params, append, contact);
  1168. * and show here how the msg_hclass_t is initialized
  1169. */
  1170. {{
  1171. /* hc_hash: */ sip_contact_hash,
  1172. /* hc_parse: */ sip_contact_d,
  1173. /* hc_print: */ sip_contact_e,
  1174. /* hc_dxtra: */ sip_contact_dup_xtra,
  1175. /* hc_dup_one: */ sip_contact_dup_one,
  1176. /* hc_update: */ sip_contact_update,
  1177. /* hc_name: */ "Contact",
  1178. /* hc_len: */ sizeof("Contact") - 1,
  1179. /* hc_short: */ "m",
  1180. /* hc_size: */ MSG_ALIGN(sizeof(sip_contact_t), sizeof(void*)),
  1181. /* hc_params: */ offsetof(sip_contact_t, m_params),
  1182. /* hc_kind: */ msg_kind_append,
  1183. /* hc_critical: */ 0
  1184. }};
  1185. issize_t sip_contact_d(su_home_t *home,
  1186. sip_header_t *h,
  1187. char *s,
  1188. isize_t slen)
  1189. {
  1190. sip_contact_t *m;
  1191. assert(h);
  1192. for(;;) {
  1193. m = (sip_contact_t *)h;
  1194. while (*s == ',') /* Ignore empty entries (comma-whitespace) */
  1195. *s = '\0', s += span_lws(s + 1) + 1;
  1196. if (sip_name_addr_d(home, &s, &m->m_display, m->m_url,
  1197. &m->m_params, &m->m_comment) == -1)
  1198. return -1;
  1199. msg_parse_next_field_without_recursion();
  1200. }
  1201. }
  1202. issize_t sip_contact_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  1203. {
  1204. sip_contact_t const *m = (sip_contact_t *)h;
  1205. int always_lt_gt = MSG_IS_CANONIC(flags) && m->m_url->url_type != url_any;
  1206. assert(sip_is_contact(h));
  1207. return sip_name_addr_e(b, bsiz, flags,
  1208. m->m_display, always_lt_gt, m->m_url,
  1209. m->m_params,
  1210. NULL /* m->m_comment */);
  1211. }
  1212. isize_t sip_contact_dup_xtra(sip_header_t const *h, isize_t offset)
  1213. {
  1214. sip_contact_t const *m = (sip_contact_t *)h;
  1215. return sip_name_addr_xtra(m->m_display,
  1216. m->m_url,
  1217. m->m_params,
  1218. offset)
  1219. + MSG_STRING_SIZE(m->m_comment);
  1220. }
  1221. char *sip_contact_dup_one(sip_header_t *dst, sip_header_t const *src,
  1222. char *b, isize_t xtra)
  1223. {
  1224. sip_contact_t *m = (sip_contact_t *)dst;
  1225. sip_contact_t const *o = (sip_contact_t *)src;
  1226. b = sip_name_addr_dup(&m->m_display, o->m_display,
  1227. m->m_url, o->m_url,
  1228. &m->m_params, o->m_params,
  1229. b, xtra);
  1230. MSG_STRING_DUP(b, m->m_comment, o->m_comment);
  1231. return b;
  1232. }
  1233. /** Update parameter in #sip_contact_t */
  1234. static int sip_contact_update(msg_common_t *h,
  1235. char const *name, isize_t namelen,
  1236. char const *value)
  1237. {
  1238. sip_contact_t *m = (sip_contact_t *)h;
  1239. if (name == NULL) {
  1240. m->m_q = NULL;
  1241. m->m_expires = NULL;
  1242. }
  1243. else if (namelen == 1 && su_casenmatch(name, "q", 1)) {
  1244. /* XXX - check for invalid value? */
  1245. m->m_q = value;
  1246. }
  1247. else if (namelen == strlen("expires") &&
  1248. su_casenmatch(name, "expires", namelen)) {
  1249. m->m_expires = value;
  1250. }
  1251. return 0;
  1252. }
  1253. /**@ingroup sip_contact
  1254. *
  1255. * Add a parameter to a @Contact header object
  1256. *
  1257. * Add a parameter to a @Contact
  1258. * object. It does not copy the contents of the string @c param.
  1259. *
  1260. * @note This function @b does @b not duplicate @p param.
  1261. *
  1262. * @param home memory home
  1263. * @param m #sip_contact_t object
  1264. * @param param parameter string
  1265. *
  1266. * @return 0 when successful, and -1 upon an error.
  1267. *
  1268. * @deprecated Use msg_header_replace_param() directly.
  1269. */
  1270. int sip_contact_add_param(su_home_t *home,
  1271. sip_contact_t *m,
  1272. char const *param)
  1273. {
  1274. return msg_header_replace_param(home, m->m_common, param);
  1275. }
  1276. /* ====================================================================== */
  1277. /**@SIP_HEADER sip_content_length Content-Length Header
  1278. *
  1279. * The Content-Length header indicates the size of the message-body in
  1280. * decimal number of octets. Its syntax is defined in @RFC3261 as
  1281. * follows:
  1282. *
  1283. * @code
  1284. * Content-Length = ( "Content-Length" / "l" ) HCOLON 1*DIGIT
  1285. * @endcode
  1286. *
  1287. * The parsed Content-Length header is stored in #sip_content_length_t
  1288. * structure.
  1289. */
  1290. /**@ingroup sip_content_length
  1291. * @typedef typedef struct sip_content_length_s sip_content_length_t;
  1292. *
  1293. * The structure #sip_content_length_t contains representation of SIP
  1294. * @ContentLength header.
  1295. *
  1296. * The #sip_content_length_t is defined as follows:
  1297. * @code
  1298. * typedef struct sip_content_length_s {
  1299. * sip_common_t l_common[1]; // Common fragment info
  1300. * sip_error_t *l_next; // Dummy link to next
  1301. * uint32_t l_length; // Message body length in bytes
  1302. * } sip_content_length_t;
  1303. * @endcode
  1304. */
  1305. msg_hclass_t sip_content_length_class[] =
  1306. SIP_HEADER_CLASS(content_length, "Content-Length", "l", l_common,
  1307. single_critical, any);
  1308. issize_t sip_content_length_d(su_home_t *home,
  1309. sip_header_t *h,
  1310. char *s,
  1311. isize_t slen)
  1312. {
  1313. sip_content_length_t *l = (sip_content_length_t *)h;
  1314. issize_t retval = msg_uint32_d(&s, &l->l_length);
  1315. if (*s)
  1316. retval = -1;
  1317. return retval;
  1318. }
  1319. issize_t sip_content_length_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  1320. {
  1321. sip_content_length_t const *l = (sip_content_length_t const *)h;
  1322. assert(sip_is_content_length(h));
  1323. return snprintf(b, bsiz, "%lu", (unsigned long)l->l_length);
  1324. }
  1325. /**@ingroup sip_content_length
  1326. *
  1327. * Create a @ContentLength header object.
  1328. *
  1329. * Create a @ContentLength
  1330. * header object with the value @a n. The memory for the header is
  1331. * allocated from the memory home @a home.
  1332. *
  1333. * @param home memory home
  1334. * @param n payload size in bytes
  1335. *
  1336. * @return
  1337. * A pointer to newly created @ContentLength header object when successful
  1338. * or NULL upon an error.
  1339. */
  1340. sip_content_length_t *sip_content_length_create(su_home_t *home, uint32_t n)
  1341. {
  1342. sip_content_length_t *l = (sip_content_length_t *)
  1343. sip_header_alloc(home, sip_content_length_class, 0);
  1344. if (l)
  1345. l->l_length = n;
  1346. return l;
  1347. }
  1348. /* ====================================================================== */
  1349. /**@SIP_HEADER sip_date Date Header
  1350. *
  1351. * The Date header field reflects the time when the request or response was
  1352. * first sent. Its syntax is defined in @RFC3261 and @RFC2616 section 14.18 as
  1353. * follows:
  1354. *
  1355. * @code
  1356. * Date = "Date" HCOLON SIP-date
  1357. * SIP-date = rfc1123-date
  1358. * rfc1123-date = wkday "," SP date1 SP time SP "GMT"
  1359. * date1 = 2DIGIT SP month SP 4DIGIT
  1360. * ; day month year (e.g., 02 Jun 1982)
  1361. * time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
  1362. * ; 00:00:00 - 23:59:59
  1363. * wkday = "Mon" / "Tue" / "Wed"
  1364. * / "Thu" / "Fri" / "Sat" / "Sun"
  1365. * month = "Jan" / "Feb" / "Mar" / "Apr"
  1366. * / "May" / "Jun" / "Jul" / "Aug"
  1367. * / "Sep" / "Oct" / "Nov" / "Dec"
  1368. * @endcode
  1369. *
  1370. * The parsed Date header is stored in #sip_date_t structure.
  1371. */
  1372. /**@ingroup sip_date
  1373. * @typedef typedef struct sip_date_s sip_date_t;
  1374. *
  1375. * The structure #sip_date_t contains representation of SIP @Date header.
  1376. *
  1377. * The #sip_date_t is defined as follows:
  1378. * @code
  1379. * typedef struct sip_date_s {
  1380. * sip_common_t d_common[1]; // Common fragment info
  1381. * sip_date_t *d_next; // Link to next (dummy)
  1382. * sip_time_t d_time; // Seconds since Jan 1, 1900
  1383. * } sip_date_t;
  1384. * @endcode
  1385. */
  1386. msg_hclass_t sip_date_class[] =
  1387. SIP_HEADER_CLASS(date, "Date", "", d_common, single, any);
  1388. issize_t sip_date_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  1389. {
  1390. sip_date_t *date = (sip_date_t *)h;
  1391. if (msg_date_d((char const **)&s, &date->d_time) < 0 || *s)
  1392. return -1;
  1393. else
  1394. return 0;
  1395. }
  1396. issize_t sip_date_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  1397. {
  1398. sip_date_t const *date = (sip_date_t *)h;
  1399. return msg_date_e(b, bsiz, date->d_time);
  1400. }
  1401. /**@ingroup sip_date
  1402. * @brief Create an @Date header object.
  1403. *
  1404. * Create a @Date header object with
  1405. * the date @a date. If @date is 0, current time (as returned by sip_now())
  1406. * is used.
  1407. *
  1408. * @param home memory home
  1409. * @param date date expressed as seconds since Mon, 01 Jan 1900 00:00:00
  1410. *
  1411. * @return
  1412. * A pointer to newly created @Date header object when successful, or NULL
  1413. * upon an error.
  1414. */
  1415. sip_date_t *sip_date_create(su_home_t *home, sip_time_t date)
  1416. {
  1417. sip_date_t *d = (sip_date_t *)sip_header_alloc(home, sip_date_class, 0);
  1418. if (d) {
  1419. if (date == 0)
  1420. date = sip_now();
  1421. d->d_time = date;
  1422. }
  1423. return d;
  1424. }
  1425. /* ====================================================================== */
  1426. /**@SIP_HEADER sip_expires Expires Header
  1427. *
  1428. * The Expires header field gives the date and time after which the message
  1429. * content expires. Its syntax is defined in @RFC3261 as follows:
  1430. *
  1431. * @code
  1432. * Expires = "Expires" HCOLON delta-seconds
  1433. * @endcode
  1434. *
  1435. * Note that the first SIP revision (@RFC2543) also allowed absolute time in
  1436. * Expires.
  1437. *
  1438. * The parsed Expires header is stored in #sip_expires_t structure.
  1439. */
  1440. /**@ingroup sip_expires
  1441. * @typedef typedef struct sip_expires_s sip_expires_t;
  1442. *
  1443. * The structure #sip_expires_t contains representation of SIP @Expires
  1444. * header.
  1445. *
  1446. * The #sip_expires_t is defined as follows:
  1447. * @code
  1448. * typedef struct sip_expires_s {
  1449. * sip_common_t ex_common[1]; // Common fragment info
  1450. * sip_error_t *ex_next; // Link to next (dummy)
  1451. * sip_time_t ex_date; // Seconds since Jan 1, 1900
  1452. * sip_time_t ex_delta; // ...or delta seconds
  1453. * } sip_expires_t;
  1454. * @endcode
  1455. */
  1456. msg_hclass_t sip_expires_class[] =
  1457. SIP_HEADER_CLASS(expires, "Expires", "", ex_common, single, any);
  1458. issize_t sip_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  1459. {
  1460. sip_expires_t *expires = (sip_expires_t *)h;
  1461. if (msg_date_delta_d((char const **)&s,
  1462. &expires->ex_date,
  1463. &expires->ex_delta) < 0 || *s)
  1464. return -1;
  1465. else
  1466. return 0;
  1467. }
  1468. issize_t sip_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  1469. {
  1470. sip_expires_t const *expires = (sip_expires_t *)h;
  1471. if (expires->ex_date)
  1472. return msg_date_e(b, bsiz, expires->ex_date + expires->ex_delta);
  1473. else
  1474. return msg_delta_e(b, bsiz, expires->ex_delta);
  1475. }
  1476. /**@ingroup sip_expires
  1477. * @brief Create an @Expires header object.
  1478. *
  1479. * Create an @Expires header object with the expiration time @a delta.
  1480. *
  1481. * @param home memory home used to allocate #sip_expires_t structure
  1482. * @param delta relative expiration time in seconds
  1483. *
  1484. * @return
  1485. * A pointer to newly created @Expires header object when successful or NULL
  1486. * upon an error.
  1487. */
  1488. sip_expires_t *sip_expires_create(su_home_t *home, sip_time_t delta)
  1489. {
  1490. sip_expires_t *ex = (sip_expires_t *)
  1491. sip_header_alloc(home, sip_expires_class, 0);
  1492. if (ex)
  1493. ex->ex_delta = delta;
  1494. return ex;
  1495. }
  1496. /* ====================================================================== */
  1497. /**@SIP_HEADER sip_from From Header
  1498. *
  1499. * The From header indicates the initiator of the request. It is defined in
  1500. * @RFC3261 as follows:
  1501. *
  1502. * @code
  1503. * From = ( "From" / "f" ) HCOLON from-spec
  1504. * from-spec = ( name-addr / addr-spec )
  1505. * *( SEMI from-param )
  1506. * from-param = tag-param / generic-param
  1507. * tag-param = "tag" EQUAL token
  1508. * @endcode
  1509. *
  1510. *
  1511. * The parsed From header is stored in #sip_from_t structure.
  1512. */
  1513. /**@ingroup sip_from
  1514. * @typedef typedef struct sip_addr_s sip_from_t;
  1515. *
  1516. * The structure #sip_from_t contains representation of @From header.
  1517. *
  1518. * The #sip_from_t is defined as follows:
  1519. * @code
  1520. * typedef struct sip_addr_s {
  1521. * sip_common_t a_common[1]; // Common fragment info
  1522. * sip_error_t *a_next; // Link to next
  1523. * char const *a_display; // Display name
  1524. * url_t a_url[1]; // URL
  1525. * msg_param_t const *a_params; // List of from-param
  1526. * char const *a_comment; // Comment
  1527. * char const *a_tag; // Tag parameter
  1528. * } sip_from_t;
  1529. * @endcode
  1530. *
  1531. */
  1532. msg_hclass_t sip_from_class[] =
  1533. SIP_HEADER_CLASS(from, "From", "f", a_params, single, addr);
  1534. issize_t sip_from_d(su_home_t *home,
  1535. sip_header_t *h,
  1536. char *s,
  1537. isize_t slen)
  1538. {
  1539. return sip_addr_d(home, h, s, slen);
  1540. }
  1541. issize_t sip_from_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  1542. {
  1543. assert(sip_is_from(h));
  1544. return sip_addr_e(b, bsiz, h, flags);
  1545. }
  1546. /**@ingroup sip_from
  1547. *
  1548. * Create a @From header object with URL.
  1549. *
  1550. * @param home memory home used to allocate #sip_from_t structure
  1551. * @param s pointer to the URL or a string
  1552. *
  1553. * @return
  1554. * A pointer to newly created @From header object when successful or NULL
  1555. * upon an error.
  1556. */
  1557. sip_from_t *
  1558. sip_from_create(su_home_t *home, url_string_t const *s)
  1559. {
  1560. return sip_addr_make_url(home, sip_from_class, s);
  1561. }
  1562. /**@ingroup sip_from
  1563. *
  1564. * Add a parameter to an #sip_from_t object.
  1565. *
  1566. * @param home memory home
  1567. * @param from a pointer to #sip_from_t object
  1568. * @param param parameter string
  1569. *
  1570. * @retval 0 when successful
  1571. * @retval -1 upon an error
  1572. *
  1573. * @deprecated Use msg_header_replace_param() directly.
  1574. */
  1575. int sip_from_add_param(su_home_t *home,
  1576. sip_from_t *from,
  1577. char const *param)
  1578. {
  1579. return msg_header_replace_param(home, from->a_common, param);
  1580. }
  1581. /**@ingroup sip_from
  1582. *
  1583. * Add a tag to a @From header. If @a tag is
  1584. * identical with the existing one, nothing will be done. An error is
  1585. * returned, if the header already contains a different tag. The @a tag can
  1586. * be provided either as a single token ("deadbeer") or as in parameter form
  1587. * ("tag=deadbeer"). In both cases the tag is duplicated using the memory
  1588. * home @a home.
  1589. *
  1590. * @param home memory home used to allocate new tag
  1591. * @param from @From header to modify
  1592. * @param tag tag token or parameter to be added
  1593. *
  1594. * @retval 0 when successful
  1595. * @retval -1 upon an error.
  1596. */
  1597. int sip_from_tag(su_home_t *home, sip_from_t *from, char const *tag)
  1598. {
  1599. return sip_addr_tag(home, from, tag);
  1600. }
  1601. int sip_to_tag(su_home_t *home, sip_to_t *to, char const *tag)
  1602. {
  1603. return sip_addr_tag(home, to, tag);
  1604. }
  1605. /* ====================================================================== */
  1606. /**@SIP_HEADER sip_max_forwards Max-Forwards Header
  1607. *
  1608. * The Max-Forwards header is used to limit the number of proxies or
  1609. * gateways that can forward the request. The Max-Forwards syntax is
  1610. * defined in @RFC3261 as follows:
  1611. *
  1612. * @code
  1613. * Max-Forwards = "Max-Forwards" HCOLON 1*DIGIT
  1614. * @endcode
  1615. *
  1616. *
  1617. * The parsed Max-Forwards header is stored in #sip_max_forwards_t structure.
  1618. */
  1619. /**@ingroup sip_max_forwards
  1620. * @typedef typedef struct sip_max_forwards_s sip_max_forwards_t;
  1621. *
  1622. * The structure #sip_max_forwards_t contains representation of SIP
  1623. * @MaxForwards header.
  1624. *
  1625. * The #sip_max_forwards_t is defined as follows:
  1626. * @code
  1627. * typedef struct sip_max_forwards_s {
  1628. * sip_common_t mf_common[1]; // Common fragment info
  1629. * sip_error_t *mf_next; // Link to next (dummy)
  1630. * unsigned long mf_count; // Digits
  1631. * } sip_max_forwards_t;
  1632. * @endcode
  1633. */
  1634. msg_hclass_t sip_max_forwards_class[] =
  1635. SIP_HEADER_CLASS(max_forwards, "Max-Forwards", "", mf_common,
  1636. single, any);
  1637. issize_t sip_max_forwards_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  1638. {
  1639. return sip_numeric_d(home, h, s, slen);
  1640. }
  1641. issize_t sip_max_forwards_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  1642. {
  1643. assert(sip_is_max_forwards(h));
  1644. return sip_numeric_e(b, bsiz, h, f);
  1645. }
  1646. /* ====================================================================== */
  1647. /**@SIP_HEADER sip_min_expires Min-Expires Header
  1648. *
  1649. * The Min-Expires header is used to limit the number of proxies or
  1650. * gateways that can forward the request. The Min-Expires syntax is
  1651. * defined in @RFC3261 as follows:
  1652. *
  1653. * @code
  1654. * Min-Expires = "Min-Expires" HCOLON delta-seconds
  1655. * @endcode
  1656. *
  1657. * The parsed Min-Expires header is stored in #sip_min_expires_t structure.
  1658. */
  1659. /**@ingroup sip_min_expires
  1660. * @typedef typedef struct sip_min_expires_s sip_min_expires_t;
  1661. *
  1662. * The structure #sip_min_expires_t contains representation of SIP
  1663. * @MinExpires header.
  1664. *
  1665. * The #sip_min_expires_t is defined as follows:
  1666. * @code
  1667. * typedef struct sip_min_expires_s {
  1668. * sip_common_t me_common[1]; // Common fragment info
  1669. * sip_error_t *me_next; // Link to next (dummy)
  1670. * unsigned long me_delta; // Seconds
  1671. * } sip_min_expires_t;
  1672. * @endcode
  1673. */
  1674. msg_hclass_t sip_min_expires_class[] =
  1675. SIP_HEADER_CLASS(min_expires, "Min-Expires", "", me_common,
  1676. single, any);
  1677. issize_t sip_min_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  1678. {
  1679. return sip_numeric_d(home, h, s, slen);
  1680. }
  1681. issize_t sip_min_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  1682. {
  1683. assert(sip_is_min_expires(h));
  1684. return sip_numeric_e(b, bsiz, h, f);
  1685. }
  1686. /* ====================================================================== */
  1687. /**@SIP_HEADER sip_retry_after Retry-After Header
  1688. *
  1689. * The Retry-After response-header field @RFC3261 section 20.33 can be used to
  1690. * indicate how long the service is expected to be unavailable or when the
  1691. * called party anticipates being available again. Its syntax is defined in
  1692. * @RFC3261 as follows:
  1693. *
  1694. * @code
  1695. * Retry-After = "Retry-After" HCOLON delta-seconds
  1696. * [ comment ] *( SEMI retry-param )
  1697. * retry-param = ("duration" EQUAL delta-seconds)
  1698. * / generic-param
  1699. * @endcode
  1700. *
  1701. * The parsed Retry-After header is stored in #sip_retry_after_t structure.
  1702. */
  1703. /**@ingroup sip_retry_after
  1704. * @typedef struct sip_retry_after_s sip_retry_after_t;
  1705. *
  1706. * The structure #sip_retry_after_t contains representation of an
  1707. * @RetryAfter header.
  1708. *
  1709. * The #sip_retry_after_t is defined as follows:
  1710. * @code
  1711. * typedef struct sip_retry_after_s {
  1712. * sip_common_t af_common[1]; // Common fragment info
  1713. * sip_error_t *af_next; // Link to next (dummy)
  1714. * sip_time_t af_delta; // Seconds to before retry
  1715. * char const *af_comment; // Comment string
  1716. * msg_param_t const *af_params; // List of parameters
  1717. * char const *af_duration; // Duration parameter
  1718. * } sip_retry_after_t;
  1719. * @endcode
  1720. */
  1721. static msg_xtra_f sip_retry_after_dup_xtra;
  1722. static msg_dup_f sip_retry_after_dup_one;
  1723. static msg_update_f sip_retry_after_update;
  1724. msg_hclass_t sip_retry_after_class[] =
  1725. SIP_HEADER_CLASS(retry_after, "Retry-After", "", af_params, single,
  1726. retry_after);
  1727. issize_t sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  1728. {
  1729. sip_retry_after_t *af = (sip_retry_after_t *)h;
  1730. if ((msg_delta_d((char const **)&s, &af->af_delta) < 0) ||
  1731. (*s == '(' && msg_comment_d(&s, &af->af_comment) == -1) ||
  1732. (*s == ';' && msg_params_d(home, &s, &af->af_params) == -1) ||
  1733. (*s != '\0')) {
  1734. if (af->af_params)
  1735. su_free(home, (void *)af->af_params), af->af_params = NULL;
  1736. return -1;
  1737. }
  1738. if (af->af_params)
  1739. msg_header_update_params(h->sh_common, 0);
  1740. return 0;
  1741. }
  1742. issize_t sip_retry_after_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
  1743. {
  1744. sip_retry_after_t const *af = (sip_retry_after_t *)h;
  1745. int const compact = MSG_IS_COMPACT(f);
  1746. char *b0 = b, *end = b + bsiz;
  1747. b += snprintf(b, bsiz, "%lu", af->af_delta);
  1748. if (af->af_comment) {
  1749. if (!compact)
  1750. MSG_CHAR_E(b, end, ' ');
  1751. MSG_CHAR_E(b, end, '(');
  1752. MSG_STRING_E(b, end, af->af_comment);
  1753. MSG_CHAR_E(b, end, ')');
  1754. if (!compact && af->af_params && af->af_params[0])
  1755. MSG_CHAR_E(b, end, ' ');
  1756. }
  1757. if (af->af_params)
  1758. MSG_PARAMS_E(b, end, af->af_params, f);
  1759. MSG_TERM_E(b, end);
  1760. return b - b0;
  1761. }
  1762. isize_t sip_retry_after_dup_xtra(sip_header_t const *h, isize_t offset)
  1763. {
  1764. sip_retry_after_t const *af = (sip_retry_after_t *)h;
  1765. MSG_PARAMS_SIZE(offset, af->af_params);
  1766. offset += MSG_STRING_SIZE(af->af_comment);
  1767. return offset;
  1768. }
  1769. char *sip_retry_after_dup_one(sip_header_t *dst,
  1770. sip_header_t const *src,
  1771. char *b,
  1772. isize_t xtra)
  1773. {
  1774. sip_retry_after_t *af = (sip_retry_after_t *)dst;
  1775. sip_retry_after_t const *o = (sip_retry_after_t *)src;
  1776. char *end = b + xtra;
  1777. b = msg_params_dup(&af->af_params, o->af_params, b, xtra);
  1778. MSG_STRING_DUP(b, af->af_comment, o->af_comment);
  1779. af->af_delta = o->af_delta;
  1780. assert(b <= end); (void)end;
  1781. return b;
  1782. }
  1783. static int sip_retry_after_update(msg_common_t *h,
  1784. char const *name, isize_t namelen,
  1785. char const *value)
  1786. {
  1787. sip_retry_after_t *af = (sip_retry_after_t *)h;
  1788. if (name == NULL) {
  1789. af->af_duration = NULL;
  1790. }
  1791. else if (namelen == strlen("duration") &&
  1792. su_casenmatch(name, "duration", namelen)) {
  1793. af->af_duration = value;
  1794. }
  1795. return 0;
  1796. }
  1797. /* ====================================================================== */
  1798. /**Parse a @Route or a @RecordRoute header.
  1799. *
  1800. * @retval 0 when successful,
  1801. * @retval -1 upon an error.
  1802. */
  1803. issize_t sip_any_route_d(su_home_t *home,
  1804. sip_header_t *h,
  1805. char *s,
  1806. isize_t slen)
  1807. {
  1808. sip_route_t *r;
  1809. assert(h);
  1810. for (;;) {
  1811. r = (sip_route_t *)h;
  1812. while (*s == ',') { /* Ignore empty entries (comma-whitespace) */
  1813. *s = '\0', s += span_lws(s + 1) + 1;
  1814. }
  1815. if (sip_name_addr_d(home, &s, &r->r_display, r->r_url, &r->r_params, NULL) < 0) {
  1816. return -1;
  1817. }
  1818. msg_parse_next_field_without_recursion();
  1819. }
  1820. }
  1821. issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  1822. {
  1823. sip_route_t const *r = (sip_route_t *)h;
  1824. return sip_name_addr_e(b, bsiz, flags,
  1825. r->r_display, 1, r->r_url, r->r_params, NULL);
  1826. }
  1827. isize_t sip_any_route_dup_xtra(sip_header_t const *h, isize_t offset)
  1828. {
  1829. sip_route_t const *r = (sip_route_t *)h;
  1830. return sip_name_addr_xtra(r->r_display,
  1831. r->r_url,
  1832. r->r_params,
  1833. offset);
  1834. }
  1835. char *sip_any_route_dup_one(sip_header_t *dst, sip_header_t const *src,
  1836. char *b,
  1837. isize_t xtra)
  1838. {
  1839. sip_route_t *r = (sip_route_t *)dst;
  1840. sip_route_t const *o = (sip_route_t *)src;
  1841. return sip_name_addr_dup(&r->r_display, o->r_display,
  1842. r->r_url, o->r_url,
  1843. &r->r_params, o->r_params,
  1844. b, xtra);
  1845. }
  1846. #define sip_any_route_update NULL
  1847. /** Create a route.
  1848. *
  1849. * Create a route or record-route entry
  1850. * from two URLs; first one provides the URL, second maddr parameter and
  1851. * port.
  1852. *
  1853. * @param home memory home
  1854. * @param rq_url route URL
  1855. * @param maddr optional route address and port
  1856. * */
  1857. static
  1858. sip_route_t *sip_any_route_create(su_home_t *home,
  1859. msg_hclass_t *hc,
  1860. url_t const *rq_url,
  1861. url_t const *maddr)
  1862. {
  1863. sip_header_t *h;
  1864. sip_route_t *rr;
  1865. url_t url[1];
  1866. size_t xtra, n, n_url, n_params, n_addr;
  1867. char *b, *param;
  1868. *url = *rq_url;
  1869. if (maddr) {
  1870. url->url_port = maddr->url_port;
  1871. url->url_params = NULL;
  1872. }
  1873. n_url = url_xtra(url);
  1874. n_params = maddr && maddr->url_params ? strlen(maddr->url_params) : 0;
  1875. if (maddr && (!maddr->url_params ||
  1876. !url_param(maddr->url_params, "maddr", NULL, 0)))
  1877. n_addr = (n_params != 0) + strlen("maddr=") + strlen(maddr->url_host);
  1878. else
  1879. n_addr = 0;
  1880. xtra = n_url + n_params + n_addr + (n_params || n_addr);
  1881. h = sip_header_alloc(home, hc, xtra);
  1882. if ((rr = (sip_record_route_t *)h)) {
  1883. b = sip_header_data(h);
  1884. n = url_dup(b, n_url, rr->r_url, url);
  1885. assert(n == n_url);
  1886. if (n_params || n_addr) {
  1887. param = b + n_url;
  1888. if (n_params) {
  1889. rr->r_url->url_params = strcpy(param, maddr->url_params);
  1890. param += n_params;
  1891. }
  1892. if (n_addr) {
  1893. if (n_params)
  1894. *param++ = ';';
  1895. strcpy(param, "maddr="), param += strlen("maddr=");
  1896. strcpy(param, maddr->url_host), param += strlen(maddr->url_host);
  1897. }
  1898. assert(b + xtra == param + 1);
  1899. }
  1900. }
  1901. return rr;
  1902. }
  1903. /* ====================================================================== */
  1904. /**@SIP_HEADER sip_route Route Header
  1905. *
  1906. * The Route headers is used to store the route set of a transaction.
  1907. * The Route header is defined in @RFC3261 as follows:
  1908. *
  1909. * @code
  1910. * Route = "Route" HCOLON route-param *(COMMA route-param)
  1911. * route-param = name-addr *( SEMI rr-param )
  1912. * @endcode
  1913. *
  1914. * The parsed Route header is stored in #sip_route_t structure.
  1915. */
  1916. /**@ingroup sip_route
  1917. * @typedef typedef struct sip_route_s sip_route_t;
  1918. *
  1919. * The structure #sip_route_t contains representation of SIP @Route header.
  1920. *
  1921. * The #sip_route_t is defined as follows:
  1922. * @code
  1923. * typedef struct sip_route_s {
  1924. * sip_common_t r_common[1]; // Common fragment info
  1925. * sip_route_t *r_next; // Link to next @Route
  1926. * char const *r_display; // Display name
  1927. * url_t r_url[1]; // @Route URL
  1928. * msg_param_t const *r_params; // List of route parameters
  1929. * } sip_route_t;
  1930. * @endcode
  1931. */
  1932. msg_hclass_t sip_route_class[] =
  1933. SIP_HEADER_CLASS(route, "Route", "", r_params, append, any_route);
  1934. issize_t sip_route_d(su_home_t *home,
  1935. sip_header_t *h,
  1936. char *s,
  1937. isize_t slen)
  1938. {
  1939. return sip_any_route_d(home, h, s, slen);
  1940. }
  1941. issize_t sip_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  1942. {
  1943. assert(sip_is_route(h));
  1944. return sip_any_route_e(b, bsiz, h, flags);
  1945. }
  1946. /**@ingroup sip_route
  1947. * @brief Create a @Route header object.
  1948. *
  1949. * Creates a route entry from two URLs; first one provides the URL, second
  1950. * maddr parameter and port.
  1951. *
  1952. * @param home memory home
  1953. * @param url route URL
  1954. * @param maddr optional route address and port
  1955. *
  1956. * @return
  1957. * Returns a pointer to newly created @Route header object when successful,
  1958. * or NULL upon an error.
  1959. */
  1960. sip_route_t *sip_route_create(su_home_t *home,
  1961. url_t const *url,
  1962. url_t const *maddr)
  1963. {
  1964. return sip_any_route_create(home, sip_route_class, url, maddr);
  1965. }
  1966. /* ====================================================================== */
  1967. /**@SIP_HEADER sip_record_route Record-Route Header
  1968. *
  1969. * The Record-Route headers are used to establish a route for transactions
  1970. * belonging to a session. The Record-Route header is defined in @RFC3261
  1971. * as follows:
  1972. *
  1973. * @code
  1974. * Record-Route = "Record-Route" HCOLON rec-route *(COMMA rec-route)
  1975. * rec-route = name-addr *( SEMI rr-param )
  1976. * rr-param = generic-param
  1977. * @endcode
  1978. *
  1979. * The parsed Record-Route header is stored in #sip_record_route_t structure.
  1980. */
  1981. /**@ingroup sip_record_route
  1982. * @typedef typedef struct sip_record_route_s sip_record_route_t;
  1983. *
  1984. * The structure #sip_record_route_t contains representation of SIP
  1985. * @RecordRoute header.
  1986. *
  1987. * The #sip_record_route_t is defined as follows:
  1988. * @code
  1989. * typedef struct sip_route_s {
  1990. * sip_common_t r_common[1]; // Common fragment info
  1991. * sip_record_route_t *r_next; // Link to next <rec-route>
  1992. * char const *r_display; // Display name
  1993. * url_t r_url[1]; // @RecordRoute URL
  1994. * msg_param_t const *r_params; // List of route parameters
  1995. * } sip_record_route_t;
  1996. * @endcode
  1997. */
  1998. msg_hclass_t sip_record_route_class[] =
  1999. SIP_HEADER_CLASS(record_route, "Record-Route", "",
  2000. r_params, prepend, any_route);
  2001. issize_t sip_record_route_d(su_home_t *home,
  2002. sip_header_t *h,
  2003. char *s,
  2004. isize_t slen)
  2005. {
  2006. return sip_any_route_d(home, h, s, slen);
  2007. }
  2008. issize_t sip_record_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  2009. {
  2010. assert(sip_is_record_route(h));
  2011. return sip_any_route_e(b, bsiz, h, flags);
  2012. }
  2013. /** @ingroup sip_record_route
  2014. *
  2015. * Create a record-route.
  2016. *
  2017. * Create a record-route entry from two URLs; first one provides the URL,
  2018. * second maddr parameter and port.
  2019. *
  2020. * @param home memory home
  2021. * @param rq_url route URL
  2022. * @param maddr optional route address and port
  2023. *
  2024. * @return
  2025. * A pointer to newly created @RecordRoute header object when successful or
  2026. * NULL upon an error.
  2027. */
  2028. sip_record_route_t *sip_record_route_create(su_home_t *home,
  2029. url_t const *rq_url,
  2030. url_t const *maddr)
  2031. {
  2032. return sip_any_route_create(home, sip_record_route_class, rq_url, maddr);
  2033. }
  2034. /* ====================================================================== */
  2035. /**@SIP_HEADER sip_to To Header
  2036. *
  2037. * The To header field specifies the "logical" recipient of the
  2038. * request. It is defined in @RFC3261 as follows:
  2039. *
  2040. * @code
  2041. * To = ( "To" / "t" ) HCOLON ( name-addr
  2042. * / addr-spec ) *( SEMI to-param )
  2043. * to-param = tag-param / generic-param
  2044. * @endcode
  2045. *
  2046. * The parsed To header is stored in #sip_to_t structure.
  2047. */
  2048. /**@ingroup sip_to
  2049. * @typedef typedef struct sip_addr_s sip_to_t;
  2050. *
  2051. * The structure #sip_to_t contains representation of @To header.
  2052. *
  2053. * The #sip_to_t is defined as follows:
  2054. * @code
  2055. * typedef struct {
  2056. * sip_common_t a_common[1]; // Common fragment info
  2057. * sip_error_t *a_next; // Link to next (dummy)
  2058. * char const *a_display; // Display name
  2059. * url_t a_url[1]; // URL
  2060. * msg_param_t const *a_params; // List of to-params
  2061. * char const *a_comment; // Comment
  2062. * char const *a_tag; // Tag parameter
  2063. * } sip_to_t;
  2064. * @endcode
  2065. *
  2066. */
  2067. msg_hclass_t sip_to_class[] =
  2068. SIP_HEADER_CLASS(to, "To", "t", a_params, single, addr);
  2069. issize_t sip_to_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  2070. {
  2071. return sip_addr_d(home, h, s, slen);
  2072. }
  2073. issize_t sip_to_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  2074. {
  2075. assert(sip_is_to(h));
  2076. return sip_addr_e(b, bsiz, h, flags);
  2077. }
  2078. /**@ingroup sip_to
  2079. *
  2080. * Create a @To header object with URL.
  2081. *
  2082. * @param home memory home
  2083. * @param url URL (string or pointer to url_t)
  2084. *
  2085. * @return
  2086. * A pointer to newly created @To header object when successful or NULL upon
  2087. * an error.
  2088. */
  2089. sip_to_t *
  2090. sip_to_create(su_home_t *home, url_string_t const *url)
  2091. {
  2092. return sip_addr_make_url(home, sip_to_class, url);
  2093. }
  2094. /**@ingroup sip_to
  2095. *
  2096. * Add a parameter to a #sip_to_t object.
  2097. *
  2098. * @note This function @b does @b not duplicate @p param.
  2099. *
  2100. * @param home memory home
  2101. * @param to #sip_to_t structure
  2102. * @param param parameter string
  2103. *
  2104. * @retval 0 when successful
  2105. * @retval -1 upon an error
  2106. *
  2107. * @deprecated Use msg_header_replace_param() directly.
  2108. */
  2109. int sip_to_add_param(su_home_t *home,
  2110. sip_to_t *to,
  2111. char const *param)
  2112. {
  2113. return msg_header_replace_param(home, to->a_common, param);
  2114. }
  2115. /* ====================================================================== */
  2116. /**@SIP_HEADER sip_via Via Header
  2117. *
  2118. * The Via header indicates the path taken by the request so far. Via
  2119. * headers can be used to prevent request looping and ensure replies take
  2120. * the same path as the requests. The Via syntax is defined in @RFC3261
  2121. * as follows:
  2122. *
  2123. * @code
  2124. * Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
  2125. * via-parm = sent-protocol LWS sent-by *( SEMI via-params )
  2126. * via-params = via-ttl / via-maddr
  2127. * / via-received / via-branch
  2128. * / via-extension
  2129. * via-ttl = "ttl" EQUAL ttl
  2130. * via-maddr = "maddr" EQUAL host
  2131. * via-received = "received" EQUAL (IPv4address / IPv6address)
  2132. * via-branch = "branch" EQUAL token
  2133. * via-extension = generic-param
  2134. * sent-protocol = protocol-name SLASH protocol-version
  2135. * SLASH transport
  2136. * protocol-name = "SIP" / token
  2137. * protocol-version = token
  2138. * transport = "UDP" / "TCP" / "TLS" / "SCTP"
  2139. * / other-transport
  2140. * sent-by = host [ COLON port ]
  2141. * ttl = 1*3DIGIT ; 0 to 255
  2142. * @endcode
  2143. *
  2144. * @note
  2145. * The @RFC2543 syntax allowed <comment>. We accept it, but don't encode it.
  2146. *
  2147. * In addition to the parameters defined in @RFC3261, @RFC3486 defines a
  2148. * parameter "comp":
  2149. * @code
  2150. * via-compression = "comp" EQUAL ("sigcomp" / other-compression)
  2151. * via-params /= via-compression
  2152. * @endcode
  2153. *
  2154. * @RFC3581 defines a parameter "rport":
  2155. * @code
  2156. * response-port = "rport" [EQUAL 1*DIGIT]
  2157. * via-params /= response-port
  2158. * @endcode
  2159. *
  2160. * The parsed Via header is stored in #sip_via_t structure.
  2161. */
  2162. /**@ingroup sip_via
  2163. * @typedef typedef struct sip_via_s sip_via_t;
  2164. *
  2165. * The structure #sip_via_t contains representation of SIP @Via header.
  2166. *
  2167. * The #sip_via_t is defined as follows:
  2168. * @code
  2169. * typedef struct sip_via_s {
  2170. * sip_common_t v_common[1]; // Common fragment info
  2171. * sip_via_t *v_next; // Link to next @Via header
  2172. * char const *v_protocol; // Application and transport protocol
  2173. * char const *v_host; // Hostname
  2174. * char const *v_port; // Port number
  2175. * msg_param_t const *v_params; // List of via-params
  2176. * char const *v_comment; // Comment
  2177. *
  2178. * char const *v_ttl; // "ttl" parameter
  2179. * char const *v_maddr; // "maddr" parameter
  2180. * char const *v_received; // "received" parameter
  2181. * char const *v_branch; // "branch" parameter
  2182. * char const *v_comp; // "comp" parameter
  2183. * char const *v_rport; // "rport" parameter
  2184. * } sip_via_t;
  2185. * @endcode
  2186. */
  2187. static msg_xtra_f sip_via_dup_xtra;
  2188. static msg_dup_f sip_via_dup_one;
  2189. static msg_update_f sip_via_update;
  2190. msg_hclass_t sip_via_class[] =
  2191. SIP_HEADER_CLASS(via, "Via", "v", v_params, prepend, via);
  2192. issize_t sip_via_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  2193. {
  2194. sip_via_t *v;
  2195. assert(h);
  2196. for (;;) {
  2197. v = (sip_via_t *)h;
  2198. while (*s == ',') /* Ignore empty entries (comma-whitespace) */
  2199. *s = '\0', s += span_lws(s + 1) + 1;
  2200. /* sent-protocol sent-by *( ";" via-params ) [ comment ] */
  2201. /* Parse protocol */
  2202. if (sip_transport_d(&s, &v->v_protocol) == -1)
  2203. return -1;
  2204. /* Host (and port) */
  2205. if (msg_hostport_d(&s, &v->v_host, &v->v_port) == -1)
  2206. return -1;
  2207. /* Parameters */
  2208. if (*s == ';' && msg_params_d(home, &s, &v->v_params) == -1)
  2209. return -1;
  2210. /* Comment */
  2211. if (*s == '(' && msg_comment_d(&s, &v->v_comment) == -1)
  2212. return -1;
  2213. msg_parse_next_field_without_recursion();
  2214. }
  2215. }
  2216. issize_t sip_via_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  2217. {
  2218. char *b0 = b, *end = b + bsiz;
  2219. sip_via_t const *v = (sip_via_t *)h;
  2220. assert(sip_is_via(h));
  2221. MSG_STRING_E(b, end, v->v_protocol);
  2222. MSG_CHAR_E(b, end, ' ');
  2223. MSG_STRING_E(b, end, v->v_host);
  2224. if (v->v_port) {
  2225. MSG_CHAR_E(b, end, ':');
  2226. MSG_STRING_E(b, end, v->v_port);
  2227. }
  2228. MSG_PARAMS_E(b, end, v->v_params, flags);
  2229. #if 0
  2230. /* Comment is deprecated in @RFC3265 - accept it, but do not send */
  2231. if (v->v_comment) {
  2232. if (!MSG_IS_COMPACT(flags))
  2233. MSG_CHAR_E(b, end, ' ');
  2234. MSG_CHAR_E(b, end, '(');
  2235. MSG_STRING_E(b, end, v->v_comment);
  2236. MSG_CHAR_E(b, end, ')');
  2237. }
  2238. #endif
  2239. MSG_TERM_E(b, end);
  2240. return b - b0;
  2241. }
  2242. isize_t sip_via_dup_xtra(sip_header_t const *h, isize_t offset)
  2243. {
  2244. sip_via_t const *v = (sip_via_t *)h;
  2245. MSG_PARAMS_SIZE(offset, v->v_params);
  2246. offset += sip_transport_xtra(v->v_protocol);
  2247. offset += MSG_STRING_SIZE(v->v_host);
  2248. offset += MSG_STRING_SIZE(v->v_port);
  2249. offset += MSG_STRING_SIZE(v->v_comment);
  2250. return offset;
  2251. }
  2252. /** Duplicate one #sip_via_t object */
  2253. char *sip_via_dup_one(sip_header_t *dst, sip_header_t const *src,
  2254. char *b, isize_t xtra)
  2255. {
  2256. sip_via_t *v = (sip_via_t *)dst;
  2257. sip_via_t const *o = (sip_via_t *)src;
  2258. char *end = b + xtra;
  2259. b = msg_params_dup(&v->v_params, o->v_params, b, xtra);
  2260. sip_transport_dup(&b, &v->v_protocol, o->v_protocol);
  2261. MSG_STRING_DUP(b, v->v_host, o->v_host);
  2262. MSG_STRING_DUP(b, v->v_port, o->v_port);
  2263. MSG_STRING_DUP(b, v->v_comment, o->v_comment);
  2264. assert(b <= end); (void)end;
  2265. return b;
  2266. }
  2267. static int sip_via_update(msg_common_t *h,
  2268. char const *name, isize_t namelen,
  2269. char const *value)
  2270. {
  2271. sip_via_t *v = (sip_via_t *)h;
  2272. if (name == NULL) {
  2273. v->v_ttl = NULL;
  2274. v->v_maddr = NULL;
  2275. v->v_received = NULL;
  2276. v->v_branch = NULL;
  2277. v->v_rport = NULL;
  2278. v->v_comp = NULL;
  2279. }
  2280. #define MATCH(s) (namelen == strlen(#s) && su_casenmatch(name, #s, strlen(#s)))
  2281. else if (MATCH(ttl)) {
  2282. v->v_ttl = value;
  2283. }
  2284. else if (MATCH(maddr)) {
  2285. v->v_maddr = value;
  2286. }
  2287. else if (MATCH(received)) {
  2288. v->v_received = value;
  2289. }
  2290. else if (MATCH(branch)) {
  2291. v->v_branch = value;
  2292. }
  2293. else if (MATCH(rport)) {
  2294. v->v_rport = value;
  2295. }
  2296. else if (MATCH(comp)) {
  2297. v->v_comp = value;
  2298. }
  2299. #undef MATCH
  2300. return 0;
  2301. }
  2302. /**@ingroup sip_via
  2303. *
  2304. * Add a parameter to a @Via object.
  2305. *
  2306. * @note This function @b does @b not duplicate @p param.
  2307. *
  2308. * @param home memory home
  2309. * @param v #sip_via_t object
  2310. * @param param parameter string
  2311. *
  2312. * @retval 0 when successful
  2313. * @retval -1 upon an error.
  2314. *
  2315. * @deprecated Use msg_header_replace_param() directly.
  2316. */
  2317. int sip_via_add_param(su_home_t *home,
  2318. sip_via_t *v,
  2319. char const *param)
  2320. {
  2321. return msg_header_replace_param(home, v->v_common, param);
  2322. }
  2323. /**@ingroup sip_via
  2324. *
  2325. * Create a @Via object.
  2326. *
  2327. * Create a new @Via header object with
  2328. * given parameters. If @a transport is NULL, the default transport
  2329. * "SIP/2.0/UDP" is used. A NULL-terminated list of parameters can be
  2330. * specified after transport.
  2331. *
  2332. * @param home memory home
  2333. * @param host host name
  2334. * @param port protocol port number
  2335. * @param transport transport protocol (default is "SIP/2.0/UDP")
  2336. * @param ... NULL-terminated list of parameters
  2337. *
  2338. * @return
  2339. * A pointer to newly created
  2340. * @Via header object when successful or NULL upon an error.
  2341. */
  2342. sip_via_t *sip_via_create(su_home_t *home,
  2343. char const *host,
  2344. char const *port,
  2345. char const *transport,
  2346. /* char const *params */
  2347. ...)
  2348. {
  2349. sip_via_t *v, via[1] = {{{{ NULL }}}};
  2350. va_list params;
  2351. via->v_common->h_class = sip_via_class;
  2352. if (transport)
  2353. via->v_protocol = transport;
  2354. else
  2355. via->v_protocol = sip_transport_udp;
  2356. via->v_host = host;
  2357. via->v_port = port;
  2358. v = (sip_via_t *)msg_header_dup_as(home, sip_via_class, (sip_header_t *)via);
  2359. if (v) {
  2360. char const *param;
  2361. va_start(params, transport);
  2362. for (param = va_arg(params, char const *);
  2363. param;
  2364. param = va_arg(params, char const *)) {
  2365. if ((param = su_strdup(home, param))) {
  2366. if (msg_header_replace_param(home, v->v_common, param) < 0)
  2367. break;
  2368. }
  2369. }
  2370. va_end(params);
  2371. }
  2372. return v;
  2373. }
  2374. /**@ingroup sip_via
  2375. *
  2376. * Get port number corresponding to a @Via line.
  2377. *
  2378. * If @a using_rport is non-null, try rport.
  2379. * If *using_rport is non-zero, try rport even if <protocol> is not UDP.
  2380. * If <protocol> is UDP, set *using_rport to zero.
  2381. */
  2382. char const *sip_via_port(sip_via_t const *v, int *using_rport)
  2383. {
  2384. if (v == NULL)
  2385. return NULL;
  2386. if (using_rport) {
  2387. char const *port;
  2388. if (v->v_rport && !v->v_maddr /* multicast */) {
  2389. if (v->v_protocol == sip_transport_udp ||
  2390. su_casematch(v->v_protocol, sip_transport_udp))
  2391. port = v->v_rport, *using_rport = 0;
  2392. else if (*using_rport)
  2393. port = v->v_rport;
  2394. else
  2395. port = NULL;
  2396. if (port && port[0])
  2397. return port;
  2398. }
  2399. *using_rport = 0; /* No, we don't... */
  2400. }
  2401. if (v->v_port)
  2402. return v->v_port;
  2403. if (sip_transport_has_tls(v->v_protocol))
  2404. return SIPS_DEFAULT_SERV; /* 5061 */
  2405. else
  2406. return SIP_DEFAULT_SERV; /* 5060 */
  2407. }
  2408. /**@SIP_HEADER sip_identity Identity Header
  2409. *
  2410. * The Identity header field specifies the "logical" recipient of the
  2411. * request. It is defined in @RFC8224 with semantics shown below,
  2412. * though for now it's parsed to a single 'value' field.
  2413. *
  2414. * @code
  2415. * Identity = "Identity" HCOLON signed-identity-digest SEMI
  2416. * ident-info *( SEMI ident-info-params )
  2417. * signed-identity-digest = 1*(base64-char / ".")
  2418. * ident-info = "info" EQUAL ident-info-uri
  2419. * ident-info-uri = LAQUOT absoluteURI RAQUOT
  2420. * ident-info-params = ident-info-alg / ident-type /
  2421. * ident-info-extension
  2422. * ident-info-alg = "alg" EQUAL token
  2423. * ident-type = "ppt" EQUAL token
  2424. * ident-info-extension = generic-param
  2425. *
  2426. * base64-char = ALPHA / DIGIT / "/" / "+"
  2427. * @endcode
  2428. *
  2429. * The parsed Identity header is stored in #sip_identity_t structure.
  2430. */
  2431. /**@ingroup sip_identity
  2432. * @typedef typedef struct sip_identity_s sip_identity_t;
  2433. *
  2434. * The structure #sip_identity_t contains representation of @Identity header.
  2435. *
  2436. * The #sip_identity_t is defined as follows:
  2437. * @code
  2438. * typedef struct {
  2439. * sip_common_t id_common[1]; // Common fragment info
  2440. * sip_identity_t *id_next; // Link to next Identity
  2441. * char const *id_value; // Identity
  2442. * char const *id_info; // Info param containing URL of the cert, with no '<','>'
  2443. * char const *id_signed_identity_digest; // Digest
  2444. * char const *id_info_alg; // Field containing alg of the cert
  2445. * char const *id_info_ppt; // Field containing PASSporT Type
  2446. * msg_param_t const *id_info_params; // Field containing extensions
  2447. * } sip_identity_t;
  2448. * @endcode
  2449. *
  2450. */
  2451. static msg_xtra_f sip_identity_dup_xtra;
  2452. static msg_dup_f sip_identity_dup_one;
  2453. static msg_update_f sip_identity_update;
  2454. msg_hclass_t sip_identity_class[] =
  2455. SIP_HEADER_CLASS(identity, "Identity", "", id_common, non_compact_append, identity);
  2456. issize_t sip_identity_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
  2457. {
  2458. sip_identity_t *id = (sip_identity_t *)h;
  2459. char const *p = NULL, *pp = NULL, *ppp = NULL, *ie = NULL;
  2460. char *sid = NULL, *uri = NULL, *alg = NULL, *ppt = NULL, *ext = NULL;
  2461. size_t len = 0;
  2462. id->id_value = su_strdup(home, s);
  2463. id->id_signed_identity_digest = s;
  2464. id->id_info = NULL;
  2465. sid = strchr(s, ';');
  2466. p = strstr(s, "info=");
  2467. alg = strstr(s, "alg=");
  2468. ppt = strstr(s, "ppt=");
  2469. if (sid) {
  2470. *sid = '\0';
  2471. } else {
  2472. id->id_signed_identity_digest = NULL;
  2473. }
  2474. if (p) {
  2475. ie = strchr(p, ';');
  2476. if (!ie) ie = strchr(p, '\0');
  2477. pp = strchr(p, '<');
  2478. ppp = strchr(p, '>');
  2479. // allow for a spaces between "info=" and opening '<'
  2480. // extract URI from inside "<>" but allow empty - let the higher level app decide what to do about it
  2481. if (ie && pp && ppp && (pp < ppp) && (ppp < ie)) {
  2482. len = ppp - pp;
  2483. uri = pp + 1;
  2484. uri[len - 1] = '\0';
  2485. id->id_info = uri;
  2486. }
  2487. }
  2488. if (alg) {
  2489. alg += 4;
  2490. id->id_info_alg = alg;
  2491. alg = strchr(alg, ';');
  2492. if (alg) {
  2493. *alg = '\0';
  2494. }
  2495. }
  2496. if (ppt) {
  2497. ext = strchr(ppt, ';');
  2498. if (ext) {
  2499. msg_param_t *params = su_alloc(home, sizeof(msg_param_t));
  2500. if (msg_params_d(home, &ext, &params) >= 0) {
  2501. id->id_info_params = params;
  2502. }
  2503. }
  2504. ppt += 4;
  2505. id->id_info_ppt = ppt;
  2506. ppt = strchr(ppt, ';');
  2507. if (ppt) {
  2508. *ppt = '\0';
  2509. }
  2510. }
  2511. return 0;
  2512. }
  2513. issize_t sip_identity_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
  2514. {
  2515. char* b0 = b, * end = b + bsiz;
  2516. sip_identity_t const* id = (sip_identity_t*)h;
  2517. if (id->id_signed_identity_digest) {
  2518. MSG_STRING_E(b, end, id->id_signed_identity_digest);
  2519. }
  2520. if (id->id_info) {
  2521. MSG_STRING_E(b, end, ";info=<");
  2522. MSG_STRING_E(b, end, id->id_info);
  2523. MSG_STRING_E(b, end, ">");
  2524. }
  2525. if (id->id_info_alg) {
  2526. MSG_STRING_E(b, end, ";alg=");
  2527. MSG_STRING_E(b, end, id->id_info_alg);
  2528. }
  2529. if (id->id_info_ppt) {
  2530. MSG_STRING_E(b, end, ";ppt=");
  2531. MSG_STRING_E(b, end, id->id_info_ppt);
  2532. /* No need to put ';' as following MSG_PARAMS_E starts from ';' */
  2533. }
  2534. if (id->id_info_params) {
  2535. MSG_PARAMS_E(b, end, id->id_info_params, flags);
  2536. }
  2537. MSG_TERM_E(b, end);
  2538. return b - b0;
  2539. }
  2540. isize_t sip_identity_dup_xtra(sip_header_t const *h, isize_t offset)
  2541. {
  2542. sip_identity_t const *id = (sip_identity_t *)h;
  2543. offset += MSG_STRING_SIZE(id->id_value);
  2544. offset += MSG_STRING_SIZE(id->id_signed_identity_digest);
  2545. offset += MSG_STRING_SIZE(id->id_info);
  2546. offset += MSG_STRING_SIZE(id->id_info_alg);
  2547. offset += MSG_STRING_SIZE(id->id_info_ppt);
  2548. MSG_PARAMS_SIZE(offset, id->id_info_params);
  2549. return offset;
  2550. }
  2551. char *sip_identity_dup_one(sip_header_t *dst, sip_header_t const *src,
  2552. char *b, isize_t xtra)
  2553. {
  2554. sip_identity_t* o_dst = dst->sh_identity;
  2555. sip_identity_t const* o_src = src->sh_identity;
  2556. char* end = b + xtra;
  2557. b = msg_params_dup(&o_dst->id_info_params, o_src->id_info_params, b, xtra);
  2558. o_dst->id_value = o_src->id_value;
  2559. o_dst->id_signed_identity_digest = o_src->id_signed_identity_digest;
  2560. o_dst->id_info = o_src->id_info;
  2561. o_dst->id_info_alg = o_src->id_info_alg;
  2562. o_dst->id_info_ppt = o_src->id_info_ppt;
  2563. assert(b <= end); (void)end;
  2564. return b;
  2565. }
  2566. static int sip_identity_update(msg_common_t *h,
  2567. char const *name, isize_t namelen,
  2568. char const *value)
  2569. {
  2570. sip_identity_t *id = (sip_identity_t *)h;
  2571. if (name == NULL) {
  2572. id->id_value = NULL;
  2573. id->id_signed_identity_digest = NULL;
  2574. id->id_info = NULL;
  2575. id->id_info_alg = NULL;
  2576. id->id_info_ppt = NULL;
  2577. id->id_info_params = NULL;
  2578. }
  2579. #define MATCH(s) (namelen == strlen(#s) && su_casenmatch(name, #s, strlen(#s)))
  2580. else if (MATCH(digest)) {
  2581. id->id_signed_identity_digest = value;
  2582. } else if (MATCH(uri)) {
  2583. id->id_info = value;
  2584. } else if (MATCH(alg)) {
  2585. id->id_info_alg = value;
  2586. } else if (MATCH(ppt)) {
  2587. id->id_info_ppt = value;
  2588. } else if (MATCH(value)) {
  2589. id->id_value = value;
  2590. }
  2591. #undef MATCH
  2592. return 0;
  2593. }