binrpc_run.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2006 iptelorg GmbH
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. */
  27. /* History:
  28. * --------
  29. * 2006-02-08 created by andrei
  30. */
  31. #include "binrpc.h"
  32. #include "../../dprint.h"
  33. #include "../../rpc.h"
  34. #include "../../sr_module.h"
  35. #include "../../mem/mem.h"
  36. #include "../../clist.h"
  37. #include "io_listener.h"
  38. #include "ctl.h"
  39. #include <stdio.h> /* vsnprintf */
  40. #include <stdlib.h> /* strtod */
  41. #include <stdarg.h>
  42. /* if set try to automatically convert values to the requested type in
  43. rpc->scan (default: not set) */
  44. int autoconvert=0;
  45. int binrpc_max_body_size = 4; /* multiplied by 1024 in mod init */
  46. int binrpc_struct_max_body_size = 1; /* multiplied by 1024 in mod init */
  47. #define BINRPC_MAX_BODY binrpc_max_body_size /* maximum body for send */
  48. #define STRUCT_MAX_BODY binrpc_struct_max_body_size
  49. #define MAX_MSG_CHUNKS 96
  50. #define BINRPC_GC_IBSIZE 4 /* initial gc block size (pointers no.) */
  51. struct rpc_struct_head{
  52. struct rpc_struct_l* next;
  53. struct rpc_struct_l* prev;
  54. };
  55. struct rpc_struct_l{
  56. struct rpc_struct_l* next;
  57. struct rpc_struct_l* prev;
  58. struct binrpc_pkt pkt;
  59. struct rpc_struct_head substructs; /* head */
  60. int offset; /* byte offset in parent's pkt */
  61. };
  62. struct binrpc_send_ctx{
  63. struct binrpc_pkt pkt; /* body */
  64. struct rpc_struct_head structs; /* list head */
  65. };
  66. struct binrpc_recv_ctx{
  67. struct binrpc_parse_ctx ctx;
  68. unsigned char* s; /* current position in buffer */
  69. unsigned char* end;
  70. int record_no;
  71. int in_struct;
  72. };
  73. struct binrpc_gc_block{
  74. unsigned short p_no; /**< array size */
  75. unsigned short idx; /**< current/last used pos. in the array */
  76. struct binrpc_gc_block* next;
  77. void* p[1]; /**< array of pointers that will be free'd */
  78. };
  79. struct binrpc_ctx{
  80. struct binrpc_recv_ctx in;
  81. struct binrpc_send_ctx out;
  82. void* send_h; /* send handle */
  83. char* method;
  84. struct binrpc_gc_block* gc; /**< garbage collection */
  85. int replied;
  86. int err_code;
  87. str err_phrase; /**< Leading zero must be included! */
  88. };
  89. struct iovec_array{
  90. struct iovec* v;
  91. int idx;
  92. int len;
  93. void *ctx;
  94. };
  95. /* send */
  96. static void rpc_fault(struct binrpc_ctx* ctx, int code, char* fmt, ...);
  97. static int rpc_send(struct binrpc_ctx* ctx);
  98. static int rpc_send_v(struct iovec_array *a);
  99. static int rpc_add(struct binrpc_ctx* ctx, char* fmt, ...);
  100. static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...);
  101. static int rpc_rpl_printf(struct binrpc_ctx* ctx, char* fmt, ...);
  102. static int rpc_struct_add(struct rpc_struct_l* s, char* fmt, ...);
  103. static int rpc_array_add(struct rpc_struct_l* s, char* fmt, ...);
  104. static int rpc_struct_scan(struct rpc_struct_l* s, char* fmt, ...);
  105. /* struct scan */
  106. static int rpc_struct_printf(struct rpc_struct_l *s, char* name,
  107. char* fmt, ...);
  108. static rpc_t binrpc_callbacks;
  109. void binrpc_callbacks_init(void)
  110. {
  111. memset(&binrpc_callbacks, 0, sizeof(binrpc_callbacks));
  112. binrpc_callbacks.fault = (rpc_fault_f)rpc_fault;
  113. binrpc_callbacks.send = (rpc_send_f)rpc_send;
  114. binrpc_callbacks.add = (rpc_add_f)rpc_add;
  115. binrpc_callbacks.scan = (rpc_scan_f)rpc_scan;
  116. binrpc_callbacks.rpl_printf = (rpc_rpl_printf_f)rpc_rpl_printf;
  117. binrpc_callbacks.struct_add = (rpc_struct_add_f)rpc_struct_add;
  118. binrpc_callbacks.array_add = (rpc_struct_add_f)rpc_array_add;
  119. binrpc_callbacks.struct_scan = (rpc_struct_scan_f)rpc_struct_scan;
  120. binrpc_callbacks.struct_printf = (rpc_struct_printf_f)rpc_struct_printf;
  121. }
  122. /** mark a pointer for freeing when the ctx is destroyed.
  123. * @return 0 on success, -1 on error
  124. */
  125. inline static int binrpc_gc_track(struct binrpc_ctx* ctx, void* p)
  126. {
  127. struct binrpc_gc_block* b;
  128. int n;
  129. b=ctx->gc;
  130. if (b==0 || (b->idx>=b->p_no)){
  131. n=(b==0)?BINRPC_GC_IBSIZE:b->p_no*2;
  132. b=ctl_malloc(sizeof(*b)+n*sizeof(void*)-sizeof(b->p));
  133. if (b==0)
  134. return -1;
  135. b->p_no=n;
  136. b->idx=0;
  137. /* link in front */
  138. b->next=ctx->gc;
  139. ctx->gc=b;
  140. }
  141. b->p[b->idx]=p;
  142. b->idx++;
  143. return 0;
  144. }
  145. /** free all the tracked pointer from ctx->gc.
  146. */
  147. inline static void binrpc_gc_collect(struct binrpc_ctx* ctx)
  148. {
  149. struct binrpc_gc_block* b;
  150. struct binrpc_gc_block* next;
  151. int i;
  152. for(b=ctx->gc; b; b=next){
  153. next=b->next;
  154. for (i=0; i<b->idx; i++)
  155. ctl_free(b->p[i]);
  156. ctl_free(b);
  157. }
  158. ctx->gc=0;
  159. }
  160. static struct rpc_struct_l* new_rpc_struct()
  161. {
  162. struct rpc_struct_l* rs;
  163. /* alloc everything in one chunk */
  164. rs=ctl_malloc(sizeof(struct rpc_struct_l)+STRUCT_MAX_BODY);
  165. if (rs==0)
  166. goto error;
  167. memset(rs, 0, sizeof(struct rpc_struct_l));
  168. clist_init(&rs->substructs, next, prev);
  169. if (binrpc_init_pkt(&rs->pkt,
  170. (unsigned char*)rs+sizeof(struct rpc_struct_l),
  171. STRUCT_MAX_BODY)<0){
  172. ctl_free(rs);
  173. goto error;
  174. }
  175. return rs;
  176. error:
  177. return 0;
  178. }
  179. #if 0 /* not used yet */
  180. /* doubles the size */
  181. static struct rpc_struct_l* grow_rpc_struct(struct rpc_struct_l *rs)
  182. {
  183. struct rpc_struct_l* new_rs;
  184. int csize; /* body */
  185. csize=binrpc_pkt_len(&rs->pkt);
  186. csize*=2;
  187. new_rs=ctl_realloc(rs, sizeof(struct rpc_struct_l)+csize);
  188. if (new_rs){
  189. binrpc_pkt_update_buf(&rs->pkt,
  190. (unsigned char*)new_rs+sizeof(struct rpc_struct_l),
  191. csize);
  192. }
  193. return new_rs;
  194. }
  195. #endif
  196. /* appends buf to an already init. binrpc_pkt */
  197. inline static int append_pkt_body(struct binrpc_pkt* p, unsigned char* buf,
  198. int len)
  199. {
  200. if ((int)(p->end-p->crt)<len){
  201. goto error;
  202. #if 0
  203. size=2*(int)(p->end-p->body);
  204. offset=binrpc_pkt_len(p);
  205. for(;(size-offset)<len; size*=2); /* find new size */
  206. new_b=ctl_realloc(p->body, size);
  207. if (new_b==0)
  208. goto error;
  209. binrpc_pkt_update_buf(p, new_b, size);
  210. #endif
  211. }
  212. memcpy(p->crt, buf, len);
  213. p->crt+=len;
  214. return 0;
  215. error:
  216. return -1; /* buff. overflow */
  217. }
  218. inline static int append_iovec(struct iovec_array* a, unsigned char* buf,
  219. int len)
  220. {
  221. int ret;
  222. if (a->idx >= a->len) {
  223. ret = rpc_send_v(a);
  224. if (ret < 0)
  225. return ret;
  226. }
  227. a->v[a->idx].iov_base=buf;
  228. a->v[a->idx].iov_len=len;
  229. a->idx++;
  230. return 0;
  231. }
  232. static int body_get_len(struct binrpc_pkt* body,
  233. struct rpc_struct_head* sl_head)
  234. {
  235. struct rpc_struct_l* l;
  236. int len;
  237. len=binrpc_pkt_len(body);
  238. clist_foreach(sl_head, l, next){
  239. len+=body_get_len(&l->pkt, &l->substructs);
  240. }
  241. return len;
  242. }
  243. static int body_fill_iovec(struct iovec_array* v_a,
  244. struct binrpc_pkt* body,
  245. struct rpc_struct_head* sl_head)
  246. {
  247. int offs;
  248. struct rpc_struct_l* l;
  249. int ret;
  250. offs=0;
  251. clist_foreach(sl_head, l, next){
  252. if ((ret=append_iovec(v_a, body->body+offs, l->offset-offs))<0)
  253. goto error;
  254. offs=l->offset;
  255. if ((ret=body_fill_iovec(v_a, &l->pkt, &l->substructs))<0)
  256. goto error;
  257. };
  258. /* copy the rest */
  259. ret=append_iovec(v_a, body->body+offs, binrpc_pkt_len(body)-offs);
  260. error:
  261. return ret;
  262. }
  263. #if 0
  264. /* expects an initialized new_b */
  265. static int build_structs(struct binrpc_pkt *new_b, struct binrpc_pkt* body,
  266. struct rpc_struct_head* sl_head)
  267. {
  268. int offs;
  269. struct rpc_struct_l* l;
  270. int ret;
  271. offs=0;
  272. clist_foreach(sl_head, l, next){
  273. if ((ret=append_pkt_body(new_b, body->body+offs, l->offset-offs))<0)
  274. goto error;
  275. offs=l->offset;
  276. if ((ret=build_structs(new_b, &l->pkt, &l->substructs))<0)
  277. goto error;
  278. };
  279. /* copy the rest */
  280. ret=append_pkt_body(new_b, body->body+offs, binrpc_pkt_len(body)-offs);
  281. error:
  282. return ret;
  283. }
  284. #endif
  285. static void free_structs(struct rpc_struct_head* sl_head)
  286. {
  287. struct rpc_struct_l* l;
  288. struct rpc_struct_l* tmp;
  289. clist_foreach_safe(sl_head, l, tmp, next){
  290. free_structs(&l->substructs);
  291. memset(l, 0, sizeof(struct rpc_struct_l)); /* debugging */
  292. ctl_free(l);
  293. };
  294. }
  295. inline static int init_binrpc_ctx( struct binrpc_ctx* ctx,
  296. unsigned char* recv_buf,
  297. int recv_buf_len,
  298. void* send_handle
  299. )
  300. {
  301. int err;
  302. unsigned char* send_buf;
  303. int send_buf_len;
  304. memset(ctx, 0, sizeof(struct binrpc_ctx));
  305. clist_init(&ctx->out.structs, next, prev);
  306. ctx->send_h=send_handle;
  307. ctx->in.end=recv_buf+recv_buf_len;
  308. ctx->in.s=binrpc_parse_init(&ctx->in.ctx, recv_buf, recv_buf_len, &err);
  309. if (err<0) goto end;
  310. if ((ctx->in.ctx.tlen+(int)(ctx->in.s-recv_buf))>recv_buf_len){
  311. err=E_BINRPC_MORE_DATA;
  312. goto end;
  313. }
  314. /* fix end value */
  315. ctx->in.end=ctx->in.s+ctx->in.ctx.tlen;
  316. /* alloc temporary body buffer */
  317. send_buf_len=BINRPC_MAX_BODY;
  318. send_buf=ctl_malloc(send_buf_len);
  319. if (send_buf==0){
  320. err=E_BINRPC_LAST;
  321. goto end;
  322. }
  323. /* we'll keep only the body */
  324. err=binrpc_init_pkt(&ctx->out.pkt, send_buf, send_buf_len);
  325. end:
  326. return err;
  327. }
  328. static inline void destroy_binrpc_ctx(struct binrpc_ctx* ctx)
  329. {
  330. free_structs(&ctx->out.structs);
  331. if (ctx->out.pkt.body){
  332. ctl_free(ctx->out.pkt.body);
  333. ctx->out.pkt.body=0;
  334. }
  335. if (ctx->err_phrase.s){
  336. ctl_free(ctx->err_phrase.s);
  337. ctx->err_phrase.s=NULL;
  338. }
  339. binrpc_gc_collect(ctx);
  340. }
  341. #define MAX_FAULT_LEN 256
  342. #define FAULT_START_BUF (3 /* maxint*/+2/*max str header*/)
  343. static void _rpc_fault(struct binrpc_ctx* ctx, int code,
  344. char *phrase, int phrase_len)
  345. {
  346. static unsigned char fault_start[FAULT_START_BUF];
  347. static unsigned char hdr[BINRPC_MAX_HDR_SIZE];
  348. struct iovec v[3];
  349. struct binrpc_pkt body;
  350. int b_len;
  351. int hdr_len;
  352. int err;
  353. if (ctx->replied){
  354. LOG(L_ERR, "ERROR: binrpc: rpc_send: rpc method %s tried to reply"
  355. " more then once\n", ctx->method?ctx->method:"");
  356. return;
  357. }
  358. err=0;
  359. err=binrpc_init_pkt(&body, fault_start, FAULT_START_BUF);
  360. if (err<0){
  361. LOG(L_ERR, "ERROR: binrpc_init_pkt error\n");
  362. goto error;
  363. }
  364. /* adding a fault "manually" to avoid extra memcpys */
  365. err=binrpc_addint(&body, code);
  366. if (err<0){
  367. LOG(L_ERR, "ERROR: _rpc_fault: addint error\n");
  368. goto error;
  369. }
  370. err=binrpc_add_str_mark(&body, BINRPC_T_STR, phrase_len);
  371. if (err<0){
  372. LOG(L_ERR, "ERROR: _rpc_fault: add_str_mark error\n");
  373. goto error;
  374. }
  375. /*
  376. err=binrpc_addfault(&body, code, phrase, phrase_len);
  377. if (err<0){
  378. LOG(L_ERR, "ERROR: binrpc_addfault error\n");
  379. goto error;
  380. }*/
  381. b_len=binrpc_pkt_len(&body);
  382. err=hdr_len=binrpc_build_hdr(BINRPC_FAULT, b_len+phrase_len,
  383. ctx->in.ctx.cookie, hdr, BINRPC_MAX_HDR_SIZE);
  384. if (err<0){
  385. LOG(L_ERR, "ERROR: binrpc_build_hdr error\n");
  386. goto error;
  387. }
  388. v[0].iov_base=hdr;
  389. v[0].iov_len=hdr_len;
  390. v[1].iov_base=body.body;
  391. v[1].iov_len=b_len;
  392. v[2].iov_base=phrase;
  393. v[2].iov_len=phrase_len;
  394. if ((err=sock_send_v(ctx->send_h, v, 3))<0){
  395. if (err==-2){
  396. LOG(L_ERR, "ERROR: _rpc_fault: send failed: "
  397. "datagram too big\n");
  398. return;
  399. }
  400. LOG(L_ERR, "ERROR: _rpc_fault: send failed\n");
  401. return;
  402. }
  403. ctx->replied=1;
  404. return;
  405. error:
  406. LOG(L_ERR, "ERROR: _rpc_fault: binrpc_* failed with: %s (%d)\n",
  407. binrpc_error(err), err);
  408. }
  409. static void rpc_fault(struct binrpc_ctx* ctx, int code, char* fmt, ...)
  410. {
  411. char buf[MAX_FAULT_LEN];
  412. va_list ap;
  413. int len;
  414. if (ctx->replied){
  415. LOG(L_ERR, "ERROR: binrpc: rpc_send: rpc method %s tried to reply"
  416. " more then once\n", ctx->method?ctx->method:"");
  417. return;
  418. }
  419. va_start(ap, fmt);
  420. len=vsnprintf(buf, MAX_FAULT_LEN, fmt, ap); /* ignore trunc. errors */
  421. if ((len<0) || (len > MAX_FAULT_LEN))
  422. len=MAX_FAULT_LEN-1;
  423. va_end(ap);
  424. len++; /* vnsprintf doesn't include the terminating 0 */
  425. return _rpc_fault(ctx, code, buf, len);
  426. }
  427. /* Prepare the error reply without sending out the message */
  428. static int rpc_fault_prepare(struct binrpc_ctx* ctx, int code, char* fmt, ...)
  429. {
  430. char buf[MAX_FAULT_LEN];
  431. va_list ap;
  432. int len;
  433. if (ctx->replied){
  434. LOG(L_ERR, "ERROR: binrpc: rpc_send: rpc method %s tried to reply"
  435. " more then once\n", ctx->method?ctx->method:"");
  436. return -1;
  437. }
  438. va_start(ap, fmt);
  439. len=vsnprintf(buf, MAX_FAULT_LEN, fmt, ap); /* ignore trunc. errors */
  440. if ((len<0) || (len > MAX_FAULT_LEN))
  441. len=MAX_FAULT_LEN-1;
  442. va_end(ap);
  443. len++; /* vnsprintf doesn't include the terminating 0 */
  444. ctx->err_code = code;
  445. if (ctx->err_phrase.s)
  446. ctl_free(ctx->err_phrase.s);
  447. ctx->err_phrase.s = (char*)ctl_malloc(sizeof(char)*len);
  448. if (!ctx->err_phrase.s) {
  449. ctx->err_code = 0;
  450. ctx->err_phrase.len = 0;
  451. LOG(L_ERR, "ERROR: rpc_fault_prepare: not enough memory\n");
  452. return -1;
  453. }
  454. memcpy(ctx->err_phrase.s, buf, len);
  455. ctx->err_phrase.len = len;
  456. return 0;
  457. }
  458. /* Reset the saved error code */
  459. static void rpc_fault_reset(struct binrpc_ctx* ctx)
  460. {
  461. ctx->err_code = 0;
  462. if (ctx->err_phrase.s) {
  463. ctl_free(ctx->err_phrase.s);
  464. ctx->err_phrase.s = NULL;
  465. ctx->err_phrase.len = 0;
  466. }
  467. }
  468. /* wrapper around sock_send_v for staggered buffer writing */
  469. static int rpc_send_v(struct iovec_array *a)
  470. {
  471. int ret;
  472. if (a->idx <= 0)
  473. return 0;
  474. ret = sock_send_v(a->ctx, a->v, a->idx);
  475. if (ret < 0)
  476. return ret;
  477. a->idx = 0;
  478. return 0;
  479. }
  480. /* build the reply from the current body */
  481. static int rpc_send(struct binrpc_ctx* ctx)
  482. {
  483. int b_len;
  484. int hdr_len;
  485. struct iovec v[MAX_MSG_CHUNKS];
  486. struct iovec_array a;
  487. static unsigned char hdr[BINRPC_MAX_HDR_SIZE];
  488. int err;
  489. err=0;
  490. a.v=v;
  491. a.idx=1;
  492. a.len=MAX_MSG_CHUNKS;
  493. a.ctx = ctx->send_h;
  494. if (ctx->replied){
  495. LOG(L_ERR, "ERROR: binrpc: rpc_send: rpc method %s tried to reply"
  496. " more then once\n", ctx->method?ctx->method:"");
  497. goto error;
  498. }
  499. b_len=body_get_len(&ctx->out.pkt, &ctx->out.structs);
  500. err=hdr_len=binrpc_build_hdr( BINRPC_REPL, b_len, ctx->in.ctx.cookie,
  501. hdr, BINRPC_MAX_HDR_SIZE);
  502. if (err<0){
  503. LOG(L_ERR, "ERROR: binrpc: rpc_fault: binrpc_* failed with:"
  504. " %s (%d)\n", binrpc_error(err), err);
  505. goto error;
  506. }
  507. v[0].iov_base=hdr;
  508. v[0].iov_len=hdr_len;
  509. /* fill the rest of the iovecs */
  510. err=body_fill_iovec(&a, &ctx->out.pkt, &ctx->out.structs);
  511. if (err<0){
  512. LOG(L_ERR, "ERROR: binrprc: rpc_send: too many message chunks\n");
  513. goto error;
  514. }
  515. if ((err = rpc_send_v(&a)) < 0){
  516. if (err==-2){
  517. LOG(L_ERR, "ERROR: binrpc: rpc_send: send failed: "
  518. "datagram too big\n");
  519. goto error;
  520. }
  521. LOG(L_ERR, "ERROR: binrprc: rpc_send: send failed\n");
  522. goto error;
  523. }
  524. ctx->replied=1;
  525. return 0;
  526. error:
  527. return -1;
  528. }
  529. /* params: buf, size - buffer containing the packet
  530. * bytes_needed - int pointer, filled with how many bytes are still
  531. * needed (after bytes_needed new bytes received this
  532. * function will be called again
  533. * reply, - buffer where the reply will be written
  534. * reply_len - intially filled with the reply buffer len,
  535. * after the call will contain how much of that
  536. * buffer was really used
  537. * returns: number of bytes processed on success/partial success
  538. * -1 on error
  539. */
  540. int process_rpc_req(unsigned char* buf, int size, int* bytes_needed,
  541. void* sh, void** saved_state)
  542. {
  543. int err;
  544. struct binrpc_val val;
  545. rpc_export_t* rpc_e;
  546. struct binrpc_ctx f_ctx;
  547. struct binrpc_parse_ctx* ctx;
  548. if (size<BINRPC_MIN_PKT_SIZE){
  549. *bytes_needed=BINRPC_MIN_PKT_SIZE-size;
  550. return 0; /* more data , nothing processed */
  551. }
  552. err=init_binrpc_ctx(&f_ctx, buf, size, sh);
  553. ctx=&f_ctx.in.ctx;
  554. if (err<0){
  555. if (err==E_BINRPC_MORE_DATA){
  556. if (f_ctx.in.ctx.tlen){
  557. *bytes_needed=ctx->tlen+(int)(f_ctx.in.s-buf)-size;
  558. }else{
  559. *bytes_needed=1; /* we don't really know how much */
  560. }
  561. goto more_data;
  562. }else if( err==E_BINRPC_LAST){
  563. LOG(L_ERR, "ERROR: init_binrpc_ctx: out of memory\n");
  564. rpc_fault(&f_ctx, 500, "internal server error: out of mem.");
  565. goto error;
  566. }
  567. rpc_fault(&f_ctx, 400, "bad request: %s", binrpc_error(err));
  568. goto error;
  569. }
  570. err=E_BINRPC_BADPKT;
  571. if (ctx->type!=BINRPC_REQ){
  572. rpc_fault(&f_ctx, 400, "bad request: %s", binrpc_error(err));
  573. goto error;
  574. }
  575. /* now we have the entire packet */
  576. /* get rpc method */
  577. val.type=BINRPC_T_STR;
  578. f_ctx.in.s=binrpc_read_record(ctx, f_ctx.in.s, f_ctx.in.end, &val, &err);
  579. if (err<0){
  580. LOG(L_CRIT, "ERROR: bad rpc request method, binrpc error: %s (%d)\n",
  581. binrpc_error(err), err);
  582. rpc_fault(&f_ctx, 400, "bad request method: %s", binrpc_error(err) );
  583. goto error;
  584. }
  585. /* find_rpc_exports needs 0 terminated strings, but all str are
  586. * 0 term by default */
  587. rpc_e=find_rpc_export(val.u.strval.s, 0);
  588. if ((rpc_e==0) || (rpc_e->function==0)){
  589. rpc_fault(&f_ctx, 500, "command %s not found", val.u.strval.s);
  590. goto end;
  591. }
  592. f_ctx.method=val.u.strval.s;
  593. rpc_e->function(&binrpc_callbacks, &f_ctx);
  594. if (f_ctx.replied==0){
  595. if ((binrpc_pkt_len(&f_ctx.out.pkt)==0)
  596. && f_ctx.err_code && f_ctx.err_phrase.s
  597. ) {
  598. _rpc_fault(&f_ctx, f_ctx.err_code,
  599. f_ctx.err_phrase.s, f_ctx.err_phrase.len);
  600. /* to get an error reply if the rpc handlers hasn't replied
  601. * uncomment the following code:
  602. * } else if (binrpc_pkt_len(&f_ctx.out.pkt)==0){
  603. rpc_fault(&f_ctx, 500, "internal server error: no reply");
  604. LOG(L_ERR, "ERROR: rpc method %s hasn't replied\n",
  605. val.u.strval.s);
  606. */
  607. } else {
  608. rpc_send(&f_ctx);
  609. }
  610. }
  611. end:
  612. *bytes_needed=0; /* full read */
  613. destroy_binrpc_ctx(&f_ctx);
  614. return (int)(f_ctx.in.end-buf);
  615. error:
  616. if (f_ctx.replied==0){
  617. rpc_fault(&f_ctx, 500, "internal server error");
  618. LOG(L_ERR, "ERROR: unknown rpc errror\n");
  619. }
  620. *bytes_needed=0; /* we don't need anymore crap */
  621. destroy_binrpc_ctx(&f_ctx);
  622. return -1;
  623. more_data:
  624. destroy_binrpc_ctx(&f_ctx);
  625. return 0; /* nothing was processed */
  626. }
  627. static char* rpc_type_name(int type)
  628. {
  629. switch(type){
  630. case BINRPC_T_INT:
  631. return "integer";
  632. case BINRPC_T_STR:
  633. return "string";
  634. case BINRPC_T_DOUBLE:
  635. return "float";
  636. case BINRPC_T_STRUCT:
  637. return "structure";
  638. case BINRPC_T_ARRAY:
  639. return "array";
  640. case BINRPC_T_AVP:
  641. return "structure member";
  642. case BINRPC_T_BYTES:
  643. return "bytes array";
  644. case BINRPC_T_ALL:
  645. return "any";
  646. }
  647. return "<unknown/error>";
  648. };
  649. /** converts a binrpc_val to int.
  650. *@return int val on success, 0 and sets err on error (E_BINRPC_TYPE) */
  651. inline static int binrpc_val_conv_int( struct binrpc_val* v, int* err)
  652. {
  653. int ret;
  654. *err=0;
  655. switch(v->type){
  656. case BINRPC_T_INT:
  657. return v->u.intval;
  658. case BINRPC_T_DOUBLE:
  659. return (int) v->u.fval;
  660. case BINRPC_T_STR:
  661. if (str2sint(&v->u.strval, &ret)==0)
  662. return ret;
  663. }
  664. *err=E_BINRPC_TYPE;
  665. return 0;
  666. }
  667. /** converts a binrpc_val to double.
  668. *@return double val on success, 0 and sets err on error (E_BINRPC_TYPE) */
  669. inline static double binrpc_val_conv_double( struct binrpc_val* v, int* err)
  670. {
  671. double ret;
  672. char* end;
  673. *err=0;
  674. switch(v->type){
  675. case BINRPC_T_DOUBLE:
  676. return v->u.fval;
  677. case BINRPC_T_INT:
  678. return (double)v->u.intval;
  679. case BINRPC_T_STR:
  680. ret=strtod(v->u.strval.s, &end);
  681. if (end!=v->u.strval.s)
  682. return ret;
  683. }
  684. *err=E_BINRPC_TYPE;
  685. return 0;
  686. }
  687. /** converts a binrpc_val to str.
  688. *@return str val pointer on success, 0 and sets err on error (E_BINRPC_TYPE)*/
  689. inline static str* binrpc_val_conv_str(struct binrpc_ctx* ctx,
  690. struct binrpc_val* v, int* err)
  691. {
  692. str* ret;
  693. char* s;
  694. int len;
  695. *err=0;
  696. switch(v->type){
  697. case BINRPC_T_STR:
  698. return &v->u.strval;
  699. case BINRPC_T_INT:
  700. s=int2str(v->u.intval, &len);
  701. ret=ctl_malloc(sizeof(*ret)+len+1);
  702. if (ret==0 || binrpc_gc_track(ctx, ret)!=0){
  703. if(ret!=0) ctl_free(ret);
  704. *err=E_BINRPC_OVERFLOW;
  705. return 0;
  706. }
  707. ret->s=(char*)ret+sizeof(*ret);
  708. ret->len=len;
  709. memcpy(ret->s, s, len);
  710. ret->s[len]=0;
  711. return ret;
  712. case BINRPC_T_DOUBLE:
  713. /* for now the double to string conversion is not supported*/
  714. *err=E_BINRPC_BUG;
  715. return 0;
  716. }
  717. *err=E_BINRPC_TYPE;
  718. return 0;
  719. }
  720. /* rpc interface functions */
  721. /* returns the number of parameters read
  722. * on error: - number of parameters read so far (<=0)*/
  723. static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...)
  724. {
  725. va_list ap;
  726. struct binrpc_val v;
  727. int err;
  728. char* orig_fmt;
  729. int nofault;
  730. int modifiers;
  731. int autoconv;
  732. int i;
  733. double d;
  734. str* s;
  735. /* clear the previously saved error code */
  736. rpc_fault_reset(ctx);
  737. va_start(ap, fmt);
  738. orig_fmt=fmt;
  739. nofault = 0;
  740. modifiers=0;
  741. autoconv=autoconvert;
  742. for (;*fmt; fmt++){
  743. switch(*fmt){
  744. case '*': /* start of optional parameters */
  745. nofault = 1;
  746. modifiers++;
  747. continue;
  748. case '.': /* autoconv. on for the next parameter */
  749. modifiers++;
  750. autoconv=1;
  751. continue;
  752. case 'b': /* bool */
  753. case 't': /* time */
  754. case 'd': /* int */
  755. v.type=autoconv?BINRPC_T_ALL:BINRPC_T_INT;
  756. ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
  757. ctx->in.end, &v, &err);
  758. if (err<0 || ((i=binrpc_val_conv_int(&v, &err))==0 && err<0))
  759. goto error_read;
  760. *(va_arg(ap, int*))=i;
  761. break;
  762. case 'f':
  763. v.type=autoconv?BINRPC_T_ALL:BINRPC_T_DOUBLE;
  764. ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
  765. ctx->in.end, &v, &err);
  766. if (err<0 || ((d=binrpc_val_conv_double(&v, &err))==0 &&
  767. err<0))
  768. goto error_read;
  769. *(va_arg(ap, double*))=d;
  770. break;
  771. case 's': /* asciiz */
  772. case 'S': /* str */
  773. v.type=autoconv?BINRPC_T_ALL:BINRPC_T_STR;
  774. ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
  775. ctx->in.end, &v,&err);
  776. if (err<0 || ((s=binrpc_val_conv_str(ctx, &v, &err))==0 &&
  777. err<0)){
  778. v.u.strval.s="if you get this string, you don't"
  779. "check rpc_scan return code !!! (very bad)";
  780. v.u.strval.len=strlen(v.u.strval.s);
  781. s=&v.u.strval;
  782. }
  783. if (*fmt=='s'){
  784. *(va_arg(ap, char**))=s->s; /* 0 term by proto*/
  785. }else{
  786. *(va_arg(ap, str*))=*s;
  787. }
  788. if (err<0) goto error_read;
  789. break;
  790. case '{': /* struct */
  791. v.type=BINRPC_T_STRUCT;
  792. /* FIXME: structure reading doesn't work for now */
  793. #if 0
  794. ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
  795. ctx->in.end, &v, &err);
  796. if (err<0) goto error_read;
  797. ctx->in.in_struct++;
  798. *(va_arg(ap, void**))=ctx; /* use the same context */
  799. #endif
  800. goto error_not_supported;
  801. break;
  802. default:
  803. goto error_inv_param;
  804. }
  805. autoconv=autoconvert; /* reset autoconv*/
  806. ctx->in.record_no++;
  807. }
  808. va_end(ap);
  809. return (int)(fmt-orig_fmt)-modifiers;
  810. error_read:
  811. /* Do not immediately send out the error message, the user might retry the scan with
  812. different parameters */
  813. if(nofault==0 || ((err!=E_BINRPC_MORE_DATA) && (err!=E_BINRPC_EOP)))
  814. rpc_fault_prepare(ctx, 400, "error at parameter %d: expected %s type but"
  815. " %s", ctx->in.record_no, rpc_type_name(v.type),
  816. binrpc_error(err));
  817. /*
  818. rpc_fault(ctx, 400, "invalid record %d, offset %d (expected %d type)"
  819. ": %s", ctx->in.record_no, ctx->in.ctx.offset,
  820. v.type, binrpc_error(err));
  821. */
  822. goto error_ret;
  823. error_not_supported:
  824. rpc_fault(ctx, 500, "internal server error, type %d not supported",
  825. v.type);
  826. LOG(L_CRIT, "BUG: binrpc: rpc_scan: formatting char \'%c\'"
  827. " not supported\n", *fmt);
  828. goto error_ret;
  829. error_inv_param:
  830. rpc_fault(ctx, 500, "internal server error, invalid format char \'%c\'",
  831. *fmt);
  832. error_ret:
  833. va_end(ap);
  834. return -((int)(fmt-orig_fmt)-modifiers);
  835. }
  836. /* returns 0 on success, -1 on error */
  837. static int rpc_add(struct binrpc_ctx* ctx, char* fmt, ...)
  838. {
  839. va_list ap;
  840. int err;
  841. char* s;
  842. str* st;
  843. struct rpc_struct_l* rs;
  844. va_start(ap, fmt);
  845. for (;*fmt; fmt++){
  846. switch(*fmt){
  847. case 'd':
  848. case 't':
  849. case 'b':
  850. err=binrpc_addint(&ctx->out.pkt, va_arg(ap, int));
  851. if (err<0) goto error_add;
  852. break;
  853. case 's': /* asciiz */
  854. s=va_arg(ap, char*);
  855. if (s==0) /* fix null strings */
  856. s="<null string>";
  857. err=binrpc_addstr(&ctx->out.pkt, s, strlen(s));
  858. if (err<0) goto error_add;
  859. break;
  860. case 'S': /* str */
  861. st=va_arg(ap, str*);
  862. err=binrpc_addstr(&ctx->out.pkt, st->s, st->len);
  863. if (err<0) goto error_add;
  864. break;
  865. case '{':
  866. case '[':
  867. err=binrpc_start_struct(&ctx->out.pkt);
  868. if (err<0) goto error_add;
  869. rs=new_rpc_struct();
  870. if (rs==0) goto error_mem;
  871. rs->offset=binrpc_pkt_len(&ctx->out.pkt);
  872. err=binrpc_end_struct(&ctx->out.pkt);
  873. if (err<0) goto error_add;
  874. clist_append(&ctx->out.structs, rs, next, prev);
  875. *(va_arg(ap, void**))=rs;
  876. break;
  877. case 'f':
  878. err=binrpc_adddouble(&ctx->out.pkt, va_arg(ap, double));
  879. if (err<0) goto error_add;
  880. break;
  881. default:
  882. rpc_fault(ctx, 500, "Internal server error: "
  883. "invalid formatting character \'%c\'", *fmt);
  884. LOG(L_CRIT, "BUG: binrpc: rpc_add: formatting char \'%c\'"
  885. " not supported\n", *fmt);
  886. goto error;
  887. }
  888. }
  889. va_end(ap);
  890. return 0;
  891. error_mem:
  892. LOG(L_ERR, "ERROR: binrpc: rpc_add: out of memory\n");
  893. rpc_fault(ctx, 500, "Internal server error: out of memory");
  894. goto error;
  895. error_add:
  896. rpc_fault(ctx, 500, "Internal server error processing \'%c\': %s (%d)",
  897. *fmt, binrpc_error(err), err);
  898. error:
  899. va_end(ap);
  900. return -1;
  901. }
  902. #define RPC_PRINTF_BUF_SIZE 1024
  903. /* returns 0 on success, -1 on error */
  904. static int rpc_rpl_printf(struct binrpc_ctx* ctx, char* fmt, ...)
  905. {
  906. va_list ap;
  907. char* buf;
  908. int len;
  909. int err;
  910. buf=ctl_malloc(RPC_PRINTF_BUF_SIZE);
  911. if (buf==0) goto error;
  912. va_start(ap, fmt);
  913. len=vsnprintf(buf, RPC_PRINTF_BUF_SIZE, fmt, ap);
  914. va_end(ap);
  915. if ((len<0) || (len> RPC_PRINTF_BUF_SIZE)){
  916. LOG(L_ERR, "ERROR: binrpc: rpc_rpl_printf: buffer size exceeded(%d)\n",
  917. RPC_PRINTF_BUF_SIZE);
  918. goto error;
  919. }
  920. if ((err=binrpc_addstr(&ctx->out.pkt, buf, len))<0){
  921. LOG(L_ERR, "ERROR: binrpc: rpc_rpl_printf: binrpc_addstr failed:"
  922. " %s (%d)\n", binrpc_error(err), err);
  923. goto error;
  924. }
  925. ctl_free(buf);
  926. return 0;
  927. error:
  928. if (buf) ctl_free(buf);
  929. return -1;
  930. }
  931. /* returns 0 on success, -1 on error */
  932. static int rpc_struct_add(struct rpc_struct_l* s, char* fmt, ...)
  933. {
  934. va_list ap;
  935. int err;
  936. struct binrpc_val avp;
  937. struct rpc_struct_l* rs;
  938. va_start(ap, fmt);
  939. for (;*fmt; fmt++){
  940. memset(&avp, 0, sizeof(struct binrpc_val));
  941. avp.name.s=va_arg(ap, char*);
  942. if (avp.name.s)
  943. avp.name.len=strlen(avp.name.s);
  944. switch(*fmt){
  945. case 'd':
  946. case 't':
  947. case 'b':
  948. avp.type=BINRPC_T_INT;
  949. avp.u.intval=va_arg(ap, int);
  950. break;
  951. case 's': /* asciiz */
  952. avp.type=BINRPC_T_STR;
  953. avp.u.strval.s=va_arg(ap, char*);
  954. if (avp.u.strval.s)
  955. avp.u.strval.len=strlen(avp.u.strval.s);
  956. break;
  957. case 'S': /* str */
  958. avp.type=BINRPC_T_STR;
  959. avp.u.strval=*(va_arg(ap, str*));
  960. break;
  961. case '{':
  962. case '[':
  963. avp.type=BINRPC_T_STRUCT;
  964. err=binrpc_addavp(&s->pkt, &avp);
  965. if (err<0) goto error_add;
  966. rs=new_rpc_struct();
  967. if (rs==0) goto error_mem;
  968. rs->offset=binrpc_pkt_len(&s->pkt);
  969. err=binrpc_end_struct(&s->pkt);
  970. if (err<0) goto error_add;
  971. clist_append(&s->substructs, rs, next, prev);
  972. *(va_arg(ap, void**))=rs;
  973. goto end;
  974. case 'f':
  975. avp.type=BINRPC_T_DOUBLE;
  976. avp.u.fval=va_arg(ap, double);
  977. break;
  978. default:
  979. LOG(L_CRIT, "BUG: binrpc: rpc_struct_add: formatting char"
  980. " \'%c\'" " not supported\n", *fmt);
  981. goto error;
  982. }
  983. err=binrpc_addavp(&s->pkt, &avp);
  984. if (err<0) goto error;
  985. }
  986. end:
  987. va_end(ap);
  988. return 0;
  989. error_mem:
  990. error_add:
  991. error:
  992. va_end(ap);
  993. return -1;
  994. }
  995. /* returns 0 on success, -1 on error */
  996. static int rpc_array_add(struct rpc_struct_l* s, char* fmt, ...)
  997. {
  998. va_list ap;
  999. int err;
  1000. char* sv;
  1001. str* st;
  1002. struct rpc_struct_l* rs;
  1003. va_start(ap, fmt);
  1004. for (;*fmt; fmt++){
  1005. switch(*fmt){
  1006. case 'd':
  1007. case 't':
  1008. case 'b':
  1009. err=binrpc_addint(&s->pkt, va_arg(ap, int));
  1010. if (err<0) goto error_add;
  1011. break;
  1012. case 's': /* asciiz */
  1013. sv=va_arg(ap, char*);
  1014. if (sv==0) /* fix null strings */
  1015. sv="<null string>";
  1016. err=binrpc_addstr(&s->pkt, sv, strlen(sv));
  1017. if (err<0) goto error_add;
  1018. break;
  1019. case 'S': /* str */
  1020. st=va_arg(ap, str*);
  1021. err=binrpc_addstr(&s->pkt, st->s, st->len);
  1022. if (err<0) goto error_add;
  1023. break;
  1024. case '{':
  1025. case '[':
  1026. err=binrpc_start_struct(&s->pkt);
  1027. if (err<0) goto error_add;
  1028. rs=new_rpc_struct();
  1029. if (rs==0) goto error_mem;
  1030. rs->offset=binrpc_pkt_len(&s->pkt);
  1031. err=binrpc_end_struct(&s->pkt);
  1032. if (err<0) goto error_add;
  1033. clist_append(&s->substructs, rs, next, prev);
  1034. *(va_arg(ap, void**))=rs;
  1035. break;
  1036. case 'f':
  1037. err=binrpc_adddouble(&s->pkt, va_arg(ap, double));
  1038. if (err<0) goto error_add;
  1039. break;
  1040. default:
  1041. LOG(L_CRIT, "BUG: binrpc: rpc_add: formatting char \'%c\'"
  1042. " not supported\n", *fmt);
  1043. goto error;
  1044. }
  1045. }
  1046. va_end(ap);
  1047. return 0;
  1048. error_mem:
  1049. error_add:
  1050. error:
  1051. va_end(ap);
  1052. return -1;
  1053. }
  1054. /* returns 0 on success, -1 on error */
  1055. static int rpc_struct_printf(struct rpc_struct_l *s, char* name,
  1056. char* fmt, ...)
  1057. {
  1058. va_list ap;
  1059. char* buf;
  1060. int len;
  1061. int err;
  1062. struct binrpc_val avp;
  1063. buf=ctl_malloc(RPC_PRINTF_BUF_SIZE);
  1064. if (buf==0) goto error;
  1065. va_start(ap, fmt);
  1066. len=vsnprintf(buf, RPC_PRINTF_BUF_SIZE, fmt, ap);
  1067. va_end(ap);
  1068. if ((len<0) || (len> RPC_PRINTF_BUF_SIZE)){
  1069. LOG(L_ERR, "ERROR: binrpc: rpc_struct_printf:"
  1070. " buffer size exceeded(%d)\n", RPC_PRINTF_BUF_SIZE);
  1071. goto error;
  1072. }
  1073. avp.name.s=name;
  1074. avp.name.len=strlen(name);
  1075. avp.type=BINRPC_T_STR;
  1076. avp.u.strval.s=buf;
  1077. avp.u.strval.len=strlen(buf);
  1078. if ((err=binrpc_addavp(&s->pkt, &avp))<0){
  1079. LOG(L_ERR, "ERROR: binrpc: rpc_printf: binrpc_addavp failed:"
  1080. " %s (%d)\n", binrpc_error(err), err);
  1081. goto error;
  1082. }
  1083. ctl_free(buf);
  1084. return 0;
  1085. error:
  1086. if (buf) ctl_free(buf);
  1087. return -1;
  1088. }
  1089. static int rpc_struct_scan(struct rpc_struct_l* s, char* fmt, ...)
  1090. {
  1091. LOG(L_CRIT, "ERROR: binrpc:rpc_struct_scan: not implemented\n");
  1092. return -1;
  1093. };