rtpproxy.c 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405
  1. /* $Id$
  2. *
  3. * Copyright (C) 2003-2008 Sippy Software, Inc., http://www.sippysoft.com
  4. *
  5. * This file is part of Kamailio, a free SIP server.
  6. *
  7. * Kamailio is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version
  11. *
  12. * Kamailio is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * History:
  22. * ---------
  23. * 2003-10-09 nat_uac_test introduced (jiri)
  24. *
  25. * 2003-11-06 nat_uac_test permitted from onreply_route (jiri)
  26. *
  27. * 2003-12-01 unforce_rtp_proxy introduced (sobomax)
  28. *
  29. * 2004-01-07 RTP proxy support updated to support new version of the
  30. * RTP proxy (20040107).
  31. *
  32. * force_rtp_proxy() now inserts a special flag
  33. * into the SDP body to indicate that this session already
  34. * proxied and ignores sessions with such flag.
  35. *
  36. * Added run-time check for version of command protocol
  37. * supported by the RTP proxy.
  38. *
  39. * 2004-01-16 Integrated slightly modified patch from Tristan Colgate,
  40. * force_rtp_proxy function with IP as a parameter (janakj)
  41. *
  42. * 2004-01-28 nat_uac_test extended to allow testing SDP body (sobomax)
  43. *
  44. * nat_uac_test extended to allow testing top Via (sobomax)
  45. *
  46. * 2004-02-21 force_rtp_proxy now accepts option argument, which
  47. * consists of string of chars, each of them turns "on"
  48. * some feature, currently supported ones are:
  49. *
  50. * `a' - flags that UA from which message is received
  51. * doesn't support symmetric RTP;
  52. * `l' - force "lookup", that is, only rewrite SDP when
  53. * corresponding session is already exists in the
  54. * RTP proxy. Only makes sense for SIP requests,
  55. * replies are always processed in "lookup" mode;
  56. * `i' - flags that message is received from UA in the
  57. * LAN. Only makes sense when RTP proxy is running
  58. * in the bridge mode.
  59. *
  60. * force_rtp_proxy can now be invoked without any arguments,
  61. * as previously, with one argument - in this case argument
  62. * is treated as option string and with two arguments, in
  63. * which case 1st argument is option string and the 2nd
  64. * one is IP address which have to be inserted into
  65. * SDP (IP address on which RTP proxy listens).
  66. *
  67. * 2004-03-12 Added support for IPv6 addresses in SDPs. Particularly,
  68. * force_rtp_proxy now can work with IPv6-aware RTP proxy,
  69. * replacing IPv4 address in SDP with IPv6 one and vice versa.
  70. * This allows creating full-fledged IPv4<->IPv6 gateway.
  71. * See 4to6.cfg file for example.
  72. *
  73. * Two new options added into force_rtp_proxy:
  74. *
  75. * `f' - instructs nathelper to ignore marks inserted
  76. * by another nathelper in transit to indicate
  77. * that the session is already goes through another
  78. * proxy. Allows creating chain of proxies.
  79. * `r' - flags that IP address in SDP should be trusted.
  80. * Without this flag, nathelper ignores address in the
  81. * SDP and uses source address of the SIP message
  82. * as media address which is passed to the RTP proxy.
  83. *
  84. * Protocol between nathelper and RTP proxy in bridge
  85. * mode has been slightly changed. Now RTP proxy expects SER
  86. * to provide 2 flags when creating or updating session
  87. * to indicate direction of this session. Each of those
  88. * flags can be either `e' or `i'. For example `ei' means
  89. * that we received INVITE from UA on the "external" network
  90. * network and will send it to the UA on "internal" one.
  91. * Also possible `ie' (internal->external), `ii'
  92. * (internal->internal) and `ee' (external->external). See
  93. * example file alg.cfg for details.
  94. *
  95. * 2004-03-15 If the rtp proxy test failed (wrong version or not started)
  96. * retry test from time to time, when some *rtpproxy* function
  97. * is invoked. Minimum interval between retries can be
  98. * configured via rtpproxy_disable_tout module parameter (default
  99. * is 60 seconds). Setting it to -1 will disable periodic
  100. * rechecks completely, setting it to 0 will force checks
  101. * for each *rtpproxy* function call. (andrei)
  102. *
  103. * 2004-03-22 Fix assignment of rtpproxy_retr and rtpproxy_tout module
  104. * parameters.
  105. *
  106. * 2004-03-22 Fix get_body position (should be called before get_callid)
  107. * (andrei)
  108. *
  109. * 2004-03-24 Fix newport for null ip address case (e.g onhold re-INVITE)
  110. * (andrei)
  111. *
  112. * 2004-09-30 added received port != via port test (andrei)
  113. *
  114. * 2004-10-10 force_socket option introduced (jiri)
  115. *
  116. * 2005-02-24 Added support for using more than one rtp proxy, in which
  117. * case traffic will be distributed evenly among them. In addition,
  118. * each such proxy can be assigned a weight, which will specify
  119. * which share of the traffic should be placed to this particular
  120. * proxy.
  121. *
  122. * Introduce failover mechanism, so that if SER detects that one
  123. * of many proxies is no longer available it temporarily decreases
  124. * its weight to 0, so that no traffic will be assigned to it.
  125. * Such "disabled" proxies are periodically checked to see if they
  126. * are back to normal in which case respective weight is restored
  127. * resulting in traffic being sent to that proxy again.
  128. *
  129. * Those features can be enabled by specifying more than one "URI"
  130. * in the rtpproxy_sock parameter, optionally followed by the weight,
  131. * which if absent is assumed to be 1, for example:
  132. *
  133. * rtpproxy_sock="unix:/foo/bar=4 udp:1.2.3.4:3456=3 udp:5.6.7.8:5432=1"
  134. *
  135. * 2005-02-25 Force for pinging the socket returned by USRLOC (bogdan)
  136. *
  137. * 2005-03-22 support for multiple media streams added (netch)
  138. *
  139. * 2005-07-11 SIP ping support added (bogdan)
  140. *
  141. * 2005-07-14 SDP origin (o=) IP may be also changed (bogdan)
  142. *
  143. * 2006-03-08 fix_nated_sdp() may take one more param to force a specific IP;
  144. * force_rtp_proxy() accepts a new flag 's' to swap creation/
  145. * confirmation between requests/replies;
  146. * add_rcv_param() may take as parameter a flag telling if the
  147. * parameter should go to the contact URI or contact header;
  148. * (bogdan)
  149. * 2006-03-28 Support for changing session-level SDP connection (c=) IP when
  150. * media-description also includes connection information (bayan)
  151. * 2007-04-13 Support multiple sets of rtpproxies and set selection added
  152. * (ancuta)
  153. * 2007-04-26 Added some MI commands:
  154. * nh_enable_ping used to enable or disable natping
  155. * nh_enable_rtpp used to enable or disable a specific rtp proxy
  156. * nh_show_rtpp used to display information for all rtp proxies
  157. * (ancuta)
  158. * 2007-05-09 New function start_recording() allowing to start recording RTP
  159. * session in the RTP proxy (Carsten Bock - ported from SER)
  160. * 2007-09-11 Separate timer process and support for multiple timer processes
  161. * (bogdan)
  162. * 2008-12-12 Support for RTCP attribute in the SDP
  163. * (Min Wang/BASIS AudioNet - ported from SER)
  164. * 2010-08-05 Core SDP parser integrated into nathelper (osas)
  165. * 2010-10-08 Removal of deprecated force_rtp_proxy and swap flag (osas)
  166. */
  167. #include <sys/types.h>
  168. #include <sys/socket.h>
  169. #include <sys/time.h>
  170. #include <netinet/in.h>
  171. #include <netinet/in_systm.h>
  172. #ifndef __USE_BSD
  173. #define __USE_BSD
  174. #endif
  175. #include <netinet/ip.h>
  176. #ifndef __FAVOR_BSD
  177. #define __FAVOR_BSD
  178. #endif
  179. #include <netinet/udp.h>
  180. #include <arpa/inet.h>
  181. #include <sys/uio.h>
  182. #include <sys/un.h>
  183. #include <ctype.h>
  184. #include <errno.h>
  185. #include <netdb.h>
  186. #include <poll.h>
  187. #include <stdio.h>
  188. #include <stdlib.h>
  189. #include <string.h>
  190. #include <unistd.h>
  191. #include "../../flags.h"
  192. #include "../../sr_module.h"
  193. #include "../../dprint.h"
  194. #include "../../data_lump.h"
  195. #include "../../data_lump_rpl.h"
  196. #include "../../error.h"
  197. #include "../../forward.h"
  198. #include "../../mem/mem.h"
  199. #include "../../parser/parse_from.h"
  200. #include "../../parser/parse_to.h"
  201. #include "../../parser/parse_uri.h"
  202. #include "../../parser/parser_f.h"
  203. #include "../../parser/sdp/sdp.h"
  204. #include "../../resolve.h"
  205. #include "../../timer.h"
  206. #include "../../trim.h"
  207. #include "../../ut.h"
  208. #include "../../pt.h"
  209. #include "../../timer_proc.h"
  210. #include "../../lib/kmi/mi.h"
  211. #include "../../lib/kcore/km_ut.h"
  212. #include "../../lib/kcore/parser_helpers.h"
  213. #include "../../pvar.h"
  214. #include "../../lvalue.h"
  215. #include "../../msg_translator.h"
  216. #include "../../usr_avp.h"
  217. #include "../../socket_info.h"
  218. #include "../../mod_fix.h"
  219. #include "../../dset.h"
  220. #include "rtpproxy.h"
  221. #include "rtpproxy_funcs.h"
  222. #include "rtpproxy_stream.h"
  223. MODULE_VERSION
  224. #if !defined(AF_LOCAL)
  225. #define AF_LOCAL AF_UNIX
  226. #endif
  227. #if !defined(PF_LOCAL)
  228. #define PF_LOCAL PF_UNIX
  229. #endif
  230. /* NAT UAC test constants */
  231. #define NAT_UAC_TEST_C_1918 0x01
  232. #define NAT_UAC_TEST_RCVD 0x02
  233. #define NAT_UAC_TEST_V_1918 0x04
  234. #define NAT_UAC_TEST_S_1918 0x08
  235. #define NAT_UAC_TEST_RPORT 0x10
  236. #define DEFAULT_RTPP_SET_ID 0
  237. #define MI_SET_NATPING_STATE "nh_enable_ping"
  238. #define MI_DEFAULT_NATPING_STATE 1
  239. #define MI_ENABLE_RTP_PROXY "nh_enable_rtpp"
  240. #define MI_MIN_RECHECK_TICKS 0
  241. #define MI_MAX_RECHECK_TICKS (unsigned int)-1
  242. #define MI_SHOW_RTP_PROXIES "nh_show_rtpp"
  243. #define MI_RTP_PROXY_NOT_FOUND "RTP proxy not found"
  244. #define MI_RTP_PROXY_NOT_FOUND_LEN (sizeof(MI_RTP_PROXY_NOT_FOUND)-1)
  245. #define MI_PING_DISABLED "NATping disabled from script"
  246. #define MI_PING_DISABLED_LEN (sizeof(MI_PING_DISABLED)-1)
  247. #define MI_SET "set"
  248. #define MI_SET_LEN (sizeof(MI_SET)-1)
  249. #define MI_INDEX "index"
  250. #define MI_INDEX_LEN (sizeof(MI_INDEX)-1)
  251. #define MI_DISABLED "disabled"
  252. #define MI_DISABLED_LEN (sizeof(MI_DISABLED)-1)
  253. #define MI_WEIGHT "weight"
  254. #define MI_WEIGHT_LEN (sizeof(MI_WEIGHT)-1)
  255. #define MI_RECHECK_TICKS "recheck_ticks"
  256. #define MI_RECHECK_T_LEN (sizeof(MI_RECHECK_TICKS)-1)
  257. /* Supported version of the RTP proxy command protocol */
  258. #define SUP_CPROTOVER 20040107
  259. /* Required additional version of the RTP proxy command protocol */
  260. #define REQ_CPROTOVER "20050322"
  261. /* Additional version necessary for re-packetization support */
  262. #define REP_CPROTOVER "20071116"
  263. #define PTL_CPROTOVER "20081102"
  264. #define CPORT "22222"
  265. static int extract_mediaip(str *, str *, int *, char *);
  266. static int alter_mediaip(struct sip_msg *, str *, str *, int, str *, int, int);
  267. static int alter_mediaport(struct sip_msg *, str *, str *, str *, int);
  268. static int alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport);
  269. static char *gencookie();
  270. static int rtpp_test(struct rtpp_node*, int, int);
  271. static int unforce_rtp_proxy_f(struct sip_msg *, char *, char *);
  272. static int force_rtp_proxy(struct sip_msg *, char *, char *, int, int);
  273. static int start_recording_f(struct sip_msg *, char *, char *);
  274. static int rtpproxy_answer1_f(struct sip_msg *, char *, char *);
  275. static int rtpproxy_answer2_f(struct sip_msg *, char *, char *);
  276. static int rtpproxy_offer1_f(struct sip_msg *, char *, char *);
  277. static int rtpproxy_offer2_f(struct sip_msg *, char *, char *);
  278. static int add_rtpproxy_socks(struct rtpp_set * rtpp_list, char * rtpproxy);
  279. static int fixup_set_id(void ** param, int param_no);
  280. static int set_rtp_proxy_set_f(struct sip_msg * msg, char * str1, char * str2);
  281. static struct rtpp_set * select_rtpp_set(int id_set);
  282. static int rtpproxy_set_store(modparam_t type, void * val);
  283. static int rtpproxy_add_rtpproxy_set( char * rtp_proxies);
  284. static int mod_init(void);
  285. static int child_init(int);
  286. static void mod_destroy(void);
  287. /* Pseudo-Variables */
  288. static int pv_get_rtpstat_f(struct sip_msg *, pv_param_t *, pv_value_t *);
  289. /*mi commands*/
  290. static struct mi_root* mi_enable_rtp_proxy(struct mi_root* cmd_tree,
  291. void* param );
  292. static struct mi_root* mi_show_rtpproxies(struct mi_root* cmd_tree,
  293. void* param);
  294. static int rtpproxy_disable_tout = 60;
  295. static int rtpproxy_retr = 5;
  296. static int rtpproxy_tout = 1;
  297. static pid_t mypid;
  298. static unsigned int myseqn = 0;
  299. static str nortpproxy_str = str_init("a=nortpproxy:yes");
  300. static char ** rtpp_strings=0;
  301. static int rtpp_sets=0; /*used in rtpproxy_set_store()*/
  302. static int rtpp_set_count = 0;
  303. static unsigned int current_msg_id = (unsigned int)-1;
  304. /* RTP proxy balancing list */
  305. struct rtpp_set_head * rtpp_set_list =0;
  306. struct rtpp_set * selected_rtpp_set =0;
  307. struct rtpp_set * default_rtpp_set=0;
  308. /* array with the sockets used by rtpporxy (per process)*/
  309. static unsigned int rtpp_no = 0;
  310. static int *rtpp_socks = 0;
  311. /*0-> disabled, 1 ->enabled*/
  312. unsigned int *natping_state=0;
  313. static str timeout_socket_str = {0, 0};
  314. static cmd_export_t cmds[] = {
  315. {"set_rtp_proxy_set", (cmd_function)set_rtp_proxy_set_f, 1,
  316. fixup_set_id, 0,
  317. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  318. {"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy_f, 0,
  319. 0, 0,
  320. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  321. {"start_recording", (cmd_function)start_recording_f, 0,
  322. 0, 0,
  323. REQUEST_ROUTE | ONREPLY_ROUTE },
  324. {"rtpproxy_offer", (cmd_function)rtpproxy_offer1_f, 0,
  325. 0, 0,
  326. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  327. {"rtpproxy_offer", (cmd_function)rtpproxy_offer1_f, 1,
  328. 0, 0,
  329. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  330. {"rtpproxy_offer", (cmd_function)rtpproxy_offer2_f, 2,
  331. 0, 0,
  332. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  333. {"rtpproxy_answer", (cmd_function)rtpproxy_answer1_f, 0,
  334. 0, 0,
  335. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  336. {"rtpproxy_answer", (cmd_function)rtpproxy_answer1_f, 1,
  337. 0, 0,
  338. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  339. {"rtpproxy_answer", (cmd_function)rtpproxy_answer2_f, 2,
  340. 0, 0,
  341. REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  342. {"rtpproxy_stream2uac",(cmd_function)rtpproxy_stream2uac2_f, 2,
  343. fixup_var_str_int, 0,
  344. REQUEST_ROUTE | ONREPLY_ROUTE },
  345. {"rtpproxy_stream2uas",(cmd_function)rtpproxy_stream2uas2_f, 2,
  346. fixup_var_str_int, 0,
  347. REQUEST_ROUTE | ONREPLY_ROUTE },
  348. {"rtpproxy_stop_stream2uac",(cmd_function)rtpproxy_stop_stream2uac2_f,0,
  349. NULL, 0,
  350. REQUEST_ROUTE | ONREPLY_ROUTE },
  351. {"rtpproxy_stop_stream2uas",(cmd_function)rtpproxy_stop_stream2uas2_f,0,
  352. NULL, 0,
  353. REQUEST_ROUTE | ONREPLY_ROUTE },
  354. {0, 0, 0, 0, 0, 0}
  355. };
  356. static pv_export_t mod_pvs[] = {
  357. {{"rtpstat", (sizeof("rtpstat")-1)}, /* RTP-Statistics */
  358. PVT_OTHER, pv_get_rtpstat_f, 0, 0, 0, 0, 0},
  359. {{0, 0}, 0, 0, 0, 0, 0, 0, 0}
  360. };
  361. static param_export_t params[] = {
  362. {"nortpproxy_str", STR_PARAM, &nortpproxy_str.s },
  363. {"rtpproxy_sock", STR_PARAM|USE_FUNC_PARAM,
  364. (void*)rtpproxy_set_store },
  365. {"rtpproxy_disable_tout", INT_PARAM, &rtpproxy_disable_tout },
  366. {"rtpproxy_retr", INT_PARAM, &rtpproxy_retr },
  367. {"rtpproxy_tout", INT_PARAM, &rtpproxy_tout },
  368. {"timeout_socket", STR_PARAM, &timeout_socket_str.s },
  369. {0, 0, 0}
  370. };
  371. static mi_export_t mi_cmds[] = {
  372. {MI_ENABLE_RTP_PROXY, mi_enable_rtp_proxy, 0, 0, 0},
  373. {MI_SHOW_RTP_PROXIES, mi_show_rtpproxies, MI_NO_INPUT_FLAG, 0, 0},
  374. { 0, 0, 0, 0, 0}
  375. };
  376. struct module_exports exports = {
  377. "rtpproxy",
  378. DEFAULT_DLFLAGS, /* dlopen flags */
  379. cmds,
  380. params,
  381. 0, /* exported statistics */
  382. mi_cmds, /* exported MI functions */
  383. mod_pvs, /* exported pseudo-variables */
  384. 0, /* extra processes */
  385. mod_init,
  386. 0, /* reply processing */
  387. mod_destroy, /* destroy function */
  388. child_init
  389. };
  390. static int rtpproxy_set_store(modparam_t type, void * val){
  391. char * p;
  392. int len;
  393. p = (char* )val;
  394. if(p==0 || *p=='\0'){
  395. return 0;
  396. }
  397. if(rtpp_sets==0){
  398. rtpp_strings = (char**)pkg_malloc(sizeof(char*));
  399. if(!rtpp_strings){
  400. LM_ERR("no pkg memory left\n");
  401. return -1;
  402. }
  403. } else {/*realloc to make room for the current set*/
  404. rtpp_strings = (char**)pkg_realloc(rtpp_strings,
  405. (rtpp_sets+1)* sizeof(char*));
  406. if(!rtpp_strings){
  407. LM_ERR("no pkg memory left\n");
  408. return -1;
  409. }
  410. }
  411. /*allocate for the current set of urls*/
  412. len = strlen(p);
  413. rtpp_strings[rtpp_sets] = (char*)pkg_malloc((len+1)*sizeof(char));
  414. if(!rtpp_strings[rtpp_sets]){
  415. LM_ERR("no pkg memory left\n");
  416. return -1;
  417. }
  418. memcpy(rtpp_strings[rtpp_sets], p, len);
  419. rtpp_strings[rtpp_sets][len] = '\0';
  420. rtpp_sets++;
  421. return 0;
  422. }
  423. static int add_rtpproxy_socks(struct rtpp_set * rtpp_list,
  424. char * rtpproxy){
  425. /* Make rtp proxies list. */
  426. char *p, *p1, *p2, *plim;
  427. struct rtpp_node *pnode;
  428. int weight;
  429. p = rtpproxy;
  430. plim = p + strlen(p);
  431. for(;;) {
  432. weight = 1;
  433. while (*p && isspace((int)*p))
  434. ++p;
  435. if (p >= plim)
  436. break;
  437. p1 = p;
  438. while (*p && !isspace((int)*p))
  439. ++p;
  440. if (p <= p1)
  441. break; /* may happen??? */
  442. /* Have weight specified? If yes, scan it */
  443. p2 = memchr(p1, '=', p - p1);
  444. if (p2 != NULL) {
  445. weight = strtoul(p2 + 1, NULL, 10);
  446. } else {
  447. p2 = p;
  448. }
  449. pnode = shm_malloc(sizeof(struct rtpp_node));
  450. if (pnode == NULL) {
  451. LM_ERR("no shm memory left\n");
  452. return -1;
  453. }
  454. memset(pnode, 0, sizeof(*pnode));
  455. pnode->idx = rtpp_no++;
  456. pnode->rn_recheck_ticks = 0;
  457. pnode->rn_weight = weight;
  458. pnode->rn_umode = 0;
  459. pnode->rn_disabled = 0;
  460. pnode->rn_url.s = shm_malloc(p2 - p1 + 1);
  461. if (pnode->rn_url.s == NULL) {
  462. shm_free(pnode);
  463. LM_ERR("no shm memory left\n");
  464. return -1;
  465. }
  466. memmove(pnode->rn_url.s, p1, p2 - p1);
  467. pnode->rn_url.s[p2 - p1] = 0;
  468. pnode->rn_url.len = p2-p1;
  469. LM_DBG("url is %s, len is %i\n", pnode->rn_url.s, pnode->rn_url.len);
  470. /* Leave only address in rn_address */
  471. pnode->rn_address = pnode->rn_url.s;
  472. if (strncasecmp(pnode->rn_address, "udp:", 4) == 0) {
  473. pnode->rn_umode = 1;
  474. pnode->rn_address += 4;
  475. } else if (strncasecmp(pnode->rn_address, "udp6:", 5) == 0) {
  476. pnode->rn_umode = 6;
  477. pnode->rn_address += 5;
  478. } else if (strncasecmp(pnode->rn_address, "unix:", 5) == 0) {
  479. pnode->rn_umode = 0;
  480. pnode->rn_address += 5;
  481. }
  482. if (rtpp_list->rn_first == NULL) {
  483. rtpp_list->rn_first = pnode;
  484. } else {
  485. rtpp_list->rn_last->rn_next = pnode;
  486. }
  487. rtpp_list->rn_last = pnode;
  488. rtpp_list->rtpp_node_count++;
  489. }
  490. return 0;
  491. }
  492. /* 0-succes
  493. * -1 - erorr
  494. * */
  495. static int rtpproxy_add_rtpproxy_set( char * rtp_proxies)
  496. {
  497. char *p,*p2;
  498. struct rtpp_set * rtpp_list;
  499. unsigned int my_current_id;
  500. str id_set;
  501. int new_list;
  502. /* empty definition? */
  503. p= rtp_proxies;
  504. if(!p || *p=='\0'){
  505. return 0;
  506. }
  507. for(;*p && isspace(*p);p++);
  508. if(*p=='\0'){
  509. return 0;
  510. }
  511. rtp_proxies = strstr(p, "==");
  512. if(rtp_proxies){
  513. if(*(rtp_proxies +2)=='\0'){
  514. LM_ERR("script error -invalid rtp proxy list!\n");
  515. return -1;
  516. }
  517. *rtp_proxies = '\0';
  518. p2 = rtp_proxies-1;
  519. for(;isspace(*p2); *p2 = '\0',p2--);
  520. id_set.s = p; id_set.len = p2 - p+1;
  521. if(id_set.len <= 0 ||str2int(&id_set, &my_current_id)<0 ){
  522. LM_ERR("script error -invalid set_id value!\n");
  523. return -1;
  524. }
  525. rtp_proxies+=2;
  526. }else{
  527. rtp_proxies = p;
  528. my_current_id = DEFAULT_RTPP_SET_ID;
  529. }
  530. for(;*rtp_proxies && isspace(*rtp_proxies);rtp_proxies++);
  531. if(!(*rtp_proxies)){
  532. LM_ERR("script error -empty rtp_proxy list\n");
  533. return -1;;
  534. }
  535. /*search for the current_id*/
  536. rtpp_list = rtpp_set_list ? rtpp_set_list->rset_first : 0;
  537. while( rtpp_list != 0 && rtpp_list->id_set!=my_current_id)
  538. rtpp_list = rtpp_list->rset_next;
  539. if(rtpp_list==NULL){ /*if a new id_set : add a new set of rtpp*/
  540. rtpp_list = shm_malloc(sizeof(struct rtpp_set));
  541. if(!rtpp_list){
  542. LM_ERR("no shm memory left\n");
  543. return -1;
  544. }
  545. memset(rtpp_list, 0, sizeof(struct rtpp_set));
  546. rtpp_list->id_set = my_current_id;
  547. new_list = 1;
  548. } else {
  549. new_list = 0;
  550. }
  551. if(add_rtpproxy_socks(rtpp_list, rtp_proxies)!= 0){
  552. /*if this list will not be inserted, clean it up*/
  553. goto error;
  554. }
  555. if (new_list) {
  556. if(!rtpp_set_list){/*initialize the list of set*/
  557. rtpp_set_list = shm_malloc(sizeof(struct rtpp_set_head));
  558. if(!rtpp_set_list){
  559. LM_ERR("no shm memory left\n");
  560. return -1;
  561. }
  562. memset(rtpp_set_list, 0, sizeof(struct rtpp_set_head));
  563. }
  564. /*update the list of set info*/
  565. if(!rtpp_set_list->rset_first){
  566. rtpp_set_list->rset_first = rtpp_list;
  567. }else{
  568. rtpp_set_list->rset_last->rset_next = rtpp_list;
  569. }
  570. rtpp_set_list->rset_last = rtpp_list;
  571. rtpp_set_count++;
  572. if(my_current_id == DEFAULT_RTPP_SET_ID){
  573. default_rtpp_set = rtpp_list;
  574. }
  575. }
  576. return 0;
  577. error:
  578. return -1;
  579. }
  580. static int fixup_set_id(void ** param, int param_no)
  581. {
  582. int int_val, err;
  583. struct rtpp_set* rtpp_list;
  584. int_val = str2s(*param, strlen(*param), &err);
  585. if (err == 0) {
  586. pkg_free(*param);
  587. if((rtpp_list = select_rtpp_set(int_val)) ==0){
  588. LM_ERR("rtpp_proxy set %i not configured\n", int_val);
  589. return E_CFG;
  590. }
  591. *param = (void *)rtpp_list;
  592. return 0;
  593. } else {
  594. LM_ERR("bad number <%s>\n", (char *)(*param));
  595. return E_CFG;
  596. }
  597. }
  598. static struct mi_root* mi_enable_rtp_proxy(struct mi_root* cmd_tree,
  599. void* param )
  600. { struct mi_node* node;
  601. str rtpp_url;
  602. unsigned int enable;
  603. struct rtpp_set * rtpp_list;
  604. struct rtpp_node * crt_rtpp;
  605. int found;
  606. found = 0;
  607. if(rtpp_set_list ==NULL)
  608. goto end;
  609. node = cmd_tree->node.kids;
  610. if(node == NULL)
  611. return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
  612. if(node->value.s == NULL || node->value.len ==0)
  613. return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
  614. rtpp_url = node->value;
  615. node = node->next;
  616. if(node == NULL)
  617. return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
  618. enable = 0;
  619. if( strno2int( &node->value, &enable) <0)
  620. goto error;
  621. for(rtpp_list = rtpp_set_list->rset_first; rtpp_list != NULL;
  622. rtpp_list = rtpp_list->rset_next){
  623. for(crt_rtpp = rtpp_list->rn_first; crt_rtpp != NULL;
  624. crt_rtpp = crt_rtpp->rn_next){
  625. /*found a matching rtpp*/
  626. if(crt_rtpp->rn_url.len == rtpp_url.len){
  627. if(strncmp(crt_rtpp->rn_url.s, rtpp_url.s, rtpp_url.len) == 0){
  628. /*set the enabled/disabled status*/
  629. found = 1;
  630. crt_rtpp->rn_recheck_ticks =
  631. enable? MI_MIN_RECHECK_TICKS : MI_MAX_RECHECK_TICKS;
  632. crt_rtpp->rn_disabled = enable?0:1;
  633. }
  634. }
  635. }
  636. }
  637. end:
  638. if(found)
  639. return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
  640. return init_mi_tree(404,MI_RTP_PROXY_NOT_FOUND,MI_RTP_PROXY_NOT_FOUND_LEN);
  641. error:
  642. return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
  643. }
  644. #define add_rtpp_node_int_info(_parent, _name, _name_len, _value, _child,\
  645. _len, _string, _error)\
  646. do {\
  647. (_string) = int2str((_value), &(_len));\
  648. if((_string) == 0){\
  649. LM_ERR("cannot convert int value\n");\
  650. goto _error;\
  651. }\
  652. if(((_child) = add_mi_node_child((_parent), MI_DUP_VALUE, (_name), \
  653. (_name_len), (_string), (_len)) ) == 0)\
  654. goto _error;\
  655. }while(0);
  656. static struct mi_root* mi_show_rtpproxies(struct mi_root* cmd_tree,
  657. void* param)
  658. {
  659. struct mi_node* node, *crt_node, *child;
  660. struct mi_root* root;
  661. struct mi_attr * attr;
  662. struct rtpp_set * rtpp_list;
  663. struct rtpp_node * crt_rtpp;
  664. char * string, *id;
  665. int id_len, len;
  666. string = id = 0;
  667. root = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
  668. if (!root) {
  669. LM_ERR("the MI tree cannot be initialized!\n");
  670. return 0;
  671. }
  672. if(rtpp_set_list ==NULL)
  673. return root;
  674. node = &root->node;
  675. for(rtpp_list = rtpp_set_list->rset_first; rtpp_list != NULL;
  676. rtpp_list = rtpp_list->rset_next){
  677. for(crt_rtpp = rtpp_list->rn_first; crt_rtpp != NULL;
  678. crt_rtpp = crt_rtpp->rn_next){
  679. id = int2str(rtpp_list->id_set, &id_len);
  680. if(!id){
  681. LM_ERR("cannot convert set id\n");
  682. goto error;
  683. }
  684. if(!(crt_node = add_mi_node_child(node, 0, crt_rtpp->rn_url.s,
  685. crt_rtpp->rn_url.len, 0,0)) ) {
  686. LM_ERR("cannot add the child node to the tree\n");
  687. goto error;
  688. }
  689. LM_DBG("adding node name %s \n",crt_rtpp->rn_url.s );
  690. if((attr = add_mi_attr(crt_node, MI_DUP_VALUE, MI_SET, MI_SET_LEN,
  691. id, id_len))== 0){
  692. LM_ERR("cannot add attributes to the node\n");
  693. goto error;
  694. }
  695. add_rtpp_node_int_info(crt_node, MI_INDEX, MI_INDEX_LEN,
  696. crt_rtpp->idx, child, len,string,error);
  697. add_rtpp_node_int_info(crt_node, MI_DISABLED, MI_DISABLED_LEN,
  698. crt_rtpp->rn_disabled, child, len,string,error);
  699. add_rtpp_node_int_info(crt_node, MI_WEIGHT, MI_WEIGHT_LEN,
  700. crt_rtpp->rn_weight, child, len, string,error);
  701. add_rtpp_node_int_info(crt_node, MI_RECHECK_TICKS,MI_RECHECK_T_LEN,
  702. crt_rtpp->rn_recheck_ticks, child, len, string, error);
  703. }
  704. }
  705. return root;
  706. error:
  707. if (root)
  708. free_mi_tree(root);
  709. return 0;
  710. }
  711. static int
  712. mod_init(void)
  713. {
  714. int i;
  715. if(register_mi_mod(exports.name, mi_cmds)!=0)
  716. {
  717. LM_ERR("failed to register MI commands\n");
  718. return -1;
  719. }
  720. /* any rtpproxy configured? */
  721. if(rtpp_set_list)
  722. default_rtpp_set = select_rtpp_set(DEFAULT_RTPP_SET_ID);
  723. if (nortpproxy_str.s==NULL || nortpproxy_str.s[0]==0) {
  724. nortpproxy_str.len = 0;
  725. nortpproxy_str.s = NULL;
  726. } else {
  727. nortpproxy_str.len = strlen(nortpproxy_str.s);
  728. while (nortpproxy_str.len > 0 && (nortpproxy_str.s[nortpproxy_str.len - 1] == '\r' ||
  729. nortpproxy_str.s[nortpproxy_str.len - 1] == '\n'))
  730. nortpproxy_str.len--;
  731. if (nortpproxy_str.len == 0)
  732. nortpproxy_str.s = NULL;
  733. }
  734. /* storing the list of rtp proxy sets in shared memory*/
  735. for(i=0;i<rtpp_sets;i++){
  736. if(rtpproxy_add_rtpproxy_set(rtpp_strings[i]) !=0){
  737. for(;i<rtpp_sets;i++)
  738. if(rtpp_strings[i])
  739. pkg_free(rtpp_strings[i]);
  740. pkg_free(rtpp_strings);
  741. return -1;
  742. }
  743. if(rtpp_strings[i])
  744. pkg_free(rtpp_strings[i]);
  745. }
  746. if (timeout_socket_str.s==NULL || timeout_socket_str.s[0]==0) {
  747. timeout_socket_str.len = 0;
  748. timeout_socket_str.s = NULL;
  749. } else {
  750. timeout_socket_str.len = strlen(timeout_socket_str.s);
  751. }
  752. if (rtpp_strings)
  753. pkg_free(rtpp_strings);
  754. return 0;
  755. }
  756. static int
  757. child_init(int rank)
  758. {
  759. int n;
  760. char *cp;
  761. struct addrinfo hints, *res;
  762. struct rtpp_set *rtpp_list;
  763. struct rtpp_node *pnode;
  764. if(rtpp_set_list==NULL )
  765. return 0;
  766. /* Iterate known RTP proxies - create sockets */
  767. mypid = getpid();
  768. rtpp_socks = (int*)pkg_malloc( sizeof(int)*rtpp_no );
  769. if (rtpp_socks==NULL) {
  770. LM_ERR("no more pkg memory\n");
  771. return -1;
  772. }
  773. for(rtpp_list = rtpp_set_list->rset_first; rtpp_list != 0;
  774. rtpp_list = rtpp_list->rset_next){
  775. for (pnode=rtpp_list->rn_first; pnode!=0; pnode = pnode->rn_next){
  776. char *hostname;
  777. if (pnode->rn_umode == 0) {
  778. rtpp_socks[pnode->idx] = -1;
  779. goto rptest;
  780. }
  781. /*
  782. * This is UDP or UDP6. Detect host and port; lookup host;
  783. * do connect() in order to specify peer address
  784. */
  785. hostname = (char*)pkg_malloc(sizeof(char) * (strlen(pnode->rn_address) + 1));
  786. if (hostname==NULL) {
  787. LM_ERR("no more pkg memory\n");
  788. return -1;
  789. }
  790. strcpy(hostname, pnode->rn_address);
  791. cp = strrchr(hostname, ':');
  792. if (cp != NULL) {
  793. *cp = '\0';
  794. cp++;
  795. }
  796. if (cp == NULL || *cp == '\0')
  797. cp = CPORT;
  798. memset(&hints, 0, sizeof(hints));
  799. hints.ai_flags = 0;
  800. hints.ai_family = (pnode->rn_umode == 6) ? AF_INET6 : AF_INET;
  801. hints.ai_socktype = SOCK_DGRAM;
  802. if ((n = getaddrinfo(hostname, cp, &hints, &res)) != 0) {
  803. LM_ERR("%s\n", gai_strerror(n));
  804. pkg_free(hostname);
  805. return -1;
  806. }
  807. pkg_free(hostname);
  808. rtpp_socks[pnode->idx] = socket((pnode->rn_umode == 6)
  809. ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
  810. if ( rtpp_socks[pnode->idx] == -1) {
  811. LM_ERR("can't create socket\n");
  812. freeaddrinfo(res);
  813. return -1;
  814. }
  815. if (connect( rtpp_socks[pnode->idx], res->ai_addr, res->ai_addrlen) == -1) {
  816. LM_ERR("can't connect to a RTP proxy\n");
  817. close( rtpp_socks[pnode->idx] );
  818. rtpp_socks[pnode->idx] = -1;
  819. freeaddrinfo(res);
  820. return -1;
  821. }
  822. freeaddrinfo(res);
  823. rptest:
  824. pnode->rn_disabled = rtpp_test(pnode, 0, 1);
  825. }
  826. }
  827. return 0;
  828. }
  829. static void mod_destroy(void)
  830. {
  831. struct rtpp_set * crt_list, * last_list;
  832. struct rtpp_node * crt_rtpp, *last_rtpp;
  833. /*free the shared memory*/
  834. if (natping_state)
  835. shm_free(natping_state);
  836. if(rtpp_set_list == NULL)
  837. return;
  838. for(crt_list = rtpp_set_list->rset_first; crt_list != NULL; ){
  839. for(crt_rtpp = crt_list->rn_first; crt_rtpp != NULL; ){
  840. if(crt_rtpp->rn_url.s)
  841. shm_free(crt_rtpp->rn_url.s);
  842. last_rtpp = crt_rtpp;
  843. crt_rtpp = last_rtpp->rn_next;
  844. shm_free(last_rtpp);
  845. }
  846. last_list = crt_list;
  847. crt_list = last_list->rset_next;
  848. shm_free(last_list);
  849. }
  850. shm_free(rtpp_set_list);
  851. }
  852. static int
  853. isnulladdr(str *sx, int pf)
  854. {
  855. char *cp;
  856. if (pf == AF_INET6) {
  857. for(cp = sx->s; cp < sx->s + sx->len; cp++)
  858. if (*cp != '0' && *cp != ':')
  859. return 0;
  860. return 1;
  861. }
  862. return (sx->len == 7 && memcmp("0.0.0.0", sx->s, 7) == 0);
  863. }
  864. #define ADD_ADIRECTION 0x01
  865. #define FIX_MEDIP 0x02
  866. #define ADD_ANORTPPROXY 0x04
  867. #define FIX_ORGIP 0x08
  868. #define ADIRECTION "a=direction:active"
  869. #define ADIRECTION_LEN (sizeof(ADIRECTION) - 1)
  870. #define AOLDMEDIP "a=oldmediaip:"
  871. #define AOLDMEDIP_LEN (sizeof(AOLDMEDIP) - 1)
  872. #define AOLDMEDIP6 "a=oldmediaip6:"
  873. #define AOLDMEDIP6_LEN (sizeof(AOLDMEDIP6) - 1)
  874. #define AOLDMEDPRT "a=oldmediaport:"
  875. #define AOLDMEDPRT_LEN (sizeof(AOLDMEDPRT) - 1)
  876. static inline int
  877. replace_sdp_ip(struct sip_msg* msg, str *org_body, char *line, str *ip)
  878. {
  879. str body1, oldip, newip;
  880. str body = *org_body;
  881. unsigned hasreplaced = 0;
  882. int pf, pf1 = 0;
  883. str body2;
  884. char *bodylimit = body.s + body.len;
  885. /* Iterate all lines and replace ips in them. */
  886. if (!ip) {
  887. newip.s = ip_addr2a(&msg->rcv.src_ip);
  888. newip.len = strlen(newip.s);
  889. } else {
  890. newip = *ip;
  891. }
  892. body1 = body;
  893. for(;;) {
  894. if (extract_mediaip(&body1, &oldip, &pf,line) == -1)
  895. break;
  896. if (pf != AF_INET) {
  897. LM_ERR("not an IPv4 address in '%s' SDP\n",line);
  898. return -1;
  899. }
  900. if (!pf1)
  901. pf1 = pf;
  902. else if (pf != pf1) {
  903. LM_ERR("mismatching address families in '%s' SDP\n",line);
  904. return -1;
  905. }
  906. body2.s = oldip.s + oldip.len;
  907. body2.len = bodylimit - body2.s;
  908. if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf,1) == -1) {
  909. LM_ERR("can't alter '%s' IP\n",line);
  910. return -1;
  911. }
  912. hasreplaced = 1;
  913. body1 = body2;
  914. }
  915. if (!hasreplaced) {
  916. LM_ERR("can't extract '%s' IP from the SDP\n",line);
  917. return -1;
  918. }
  919. return 0;
  920. }
  921. static int
  922. extract_mediaip(str *body, str *mediaip, int *pf, char *line)
  923. {
  924. char *cp, *cp1;
  925. int len, nextisip;
  926. cp1 = NULL;
  927. for (cp = body->s; (len = body->s + body->len - cp) > 0;) {
  928. cp1 = ser_memmem(cp, line, len, 2);
  929. if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
  930. break;
  931. cp = cp1 + 2;
  932. }
  933. if (cp1 == NULL)
  934. return -1;
  935. mediaip->s = cp1 + 2;
  936. mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s;
  937. trim_len(mediaip->len, mediaip->s, *mediaip);
  938. nextisip = 0;
  939. for (cp = mediaip->s; cp < mediaip->s + mediaip->len;) {
  940. len = eat_token_end(cp, mediaip->s + mediaip->len) - cp;
  941. if (nextisip == 1) {
  942. mediaip->s = cp;
  943. mediaip->len = len;
  944. nextisip++;
  945. break;
  946. }
  947. if (len == 3 && memcmp(cp, "IP", 2) == 0) {
  948. switch (cp[2]) {
  949. case '4':
  950. nextisip = 1;
  951. *pf = AF_INET;
  952. break;
  953. case '6':
  954. nextisip = 1;
  955. *pf = AF_INET6;
  956. break;
  957. default:
  958. break;
  959. }
  960. }
  961. cp = eat_space_end(cp + len, mediaip->s + mediaip->len);
  962. }
  963. if (nextisip != 2 || mediaip->len == 0) {
  964. LM_ERR("no `IP[4|6]' in `%s' field\n",line);
  965. return -1;
  966. }
  967. return 1;
  968. }
  969. static int
  970. alter_mediaip(struct sip_msg *msg, str *body, str *oldip, int oldpf,
  971. str *newip, int newpf, int preserve)
  972. {
  973. char *buf;
  974. int offset;
  975. struct lump* anchor;
  976. str omip, nip, oip;
  977. /* check that updating mediaip is really necessary */
  978. if (oldpf == newpf && isnulladdr(oldip, oldpf))
  979. return 0;
  980. if (newip->len == oldip->len &&
  981. memcmp(newip->s, oldip->s, newip->len) == 0)
  982. return 0;
  983. if (preserve != 0) {
  984. anchor = anchor_lump(msg, body->s + body->len - msg->buf, 0, 0);
  985. if (anchor == NULL) {
  986. LM_ERR("anchor_lump failed\n");
  987. return -1;
  988. }
  989. if (oldpf == AF_INET6) {
  990. omip.s = AOLDMEDIP6;
  991. omip.len = AOLDMEDIP6_LEN;
  992. } else {
  993. omip.s = AOLDMEDIP;
  994. omip.len = AOLDMEDIP_LEN;
  995. }
  996. buf = pkg_malloc(omip.len + oldip->len + CRLF_LEN);
  997. if (buf == NULL) {
  998. LM_ERR("out of pkg memory\n");
  999. return -1;
  1000. }
  1001. memcpy(buf, CRLF, CRLF_LEN);
  1002. memcpy(buf + CRLF_LEN, omip.s, omip.len);
  1003. memcpy(buf + CRLF_LEN + omip.len, oldip->s, oldip->len);
  1004. if (insert_new_lump_after(anchor, buf,
  1005. omip.len + oldip->len + CRLF_LEN, 0) == NULL) {
  1006. LM_ERR("insert_new_lump_after failed\n");
  1007. pkg_free(buf);
  1008. return -1;
  1009. }
  1010. }
  1011. if (oldpf == newpf) {
  1012. nip.len = newip->len;
  1013. nip.s = pkg_malloc(nip.len);
  1014. if (nip.s == NULL) {
  1015. LM_ERR("out of pkg memory\n");
  1016. return -1;
  1017. }
  1018. memcpy(nip.s, newip->s, newip->len);
  1019. } else {
  1020. nip.len = newip->len + 2;
  1021. nip.s = pkg_malloc(nip.len);
  1022. if (nip.s == NULL) {
  1023. LM_ERR("out of pkg memory\n");
  1024. return -1;
  1025. }
  1026. memcpy(nip.s + 2, newip->s, newip->len);
  1027. nip.s[0] = (newpf == AF_INET6) ? '6' : '4';
  1028. nip.s[1] = ' ';
  1029. }
  1030. oip = *oldip;
  1031. if (oldpf != newpf) {
  1032. do {
  1033. oip.s--;
  1034. oip.len++;
  1035. } while (*oip.s != '6' && *oip.s != '4');
  1036. }
  1037. offset = oip.s - msg->buf;
  1038. anchor = del_lump(msg, offset, oip.len, 0);
  1039. if (anchor == NULL) {
  1040. LM_ERR("del_lump failed\n");
  1041. pkg_free(nip.s);
  1042. return -1;
  1043. }
  1044. if (insert_new_lump_after(anchor, nip.s, nip.len, 0) == 0) {
  1045. LM_ERR("insert_new_lump_after failed\n");
  1046. pkg_free(nip.s);
  1047. return -1;
  1048. }
  1049. return 0;
  1050. }
  1051. static int
  1052. alter_mediaport(struct sip_msg *msg, str *body, str *oldport, str *newport,
  1053. int preserve)
  1054. {
  1055. char *buf;
  1056. int offset;
  1057. struct lump* anchor;
  1058. /* check that updating mediaport is really necessary */
  1059. if (newport->len == oldport->len &&
  1060. memcmp(newport->s, oldport->s, newport->len) == 0)
  1061. return 0;
  1062. /*
  1063. * Since rewriting the same info twice will mess SDP up,
  1064. * apply simple anti foot shooting measure - put flag on
  1065. * messages that have been altered and check it when
  1066. * another request comes.
  1067. */
  1068. #if 0
  1069. /* disabled: - it propagates to the reply and we don't want this
  1070. * -- andrei */
  1071. if (msg->msg_flags & FL_SDP_PORT_AFS) {
  1072. LM_ERR("you can't rewrite the same SDP twice, check your config!\n");
  1073. return -1;
  1074. }
  1075. #endif
  1076. if (preserve != 0) {
  1077. anchor = anchor_lump(msg, body->s + body->len - msg->buf, 0, 0);
  1078. if (anchor == NULL) {
  1079. LM_ERR("anchor_lump failed\n");
  1080. return -1;
  1081. }
  1082. buf = pkg_malloc(AOLDMEDPRT_LEN + oldport->len + CRLF_LEN);
  1083. if (buf == NULL) {
  1084. LM_ERR("out of pkg memory\n");
  1085. return -1;
  1086. }
  1087. memcpy(buf, CRLF, CRLF_LEN);
  1088. memcpy(buf + CRLF_LEN, AOLDMEDPRT, AOLDMEDPRT_LEN);
  1089. memcpy(buf + CRLF_LEN + AOLDMEDPRT_LEN, oldport->s, oldport->len);
  1090. if (insert_new_lump_after(anchor, buf,
  1091. AOLDMEDPRT_LEN + oldport->len + CRLF_LEN, 0) == NULL) {
  1092. LM_ERR("insert_new_lump_after failed\n");
  1093. pkg_free(buf);
  1094. return -1;
  1095. }
  1096. }
  1097. buf = pkg_malloc(newport->len);
  1098. if (buf == NULL) {
  1099. LM_ERR("out of pkg memory\n");
  1100. return -1;
  1101. }
  1102. offset = oldport->s - msg->buf;
  1103. anchor = del_lump(msg, offset, oldport->len, 0);
  1104. if (anchor == NULL) {
  1105. LM_ERR("del_lump failed\n");
  1106. pkg_free(buf);
  1107. return -1;
  1108. }
  1109. memcpy(buf, newport->s, newport->len);
  1110. if (insert_new_lump_after(anchor, buf, newport->len, 0) == 0) {
  1111. LM_ERR("insert_new_lump_after failed\n");
  1112. pkg_free(buf);
  1113. return -1;
  1114. }
  1115. #if 0
  1116. msg->msg_flags |= FL_SDP_PORT_AFS;
  1117. #endif
  1118. return 0;
  1119. }
  1120. /*
  1121. * this function is ported from SER
  1122. */
  1123. static int
  1124. alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport)
  1125. {
  1126. char *buf;
  1127. int offset;
  1128. struct lump* anchor;
  1129. /* check that updating rtcpport is really necessary */
  1130. if (newport->len == oldport->len &&
  1131. memcmp(newport->s, oldport->s, newport->len) == 0)
  1132. return 0;
  1133. buf = pkg_malloc(newport->len);
  1134. if (buf == NULL) {
  1135. LM_ERR("alter_rtcp: out of memory\n");
  1136. return -1;
  1137. }
  1138. offset = oldport->s - msg->buf;
  1139. anchor = del_lump(msg, offset, oldport->len, 0);
  1140. if (anchor == NULL) {
  1141. LM_ERR("alter_rtcp: del_lump failed\n");
  1142. pkg_free(buf);
  1143. return -1;
  1144. }
  1145. memcpy(buf, newport->s, newport->len);
  1146. if (insert_new_lump_after(anchor, buf, newport->len, 0) == 0) {
  1147. LM_ERR("alter_rtcp: insert_new_lump_after failed\n");
  1148. pkg_free(buf);
  1149. return -1;
  1150. }
  1151. return 0;
  1152. }
  1153. static char * gencookie(void)
  1154. {
  1155. static char cook[34];
  1156. sprintf(cook, "%d_%u ", (int)mypid, myseqn);
  1157. myseqn++;
  1158. return cook;
  1159. }
  1160. static int
  1161. rtpp_checkcap(struct rtpp_node *node, char *cap, int caplen)
  1162. {
  1163. char *cp;
  1164. struct iovec vf[4] = {{NULL, 0}, {"VF", 2}, {" ", 1}, {NULL, 0}};
  1165. vf[3].iov_base = cap;
  1166. vf[3].iov_len = caplen;
  1167. cp = send_rtpp_command(node, vf, 4);
  1168. if (cp == NULL)
  1169. return -1;
  1170. if (cp[0] == 'E' || atoi(cp) != 1)
  1171. return 0;
  1172. return 1;
  1173. }
  1174. static int
  1175. rtpp_test(struct rtpp_node *node, int isdisabled, int force)
  1176. {
  1177. int rtpp_ver, rval;
  1178. char *cp;
  1179. struct iovec v[2] = {{NULL, 0}, {"V", 1}};
  1180. if(node->rn_recheck_ticks == MI_MAX_RECHECK_TICKS){
  1181. LM_DBG("rtpp %s disabled for ever\n", node->rn_url.s);
  1182. return 1;
  1183. }
  1184. if (force == 0) {
  1185. if (isdisabled == 0)
  1186. return 0;
  1187. if (node->rn_recheck_ticks > get_ticks())
  1188. return 1;
  1189. }
  1190. cp = send_rtpp_command(node, v, 2);
  1191. if (cp == NULL) {
  1192. LM_WARN("can't get version of the RTP proxy\n");
  1193. goto error;
  1194. }
  1195. rtpp_ver = atoi(cp);
  1196. if (rtpp_ver != SUP_CPROTOVER) {
  1197. LM_WARN("unsupported version of RTP proxy <%s> found: %d supported,"
  1198. "%d present\n", node->rn_url.s, SUP_CPROTOVER, rtpp_ver);
  1199. goto error;
  1200. }
  1201. rval = rtpp_checkcap(node, REQ_CPROTOVER, sizeof(REQ_CPROTOVER) - 1);
  1202. if (rval == -1) {
  1203. LM_WARN("RTP proxy went down during version query\n");
  1204. goto error;
  1205. }
  1206. if (rval == 0) {
  1207. LM_WARN("of RTP proxy <%s> doesn't support required protocol version"
  1208. "%s\n", node->rn_url.s, REQ_CPROTOVER);
  1209. goto error;
  1210. }
  1211. LM_INFO("rtp proxy <%s> found, support for it %senabled\n",
  1212. node->rn_url.s, force == 0 ? "re-" : "");
  1213. /* Check for optional capabilities */
  1214. rval = rtpp_checkcap(node, REP_CPROTOVER, sizeof(REP_CPROTOVER) - 1);
  1215. if (rval != -1) {
  1216. node->rn_rep_supported = rval;
  1217. } else {
  1218. node->rn_rep_supported = 0;
  1219. }
  1220. rval = rtpp_checkcap(node, PTL_CPROTOVER, sizeof(PTL_CPROTOVER) - 1);
  1221. if (rval != -1) {
  1222. node->rn_ptl_supported = rval;
  1223. } else {
  1224. node->rn_ptl_supported = 0;
  1225. }
  1226. return 0;
  1227. error:
  1228. LM_WARN("support for RTP proxy <%s> has been disabled%s\n", node->rn_url.s,
  1229. rtpproxy_disable_tout < 0 ? "" : " temporarily");
  1230. if (rtpproxy_disable_tout >= 0)
  1231. node->rn_recheck_ticks = get_ticks() + rtpproxy_disable_tout;
  1232. return 1;
  1233. }
  1234. char *
  1235. send_rtpp_command(struct rtpp_node *node, struct iovec *v, int vcnt)
  1236. {
  1237. struct sockaddr_un addr;
  1238. int fd, len, i;
  1239. char *cp;
  1240. static char buf[256];
  1241. struct pollfd fds[1];
  1242. len = 0;
  1243. cp = buf;
  1244. if (node->rn_umode == 0) {
  1245. memset(&addr, 0, sizeof(addr));
  1246. addr.sun_family = AF_LOCAL;
  1247. strncpy(addr.sun_path, node->rn_address,
  1248. sizeof(addr.sun_path) - 1);
  1249. #ifdef HAVE_SOCKADDR_SA_LEN
  1250. addr.sun_len = strlen(addr.sun_path);
  1251. #endif
  1252. fd = socket(AF_LOCAL, SOCK_STREAM, 0);
  1253. if (fd < 0) {
  1254. LM_ERR("can't create socket\n");
  1255. goto badproxy;
  1256. }
  1257. if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  1258. close(fd);
  1259. LM_ERR("can't connect to RTP proxy\n");
  1260. goto badproxy;
  1261. }
  1262. do {
  1263. len = writev(fd, v + 1, vcnt - 1);
  1264. } while (len == -1 && errno == EINTR);
  1265. if (len <= 0) {
  1266. close(fd);
  1267. LM_ERR("can't send command to a RTP proxy\n");
  1268. goto badproxy;
  1269. }
  1270. do {
  1271. len = read(fd, buf, sizeof(buf) - 1);
  1272. } while (len == -1 && errno == EINTR);
  1273. close(fd);
  1274. if (len <= 0) {
  1275. LM_ERR("can't read reply from a RTP proxy\n");
  1276. goto badproxy;
  1277. }
  1278. } else {
  1279. fds[0].fd = rtpp_socks[node->idx];
  1280. fds[0].events = POLLIN;
  1281. fds[0].revents = 0;
  1282. /* Drain input buffer */
  1283. while ((poll(fds, 1, 0) == 1) &&
  1284. ((fds[0].revents & POLLIN) != 0)) {
  1285. recv(rtpp_socks[node->idx], buf, sizeof(buf) - 1, 0);
  1286. fds[0].revents = 0;
  1287. }
  1288. v[0].iov_base = gencookie();
  1289. v[0].iov_len = strlen(v[0].iov_base);
  1290. for (i = 0; i < rtpproxy_retr; i++) {
  1291. do {
  1292. len = writev(rtpp_socks[node->idx], v, vcnt);
  1293. } while (len == -1 && (errno == EINTR || errno == ENOBUFS));
  1294. if (len <= 0) {
  1295. LM_ERR("can't send command to a RTP proxy\n");
  1296. goto badproxy;
  1297. }
  1298. while ((poll(fds, 1, rtpproxy_tout * 1000) == 1) &&
  1299. (fds[0].revents & POLLIN) != 0) {
  1300. do {
  1301. len = recv(rtpp_socks[node->idx], buf, sizeof(buf)-1, 0);
  1302. } while (len == -1 && errno == EINTR);
  1303. if (len <= 0) {
  1304. LM_ERR("can't read reply from a RTP proxy\n");
  1305. goto badproxy;
  1306. }
  1307. if (len >= (v[0].iov_len - 1) &&
  1308. memcmp(buf, v[0].iov_base, (v[0].iov_len - 1)) == 0) {
  1309. len -= (v[0].iov_len - 1);
  1310. cp += (v[0].iov_len - 1);
  1311. if (len != 0) {
  1312. len--;
  1313. cp++;
  1314. }
  1315. goto out;
  1316. }
  1317. fds[0].revents = 0;
  1318. }
  1319. }
  1320. if (i == rtpproxy_retr) {
  1321. LM_ERR("timeout waiting reply from a RTP proxy\n");
  1322. goto badproxy;
  1323. }
  1324. }
  1325. out:
  1326. cp[len] = '\0';
  1327. return cp;
  1328. badproxy:
  1329. LM_ERR("proxy <%s> does not respond, disable it\n", node->rn_url.s);
  1330. node->rn_disabled = 1;
  1331. node->rn_recheck_ticks = get_ticks() + rtpproxy_disable_tout;
  1332. return NULL;
  1333. }
  1334. /*
  1335. * select the set with the id_set id
  1336. */
  1337. static struct rtpp_set * select_rtpp_set(int id_set ){
  1338. struct rtpp_set * rtpp_list;
  1339. /*is it a valid set_id?*/
  1340. if(!rtpp_set_list || !rtpp_set_list->rset_first){
  1341. LM_ERR("no rtp_proxy configured\n");
  1342. return 0;
  1343. }
  1344. for(rtpp_list=rtpp_set_list->rset_first; rtpp_list!=0 &&
  1345. rtpp_list->id_set!=id_set; rtpp_list=rtpp_list->rset_next);
  1346. if(!rtpp_list){
  1347. LM_ERR(" script error-invalid id_set to be selected\n");
  1348. }
  1349. return rtpp_list;
  1350. }
  1351. /*
  1352. * Main balancing routine. This does not try to keep the same proxy for
  1353. * the call if some proxies were disabled or enabled; proxy death considered
  1354. * too rare. Otherwise we should implement "mature" HA clustering, which is
  1355. * too expensive here.
  1356. */
  1357. struct rtpp_node *
  1358. select_rtpp_node(str callid, int do_test)
  1359. {
  1360. unsigned sum, sumcut, weight_sum;
  1361. struct rtpp_node* node;
  1362. int was_forced;
  1363. if(!selected_rtpp_set){
  1364. LM_ERR("script error -no valid set selected\n");
  1365. return NULL;
  1366. }
  1367. /* Most popular case: 1 proxy, nothing to calculate */
  1368. if (selected_rtpp_set->rtpp_node_count == 1) {
  1369. node = selected_rtpp_set->rn_first;
  1370. if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks())
  1371. node->rn_disabled = rtpp_test(node, 1, 0);
  1372. return node->rn_disabled ? NULL : node;
  1373. }
  1374. /* XXX Use quick-and-dirty hashing algo */
  1375. for(sum = 0; callid.len > 0; callid.len--)
  1376. sum += callid.s[callid.len - 1];
  1377. sum &= 0xff;
  1378. was_forced = 0;
  1379. retry:
  1380. weight_sum = 0;
  1381. for (node=selected_rtpp_set->rn_first; node!=NULL; node=node->rn_next) {
  1382. if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks()){
  1383. /* Try to enable if it's time to try. */
  1384. node->rn_disabled = rtpp_test(node, 1, 0);
  1385. }
  1386. if (!node->rn_disabled)
  1387. weight_sum += node->rn_weight;
  1388. }
  1389. if (weight_sum == 0) {
  1390. /* No proxies? Force all to be redetected, if not yet */
  1391. if (was_forced)
  1392. return NULL;
  1393. was_forced = 1;
  1394. for(node=selected_rtpp_set->rn_first; node!=NULL; node=node->rn_next) {
  1395. node->rn_disabled = rtpp_test(node, 1, 1);
  1396. }
  1397. goto retry;
  1398. }
  1399. sumcut = sum % weight_sum;
  1400. /*
  1401. * sumcut here lays from 0 to weight_sum-1.
  1402. * Scan proxy list and decrease until appropriate proxy is found.
  1403. */
  1404. for (node=selected_rtpp_set->rn_first; node!=NULL; node=node->rn_next) {
  1405. if (node->rn_disabled)
  1406. continue;
  1407. if (sumcut < node->rn_weight)
  1408. goto found;
  1409. sumcut -= node->rn_weight;
  1410. }
  1411. /* No node list */
  1412. return NULL;
  1413. found:
  1414. if (do_test) {
  1415. node->rn_disabled = rtpp_test(node, node->rn_disabled, 0);
  1416. if (node->rn_disabled)
  1417. goto retry;
  1418. }
  1419. return node;
  1420. }
  1421. static int
  1422. unforce_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)
  1423. {
  1424. str callid, from_tag, to_tag;
  1425. struct rtpp_node *node;
  1426. struct iovec v[1 + 4 + 3] = {{NULL, 0}, {"D", 1}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}};
  1427. /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 1 */
  1428. if (get_callid(msg, &callid) == -1 || callid.len == 0) {
  1429. LM_ERR("can't get Call-Id field\n");
  1430. return -1;
  1431. }
  1432. to_tag.s = 0;
  1433. if (get_to_tag(msg, &to_tag) == -1) {
  1434. LM_ERR("can't get To tag\n");
  1435. return -1;
  1436. }
  1437. if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
  1438. LM_ERR("can't get From tag\n");
  1439. return -1;
  1440. }
  1441. STR2IOVEC(callid, v[3]);
  1442. STR2IOVEC(from_tag, v[5]);
  1443. STR2IOVEC(to_tag, v[7]);
  1444. if(msg->id != current_msg_id){
  1445. selected_rtpp_set = default_rtpp_set;
  1446. }
  1447. node = select_rtpp_node(callid, 1);
  1448. if (!node) {
  1449. LM_ERR("no available proxies\n");
  1450. return -1;
  1451. }
  1452. send_rtpp_command(node, v, (to_tag.len > 0) ? 8 : 6);
  1453. return 1;
  1454. }
  1455. /* This function assumes p points to a line of requested type. */
  1456. static int
  1457. set_rtp_proxy_set_f(struct sip_msg * msg, char * str1, char * str2)
  1458. {
  1459. current_msg_id = msg->id;
  1460. selected_rtpp_set = (struct rtpp_set *)str1;
  1461. return 1;
  1462. }
  1463. static int
  1464. rtpproxy_offer1_f(struct sip_msg *msg, char *str1, char *str2)
  1465. {
  1466. char *cp;
  1467. char newip[IP_ADDR_MAX_STR_SIZE];
  1468. cp = ip_addr2a(&msg->rcv.dst_ip);
  1469. strcpy(newip, cp);
  1470. return force_rtp_proxy(msg, str1, newip, 1, 0);
  1471. }
  1472. static int
  1473. rtpproxy_offer2_f(struct sip_msg *msg, char *param1, char *param2)
  1474. {
  1475. return force_rtp_proxy(msg, param1, param2, 1, 1);
  1476. }
  1477. static int
  1478. rtpproxy_answer1_f(struct sip_msg *msg, char *str1, char *str2)
  1479. {
  1480. char *cp;
  1481. char newip[IP_ADDR_MAX_STR_SIZE];
  1482. if (msg->first_line.type == SIP_REQUEST)
  1483. if (msg->first_line.u.request.method_value != METHOD_ACK)
  1484. return -1;
  1485. cp = ip_addr2a(&msg->rcv.dst_ip);
  1486. strcpy(newip, cp);
  1487. return force_rtp_proxy(msg, str1, newip, 0, 0);
  1488. }
  1489. static int
  1490. rtpproxy_answer2_f(struct sip_msg *msg, char *param1, char *param2)
  1491. {
  1492. if (msg->first_line.type == SIP_REQUEST)
  1493. if (msg->first_line.u.request.method_value != METHOD_ACK)
  1494. return -1;
  1495. return force_rtp_proxy(msg, param1, param2, 0, 1);
  1496. }
  1497. struct options {
  1498. str s;
  1499. int oidx;
  1500. };
  1501. static int
  1502. append_opts(struct options *op, char ch)
  1503. {
  1504. void *p;
  1505. if (op->s.len <= op->oidx) {
  1506. p = pkg_realloc(op->s.s, op->oidx + 32);
  1507. if (p == NULL) {
  1508. return (-1);
  1509. }
  1510. op->s.s = p;
  1511. op->s.len = op->oidx + 32;
  1512. }
  1513. op->s.s[op->oidx++] = ch;
  1514. return (0);
  1515. }
  1516. static void
  1517. free_opts(struct options *op1, struct options *op2, struct options *op3)
  1518. {
  1519. if (op1->s.len > 0 && op1->s.s != NULL) {
  1520. pkg_free(op1->s.s);
  1521. op1->s.len = 0;
  1522. }
  1523. if (op2->s.len > 0 && op2->s.s != NULL) {
  1524. pkg_free(op2->s.s);
  1525. op2->s.len = 0;
  1526. }
  1527. if (op3->s.len > 0 && op3->s.s != NULL) {
  1528. pkg_free(op3->s.s);
  1529. op3->s.len = 0;
  1530. }
  1531. }
  1532. #define FORCE_RTP_PROXY_RET(e) \
  1533. do { \
  1534. free_opts(&opts, &rep_opts, &pt_opts); \
  1535. return (e); \
  1536. } while (0);
  1537. static int
  1538. force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forcedIP)
  1539. {
  1540. str body, body1, oldport, oldip, newport, newip;
  1541. str callid, from_tag, to_tag, tmp, payload_types;
  1542. str newrtcp;
  1543. int create, port, len, flookup, argc, proxied, real;
  1544. int orgip, commip;
  1545. int pf, pf1, force;
  1546. struct options opts, rep_opts, pt_opts;
  1547. char *cp, *cp1;
  1548. char *cpend, *next;
  1549. char **ap, *argv[10];
  1550. struct lump* anchor;
  1551. struct rtpp_node *node;
  1552. struct iovec v[] = {
  1553. {NULL, 0}, /* reserved (cookie) */
  1554. {NULL, 0}, /* command & common options */
  1555. {NULL, 0}, /* per-media/per-node options 1 */
  1556. {NULL, 0}, /* per-media/per-node options 2 */
  1557. {" ", 1}, /* separator */
  1558. {NULL, 0}, /* callid */
  1559. {" ", 1}, /* separator */
  1560. {NULL, 7}, /* newip */
  1561. {" ", 1}, /* separator */
  1562. {NULL, 1}, /* oldport */
  1563. {" ", 1}, /* separator */
  1564. {NULL, 0}, /* from_tag */
  1565. {";", 1}, /* separator */
  1566. {NULL, 0}, /* medianum */
  1567. {" ", 1}, /* separator */
  1568. {NULL, 0}, /* to_tag */
  1569. {";", 1}, /* separator */
  1570. {NULL, 0}, /* medianum */
  1571. {" ", 1}, /* separator */
  1572. {NULL, 0}, /* Timeout-Socket */
  1573. };
  1574. int iovec_param_count;
  1575. char *c1p, *c2p, *bodylimit, *o1p;
  1576. char itoabuf_buf[20];
  1577. int medianum, media_multi;
  1578. str itoabuf_str;
  1579. int c1p_altered;
  1580. int sdp_session_num, sdp_stream_num;
  1581. sdp_session_cell_t* sdp_session;
  1582. sdp_stream_cell_t* sdp_stream;
  1583. memset(&opts, '\0', sizeof(opts));
  1584. memset(&rep_opts, '\0', sizeof(rep_opts));
  1585. memset(&pt_opts, '\0', sizeof(pt_opts));
  1586. /* Leave space for U/L prefix TBD later */
  1587. if (append_opts(&opts, '?') == -1) {
  1588. LM_ERR("out of pkg memory\n");
  1589. FORCE_RTP_PROXY_RET (-1);
  1590. }
  1591. flookup = force = real = orgip = commip = 0;
  1592. for (cp = str1; cp != NULL && *cp != '\0'; cp++) {
  1593. switch (*cp) {
  1594. case 'a':
  1595. case 'A':
  1596. if (append_opts(&opts, 'A') == -1) {
  1597. LM_ERR("out of pkg memory\n");
  1598. FORCE_RTP_PROXY_RET (-1);
  1599. }
  1600. real = 1;
  1601. break;
  1602. case 'i':
  1603. case 'I':
  1604. if (append_opts(&opts, 'I') == -1) {
  1605. LM_ERR("out of pkg memory\n");
  1606. FORCE_RTP_PROXY_RET (-1);
  1607. }
  1608. break;
  1609. case 'e':
  1610. case 'E':
  1611. if (append_opts(&opts, 'E') == -1) {
  1612. LM_ERR("out of pkg memory\n");
  1613. FORCE_RTP_PROXY_RET (-1);
  1614. }
  1615. break;
  1616. case 'l':
  1617. case 'L':
  1618. if (offer == 0) {
  1619. FORCE_RTP_PROXY_RET (-1);
  1620. }
  1621. flookup = 1;
  1622. break;
  1623. case 'f':
  1624. case 'F':
  1625. force = 1;
  1626. break;
  1627. case 'r':
  1628. case 'R':
  1629. real = 1;
  1630. break;
  1631. case 'c':
  1632. case 'C':
  1633. commip = 1;
  1634. break;
  1635. case 'o':
  1636. case 'O':
  1637. orgip = 1;
  1638. break;
  1639. case 'w':
  1640. case 'W':
  1641. if (append_opts(&opts, 'S') == -1) {
  1642. LM_ERR("out of pkg memory\n");
  1643. FORCE_RTP_PROXY_RET (-1);
  1644. }
  1645. break;
  1646. case 'z':
  1647. case 'Z':
  1648. if (append_opts(&rep_opts, 'Z') == -1) {
  1649. LM_ERR("out of pkg memory\n");
  1650. FORCE_RTP_PROXY_RET (-1);
  1651. }
  1652. /* If there are any digits following Z copy them into the command */
  1653. for (; cp[1] != '\0' && isdigit(cp[1]); cp++) {
  1654. if (append_opts(&rep_opts, cp[1]) == -1) {
  1655. LM_ERR("out of pkg memory\n");
  1656. FORCE_RTP_PROXY_RET (-1);
  1657. }
  1658. }
  1659. break;
  1660. default:
  1661. LM_ERR("unknown option `%c'\n", *cp);
  1662. FORCE_RTP_PROXY_RET (-1);
  1663. }
  1664. }
  1665. if (offer != 0) {
  1666. create = 1;
  1667. } else {
  1668. create = 0;
  1669. }
  1670. /* extract_body will also parse all the headers in the message as
  1671. * a side effect => don't move get_callid/get_to_tag in front of it
  1672. * -- andrei */
  1673. if (extract_body(msg, &body) == -1) {
  1674. LM_ERR("can't extract body from the message\n");
  1675. FORCE_RTP_PROXY_RET (-1);
  1676. }
  1677. if (get_callid(msg, &callid) == -1 || callid.len == 0) {
  1678. LM_ERR("can't get Call-Id field\n");
  1679. FORCE_RTP_PROXY_RET (-1);
  1680. }
  1681. to_tag.s = 0;
  1682. if (get_to_tag(msg, &to_tag) == -1) {
  1683. LM_ERR("can't get To tag\n");
  1684. FORCE_RTP_PROXY_RET (-1);
  1685. }
  1686. if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
  1687. LM_ERR("can't get From tag\n");
  1688. FORCE_RTP_PROXY_RET (-1);
  1689. }
  1690. if (flookup != 0) {
  1691. if (to_tag.len == 0) {
  1692. FORCE_RTP_PROXY_RET (-1);
  1693. }
  1694. create = 0;
  1695. } else if ((msg->first_line.type == SIP_REPLY && offer != 0)
  1696. || (msg->first_line.type == SIP_REQUEST && offer == 0)) {
  1697. if (to_tag.len == 0) {
  1698. FORCE_RTP_PROXY_RET (-1);
  1699. }
  1700. tmp = from_tag;
  1701. from_tag = to_tag;
  1702. to_tag = tmp;
  1703. }
  1704. proxied = 0;
  1705. if (nortpproxy_str.len) {
  1706. for ( cp=body.s ; (len=body.s+body.len-cp) >= nortpproxy_str.len ; ) {
  1707. cp1 = ser_memmem(cp, nortpproxy_str.s, len, nortpproxy_str.len);
  1708. if (cp1 == NULL)
  1709. break;
  1710. if (cp1[-1] == '\n' || cp1[-1] == '\r') {
  1711. proxied = 1;
  1712. break;
  1713. }
  1714. cp = cp1 + nortpproxy_str.len;
  1715. }
  1716. }
  1717. if (proxied != 0 && force == 0) {
  1718. FORCE_RTP_PROXY_RET (-2);
  1719. }
  1720. /*
  1721. * Parsing of SDP body.
  1722. * It can contain a few session descriptions (each starts with
  1723. * v-line), and each session may contain a few media descriptions
  1724. * (each starts with m-line).
  1725. * We have to change ports in m-lines, and also change IP addresses in
  1726. * c-lines which can be placed either in session header (fallback for
  1727. * all medias) or media description.
  1728. * Ports should be allocated for any media. IPs all should be changed
  1729. * to the same value (RTP proxy IP), so we can change all c-lines
  1730. * unconditionally.
  1731. */
  1732. if(0 != parse_sdp(msg)) {
  1733. LM_ERR("Unable to parse sdp\n");
  1734. FORCE_RTP_PROXY_RET (-1);
  1735. }
  1736. #ifdef EXTRA_DEBUG
  1737. print_sdp((sdp_info_t*)msg->body, L_DBG);
  1738. #endif
  1739. bodylimit = body.s + body.len;
  1740. if(msg->id != current_msg_id){
  1741. selected_rtpp_set = default_rtpp_set;
  1742. }
  1743. opts.s.s[0] = (create == 0) ? 'L' : 'U';
  1744. v[1].iov_base = opts.s.s;
  1745. v[1].iov_len = opts.oidx;
  1746. STR2IOVEC(callid, v[5]);
  1747. STR2IOVEC(from_tag, v[11]);
  1748. STR2IOVEC(to_tag, v[15]);
  1749. /* check if this is a single or a multi stream SDP offer/answer */
  1750. sdp_stream_num = get_sdp_stream_num(msg);
  1751. switch (sdp_stream_num) {
  1752. case 0:
  1753. LM_ERR("sdp w/o streams\n");
  1754. FORCE_RTP_PROXY_RET (-1);
  1755. break;
  1756. case 1:
  1757. media_multi = 0;
  1758. break;
  1759. default:
  1760. media_multi = 1;
  1761. }
  1762. #ifdef EXTRA_DEBUG
  1763. LM_DBG("my new media_multi=%d\n", media_multi);
  1764. #endif
  1765. medianum = 0;
  1766. sdp_session_num = 0;
  1767. for(;;) {
  1768. sdp_session = get_sdp_session(msg, sdp_session_num);
  1769. if(!sdp_session) break;
  1770. sdp_stream_num = 0;
  1771. c1p_altered = 0;
  1772. o1p = sdp_session->o_ip_addr.s;
  1773. for(;;) {
  1774. sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
  1775. if(!sdp_stream) break;
  1776. if (sdp_stream->ip_addr.s && sdp_stream->ip_addr.len>0) {
  1777. oldip = sdp_stream->ip_addr;
  1778. pf = sdp_stream->pf;
  1779. } else {
  1780. oldip = sdp_session->ip_addr;
  1781. pf = sdp_session->pf;
  1782. }
  1783. oldport = sdp_stream->port;
  1784. payload_types = sdp_stream->payloads;
  1785. medianum++;
  1786. if (real != 0) {
  1787. newip = oldip;
  1788. } else {
  1789. newip.s = ip_addr2a(&msg->rcv.src_ip);
  1790. newip.len = strlen(newip.s);
  1791. }
  1792. /* XXX must compare address families in all addresses */
  1793. if (pf == AF_INET6) {
  1794. if (append_opts(&opts, '6') == -1) {
  1795. LM_ERR("out of pkg memory\n");
  1796. FORCE_RTP_PROXY_RET (-1);
  1797. }
  1798. }
  1799. STR2IOVEC(newip, v[7]);
  1800. STR2IOVEC(oldport, v[9]);
  1801. #ifdef EXTRA_DEBUG
  1802. LM_DBG("STR2IOVEC(newip[%.*s], v[7])", newip.len, newip.s);
  1803. LM_DBG("STR2IOVEC(oldport[%.*s], v[9])", oldport.len, oldport.s);
  1804. #endif
  1805. if (1 || media_multi) /* XXX netch: can't choose now*/
  1806. {
  1807. snprintf(itoabuf_buf, sizeof itoabuf_buf, "%d", medianum);
  1808. itoabuf_str.s = itoabuf_buf;
  1809. itoabuf_str.len = strlen(itoabuf_buf);
  1810. STR2IOVEC(itoabuf_str, v[13]);
  1811. STR2IOVEC(itoabuf_str, v[17]);
  1812. #ifdef EXTRA_DEBUG
  1813. LM_DBG("STR2IOVEC(itoabuf_str, v[13])\n");
  1814. LM_DBG("STR2IOVEC(itoabuf_str, v[17])\n");
  1815. #endif
  1816. } else {
  1817. v[12].iov_len = v[13].iov_len = 0;
  1818. v[16].iov_len = v[17].iov_len = 0;
  1819. }
  1820. do {
  1821. node = select_rtpp_node(callid, 1);
  1822. if (!node) {
  1823. LM_ERR("no available proxies\n");
  1824. FORCE_RTP_PROXY_RET (-1);
  1825. }
  1826. if (rep_opts.oidx > 0) {
  1827. if (node->rn_rep_supported == 0) {
  1828. LM_WARN("re-packetization is requested but is not "
  1829. "supported by the selected RTP proxy node\n");
  1830. v[2].iov_len = 0;
  1831. } else {
  1832. v[2].iov_base = rep_opts.s.s;
  1833. v[2].iov_len += rep_opts.oidx;
  1834. }
  1835. }
  1836. #ifdef EXTRA_DEBUG
  1837. LM_DBG("payload_types='%.*s'\n", payload_types.len, payload_types.s);
  1838. #endif
  1839. if (sdp_stream->is_rtp && payload_types.len > 0 && node->rn_ptl_supported != 0) {
  1840. pt_opts.oidx = 0;
  1841. if (append_opts(&pt_opts, 'c') == -1) {
  1842. LM_ERR("out of pkg memory\n");
  1843. FORCE_RTP_PROXY_RET (-1);
  1844. }
  1845. /*
  1846. * Convert space-separated payload types list into
  1847. * a comma-separated list.
  1848. */
  1849. for (cp = payload_types.s;
  1850. cp < payload_types.s + payload_types.len; cp++) {
  1851. if (isdigit(*cp)) {
  1852. if (append_opts(&pt_opts, *cp) == -1) {
  1853. LM_ERR("out of pkg memory\n");
  1854. FORCE_RTP_PROXY_RET (-1);
  1855. }
  1856. continue;
  1857. }
  1858. do {
  1859. cp++;
  1860. } while (!isdigit(*cp) &&
  1861. cp < payload_types.s + payload_types.len);
  1862. /* Check EOL */
  1863. if (cp >= payload_types.s + payload_types.len)
  1864. break;
  1865. if (append_opts(&pt_opts, ',') == -1) {
  1866. LM_ERR("out of pkg memory\n");
  1867. FORCE_RTP_PROXY_RET (-1);
  1868. }
  1869. cp--;
  1870. }
  1871. v[3].iov_base = pt_opts.s.s;
  1872. v[3].iov_len = pt_opts.oidx;
  1873. } else {
  1874. v[3].iov_len = 0;
  1875. }
  1876. if (to_tag.len > 0) {
  1877. iovec_param_count = 18;
  1878. if (timeout_socket_str.len > 0) {
  1879. iovec_param_count = 20;
  1880. STR2IOVEC(timeout_socket_str, v[19]);
  1881. }
  1882. } else {
  1883. iovec_param_count = 14;
  1884. }
  1885. cp = send_rtpp_command(node, v, iovec_param_count);
  1886. } while (cp == NULL);
  1887. LM_DBG("proxy reply: %s\n", cp);
  1888. /* Parse proxy reply to <argc,argv> */
  1889. argc = 0;
  1890. memset(argv, 0, sizeof(argv));
  1891. cpend=cp+strlen(cp);
  1892. next=eat_token_end(cp, cpend);
  1893. for (ap=argv; cp<cpend; cp=next+1, next=eat_token_end(cp, cpend)){
  1894. *next=0;
  1895. if (*cp != '\0') {
  1896. *ap=cp;
  1897. argc++;
  1898. if ((char*)++ap >= ((char*)argv+sizeof(argv)))
  1899. break;
  1900. }
  1901. }
  1902. if (argc < 1) {
  1903. LM_ERR("no reply from rtp proxy\n");
  1904. FORCE_RTP_PROXY_RET (-1);
  1905. }
  1906. port = atoi(argv[0]);
  1907. if (port <= 0 || port > 65535) {
  1908. if (port != 0 || flookup == 0)
  1909. LM_ERR("incorrect port %i in reply "
  1910. "from rtp proxy\n",port);
  1911. FORCE_RTP_PROXY_RET (-1);
  1912. }
  1913. pf1 = (argc >= 3 && argv[2][0] == '6') ? AF_INET6 : AF_INET;
  1914. if (isnulladdr(&oldip, pf)) {
  1915. if (pf1 == AF_INET6) {
  1916. newip.s = "::";
  1917. newip.len = 2;
  1918. } else {
  1919. newip.s = "0.0.0.0";
  1920. newip.len = 7;
  1921. }
  1922. } else {
  1923. if (forcedIP) {
  1924. newip.s = str2;
  1925. newip.len = strlen(newip.s);
  1926. #ifdef EXTRA_DEBUG
  1927. LM_DBG("forcing IP='%.*s'\n", newip.len, newip.s);
  1928. #endif
  1929. } else {
  1930. newip.s = (argc < 2) ? str2 : argv[1];
  1931. newip.len = strlen(newip.s);
  1932. }
  1933. }
  1934. /* marker to double check : newport goes: str -> int -> str ?!?! */
  1935. newport.s = int2str(port, &newport.len); /* beware static buffer */
  1936. /* Alter port. */
  1937. body1.s = sdp_stream->media.s;
  1938. body1.len = bodylimit - body1.s;
  1939. #ifdef EXTRA_DEBUG
  1940. LM_DBG("alter port body1='%.*s'\n", body1.len, body1.s);
  1941. #endif
  1942. /* do not do it if old port was 0 (means media disable)
  1943. * - check if actually should be better done in rtpptoxy,
  1944. * by returning also 0
  1945. * - or by not sending to rtpproxy the old port if 0
  1946. */
  1947. if(oldport.len!=1 || oldport.s[0]!='0')
  1948. {
  1949. if (alter_mediaport(msg, &body1, &oldport, &newport, 0) == -1) {
  1950. FORCE_RTP_PROXY_RET (-1);
  1951. }
  1952. }
  1953. /*
  1954. * Alter RTCP attribute if present. Inserting RTP port + 1 (as allocated
  1955. * by RTP proxy). No IP-address is needed in the new RTCP attribute as the
  1956. * 'c' attribute (altered below) will contain the RTP proxy IP address.
  1957. * See RFC 3605 for definition of RTCP attribute.
  1958. * ported from ser
  1959. */
  1960. if (sdp_stream->rtcp_port.s && sdp_stream->rtcp_port.len) {
  1961. newrtcp.s = int2str(port+1, &newrtcp.len); /* beware static buffer */
  1962. /* Alter port. */
  1963. body1.s = sdp_stream->rtcp_port.s;
  1964. body1.len = bodylimit - body1.s;
  1965. #ifdef EXTRA_DEBUG
  1966. LM_DBG("alter rtcp body1='%.*s'\n", body1.len, body1.s);
  1967. #endif
  1968. if (alter_rtcp(msg, &body1, &sdp_stream->rtcp_port, &newrtcp) == -1) {
  1969. FORCE_RTP_PROXY_RET (-1);
  1970. }
  1971. }
  1972. c1p = sdp_session->ip_addr.s;
  1973. c2p = sdp_stream->ip_addr.s;
  1974. /*
  1975. * Alter IP. Don't alter IP common for the session
  1976. * more than once.
  1977. */
  1978. if (c2p != NULL || !c1p_altered) {
  1979. body1.s = c2p ? c2p : c1p;
  1980. body1.len = bodylimit - body1.s;
  1981. #ifdef EXTRA_DEBUG
  1982. LM_DBG("alter ip body1='%.*s'\n", body1.len, body1.s);
  1983. #endif
  1984. if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1) {
  1985. FORCE_RTP_PROXY_RET (-1);
  1986. }
  1987. if (!c2p)
  1988. c1p_altered = 1;
  1989. }
  1990. /*
  1991. * Alter common IP if required, but don't do it more than once.
  1992. */
  1993. if (commip && c1p && !c1p_altered) {
  1994. body1.s = c1p;
  1995. body1.len = bodylimit - body1.s;
  1996. #ifdef EXTRA_DEBUG
  1997. LM_DBG("alter common ip body1='%.*s'\n", body1.len, body1.s);
  1998. #endif
  1999. if (alter_mediaip(msg, &body1, &sdp_session->ip_addr, sdp_session->pf, &newip, pf1, 0)==-1) {
  2000. FORCE_RTP_PROXY_RET (-1);
  2001. }
  2002. c1p_altered = 1;
  2003. }
  2004. /*
  2005. * Alter the IP in "o=", but only once per session
  2006. */
  2007. if (o1p) {
  2008. body1.s = o1p;
  2009. body1.len = bodylimit - body1.s;
  2010. #ifdef EXTRA_DEBUG
  2011. LM_DBG("alter media ip body1='%.*s'\n", body1.len, body1.s);
  2012. #endif
  2013. if (alter_mediaip(msg, &body1, &sdp_session->o_ip_addr, sdp_session->o_pf, &newip, pf1, 0)==-1) {
  2014. FORCE_RTP_PROXY_RET (-1);
  2015. }
  2016. o1p = 0;
  2017. }
  2018. sdp_stream_num++;
  2019. }
  2020. sdp_session_num++;
  2021. }
  2022. free_opts(&opts, &rep_opts, &pt_opts);
  2023. if (proxied == 0 && nortpproxy_str.len) {
  2024. cp = pkg_malloc((nortpproxy_str.len + CRLF_LEN) * sizeof(char));
  2025. if (cp == NULL) {
  2026. LM_ERR("out of pkg memory\n");
  2027. return -1;
  2028. }
  2029. anchor = anchor_lump(msg, body.s + body.len - msg->buf, 0, 0);
  2030. if (anchor == NULL) {
  2031. LM_ERR("anchor_lump failed\n");
  2032. pkg_free(cp);
  2033. return -1;
  2034. }
  2035. memcpy(cp, CRLF, CRLF_LEN);
  2036. memcpy(cp + CRLF_LEN, nortpproxy_str.s, nortpproxy_str.len);
  2037. if (insert_new_lump_after(anchor, cp, nortpproxy_str.len + CRLF_LEN, 0) == NULL) {
  2038. LM_ERR("insert_new_lump_after failed\n");
  2039. pkg_free(cp);
  2040. return -1;
  2041. }
  2042. }
  2043. return 1;
  2044. }
  2045. static int start_recording_f(struct sip_msg* msg, char *foo, char *bar)
  2046. {
  2047. int nitems;
  2048. str callid = {0, 0};
  2049. str from_tag = {0, 0};
  2050. str to_tag = {0, 0};
  2051. struct rtpp_node *node;
  2052. struct iovec v[1 + 4 + 3] = {{NULL, 0}, {"R", 1}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}};
  2053. /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 1 */
  2054. if (get_callid(msg, &callid) == -1 || callid.len == 0) {
  2055. LM_ERR("can't get Call-Id field\n");
  2056. return -1;
  2057. }
  2058. if (get_to_tag(msg, &to_tag) == -1) {
  2059. LM_ERR("can't get To tag\n");
  2060. return -1;
  2061. }
  2062. if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
  2063. LM_ERR("can't get From tag\n");
  2064. return -1;
  2065. }
  2066. if(msg->id != current_msg_id){
  2067. selected_rtpp_set = default_rtpp_set;
  2068. }
  2069. STR2IOVEC(callid, v[3]);
  2070. STR2IOVEC(from_tag, v[5]);
  2071. STR2IOVEC(to_tag, v[7]);
  2072. node = select_rtpp_node(callid, 1);
  2073. if (!node) {
  2074. LM_ERR("no available proxies\n");
  2075. return -1;
  2076. }
  2077. nitems = 8;
  2078. if (msg->first_line.type == SIP_REPLY) {
  2079. if (to_tag.len == 0)
  2080. return -1;
  2081. STR2IOVEC(to_tag, v[5]);
  2082. STR2IOVEC(from_tag, v[7]);
  2083. } else {
  2084. STR2IOVEC(from_tag, v[5]);
  2085. STR2IOVEC(to_tag, v[7]);
  2086. if (to_tag.len <= 0)
  2087. nitems = 6;
  2088. }
  2089. send_rtpp_command(node, v, nitems);
  2090. return 1;
  2091. }
  2092. /*
  2093. * Returns the current RTP-Statistics from the RTP-Proxy
  2094. */
  2095. static int
  2096. pv_get_rtpstat_f(struct sip_msg *msg, pv_param_t *param,
  2097. pv_value_t *res)
  2098. {
  2099. str ret_val = {0, 0};
  2100. int nitems;
  2101. str callid = {0, 0};
  2102. str from_tag = {0, 0};
  2103. str to_tag = {0, 0};
  2104. struct rtpp_node *node;
  2105. struct iovec v[1 + 4 + 3 + 1] = {{NULL, 0}, {"Q", 1}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}, {";1 ", 3}, {";1", }, {NULL, 0}};
  2106. if (get_callid(msg, &callid) == -1 || callid.len == 0) {
  2107. LM_ERR("can't get Call-Id field\n");
  2108. return -1;
  2109. }
  2110. if (get_to_tag(msg, &to_tag) == -1) {
  2111. LM_ERR("can't get To tag\n");
  2112. return -1;
  2113. }
  2114. if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
  2115. LM_ERR("can't get From tag\n");
  2116. return -1;
  2117. }
  2118. if(msg->id != current_msg_id){
  2119. selected_rtpp_set = default_rtpp_set;
  2120. }
  2121. STR2IOVEC(callid, v[3]);
  2122. STR2IOVEC(from_tag, v[5]);
  2123. STR2IOVEC(to_tag, v[7]);
  2124. node = select_rtpp_node(callid, 1);
  2125. if (!node) {
  2126. LM_ERR("no available proxies\n");
  2127. return -1;
  2128. }
  2129. nitems = 8;
  2130. if (msg->first_line.type == SIP_REPLY) {
  2131. if (to_tag.len == 0)
  2132. return -1;
  2133. STR2IOVEC(to_tag, v[5]);
  2134. STR2IOVEC(from_tag, v[7]);
  2135. } else {
  2136. STR2IOVEC(from_tag, v[5]);
  2137. STR2IOVEC(to_tag, v[7]);
  2138. if (to_tag.len <= 0)
  2139. nitems = 6;
  2140. }
  2141. ret_val.s = send_rtpp_command(node, v, nitems);
  2142. ret_val.len = strlen(ret_val.s);
  2143. return pv_get_strval(msg, param, res, &ret_val);
  2144. }