Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
proxyreq.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdsoap2.h>
20 #include <pthread.h>
21 #include <sys/prctl.h>
22 
23 #include "log.h"
24 #include "monitor.h"
25 #include "proxyreq.h"
26 
30 int proxyreq_handle_request(struct soap *soap,char *svc_name) {
31  struct proxyreq *pr;
32  struct monitor *monitor;
33  int retval;
34  char name[16];
35  int rc;
36 
37  /*
38  * If there is even a possibility that we might proxy the request to
39  * a different thread or process for handling, we have to save off
40  * the request before even beginning to handle it. If the request
41  * is handled in the RPC method, we can just free the proxy request
42  * buf. If, on the other hand, the RPC method signals us that we
43  * have to signal another thread/process to handle the request, we
44  * have to do that.
45  */
46  pr = proxyreq_create(soap);
47 
48  retval = soap_serve(soap);
49 
50  if (retval == SOAP_STOP) {
51  vdebug(8,LA_XML,LF_RPC,"proxying request from %d.%d.%d.%d\n",
52  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
53  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
54 
56 
57  if (soap->error != SOAP_OK) {
58  verror("could not handle SOAP_STOP by proxing request!\n");
59  // XXX: need to send SOAP error!;
60  proxyreq_free(pr);
61  soap_destroy(soap);
62  soap_end(soap);
63  soap_done(soap);
64  free(soap);
65  }
66 
67  /*
68  * Don't destroy the soap context; the monitor thread will
69  * destroy it once it answers the request.
70  */
71  retval = 0;
72  }
73  else if (soap->error == SOAP_OK) {
74  if (pr->monitor && pr->monitor_is_new) {
76  "finished request from %d.%d.%d.%d; new monitor thread %lu\n",
77  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
78  (soap->ip >> 8) & 0xff,soap->ip & 0xff,
79  pr->monitor->mtid);
80 
81  monitor = pr->monitor;
82 
83  snprintf(name,16,"%s_m_%d",svc_name,monitor->objid);
84  prctl(PR_SET_NAME,name,NULL,NULL,NULL);
85 
86  proxyreq_free(pr);
87  soap_destroy(soap);
88  soap_end(soap);
89  soap_done(soap);
90  free(soap);
91 
92  while (1) {
93  rc = monitor_run(monitor);
94  if (rc < 0) {
95  verror("bad internal error in monitor for %s %d; destroying!\n",
96  svc_name,monitor->objid);
97  monitor_destroy(monitor);
98  return -1;
99  }
100  else {
101  if (monitor_is_done(monitor)) {
102  if (!monitor_objects(monitor)) {
103  vdebug(2,LA_XML,LF_RPC,
104  "monitoring on %s %d is done; finalizing!\n",
105  svc_name,monitor->objid);
106  monitor_destroy(monitor);
107  }
108  else {
109  vdebug(2,LA_XML,LF_RPC,
110  "monitoring on %s %d is done;"
111  " shutting down!\n",
112  svc_name,monitor->objid);
113  monitor_shutdown(monitor);
114  monitor->mtid = 0;
115  }
116  return 0;
117  }
118  else {
119  vwarn("%s %d monitor_run returned unexpectedly;"
120  " closing (not finalizing)!\n",
121  svc_name,monitor->objid);
122  monitor_shutdown(monitor);
123  monitor->mtid = 0;
124  return 0;
125  }
126  }
127  }
128 
129  return 0;
130  }
131  else {
132  vdebug(5,LA_XML,LF_RPC,
133  "finished request from %d.%d.%d.%d\n",
134  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
135  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
136  }
137 
138  retval = soap->error;
139 
140  proxyreq_free(pr);
141  soap_destroy(soap);
142  soap_end(soap);
143  soap_done(soap);
144  free(soap);
145  }
146  else {
147  vdebug(8,LA_XML,LF_RPC,"finished request from %d.%d.%d.%d with status %d\n",
148  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
149  (soap->ip >> 8) & 0xff,soap->ip & 0xff,soap->error);
150 
151  retval = soap->error;
152 
153  proxyreq_free(pr);
154  soap_destroy(soap);
155  soap_end(soap);
156  soap_done(soap);
157 
158  free(soap);
159  }
160 
161  return retval;
162 }
163 
168 /*
169  * Saves a request into a buffer for later use. Uses the default gsoap
170  * receiver function to read from the real source during save.
171  *
172  * (gsoap documentation:
173  * Called for all receive operations to fill buffer s of maximum length
174  * n. Should return the number of bytes read or 0 in case of an error,
175  * e.g. EOF. Built-in gSOAP function: frecv)
176  */
177 static size_t _soap_proxyreq_frecv_save(struct soap *soap,char *s,size_t n) {
178  struct proxyreq *pr;
179  size_t retval = 0;
180  char *tmp;
181 
182  pr = (struct proxyreq *)soap->user;
183 
184  if (!pr) {
185  verror("no proxyreq state!\n");
186  return soap_receiver_fault(soap,"Internal error!",
187  "Internal error: no proxyreq state!");
188  }
189 
190  if (!pr->buf) {
191  pr->bufsiz = 4096;
192  pr->buf = malloc(pr->bufsiz);
193  pr->len = 0;
194  pr->bufidx = 0;
195  }
196 
197  retval = pr->orig_frecv(soap,s,n);
198 
199  if (retval > 0) {
200  if (retval > (size_t)(pr->bufsiz - pr->len)) {
201  tmp = malloc(pr->bufsiz + 4096);
202  memcpy(tmp,pr->buf,pr->bufsiz);
203  free(pr->buf);
204  pr->buf = tmp;
205  pr->bufsiz += 4096;
206  }
207  memcpy(&pr->buf[pr->len],s,retval);
208  pr->len += retval;
209  }
210 
211  return retval;
212 }
213 
214 /*
215  * Reads a request from a saved proxy request.
216  */
217 static size_t _soap_proxyreq_frecv_read(struct soap *soap,char *s,size_t n) {
218  struct proxyreq *pr;
219  size_t retval = 0;
220 
221  pr = (struct proxyreq *)soap->user;
222  if (!pr) {
223  verror("no proxyreq!\n");
224  return soap_receiver_fault(soap,"Internal error!",
225  "Internal error: no proxyreq!");
226  }
227 
228  retval = pr->len - pr->bufidx;
229  retval = (n > retval) ? retval : n;
230 
231  if (retval > 0) {
232  memcpy(s,&pr->buf[pr->bufidx],retval);
233 
234  pr->bufidx += retval;
235 
236  soap->error = SOAP_OK;
237  }
238  else {
239  soap->error = SOAP_OK;
240 
242 
243  vdebug(5,LA_XML,LF_RPC,"finished injecting %d bytes!\n",pr->len);
244 
245  /*
246  * Set up for _soap_proxyreq_fsend!
247  *
248  * XXX: free the buf???
249  */
250  pr->buf = NULL;
251  pr->len = pr->bufidx = pr->bufsiz = 0;
252  }
253 
254  return retval;
255 }
256 
257 /*
258  * Sends a whole buffered gsoap response as a proxyreq response.
259  */
260 static int _soap_proxyreq_fsend(struct soap *soap,const char *s,size_t n) {
261  struct proxyreq *pr;
262 
263  pr = (struct proxyreq *)soap->user;
264  if (!pr) {
265  verror("no proxyreq!\n");
266  return soap_receiver_fault(soap,"Internal error!",
267  "Internal error: no proxyreq!");
268  }
269 
270  if (!pr->buf) {
271  pr->bufsiz = (n > 1024) ? n : 1024;
272  pr->buf = malloc(pr->bufsiz);
273  }
274  else if ((unsigned)(pr->bufsiz - pr->len) < n) {
275  pr->bufsiz += ((n - (pr->bufsiz - pr->len)) > 1024) \
276  ? n - (pr->bufsiz - pr->len) : 1024;
277  if (!realloc(pr->buf,pr->bufsiz)) {
278  verror("could not increase buf from %d to %d!\n",pr->len,pr->bufsiz);
279  free(pr->buf);
280  pr->bufidx = pr->bufsiz = pr->len = 0;
281  return SOAP_EOF;
282  }
283  }
284 
285  memcpy(pr->buf + pr->len,s,n);
286  pr->len += n;
287 
288  return 0;
289 }
290 
291 static int _soap_proxyreq_noclose(struct soap *soap) {
292  return SOAP_OK;
293 }
294 
298 struct proxyreq *proxyreq_create(struct soap *soap) {
299  struct proxyreq *pr;
300 
301  if (soap->user) {
302  verror("soap->user already set; already proxied this request?!\n");
303  return NULL;
304  }
305 
306  pr = calloc(1,sizeof(*pr));
307 
308  pr->tid = pthread_self();
310  pr->soap = soap;
311 
312  soap->user = pr;
313 
314  /*
315  * Adjust soap struct to save off the request as it processes it the
316  * first time.
317  */
318  pr->orig_frecv = soap->frecv;
319  soap->frecv = _soap_proxyreq_frecv_save;
320 
321  pr->orig_fclose = soap->fclose;
322  soap->fclose = _soap_proxyreq_noclose;
323 
324  /*
325  * Note: we do not have to worry about the gsoap sock; it is already
326  * set CLOEXEC, so we can fork safely if we need to.
327  */
328 
329  return pr;
330 }
331 
332 struct proxyreq *proxyreq_create_proxied(int objid,char *buf,int buflen) {
333  struct proxyreq *pr;
334  struct soap *soap;
335  struct monitor *monitor = NULL;
336 
337  if (!monitor_lookup_objid(objid,NULL,NULL,&monitor)) {
338  verror("no monitor for object %d!\n",objid);
339  return NULL;
340  }
341 
342  soap = calloc(1,sizeof(*soap));
343  soap_init(soap);
344  //soap->error = SOAP_OK;
345 
346  pr = calloc(1,sizeof(*pr));
347 
348  pr->monitor = monitor;
349  pr->tid = pthread_self();
351  pr->soap = soap;
352 
353  pr->objid = objid;
354 
355  pr->buf = buf;
356  pr->len = buflen;
357  pr->bufsiz = buflen;
358  pr->bufidx = 0;
359 
360  soap->user = pr;
361 
362  /*
363  * Adjust soap struct to replay the request as it processes it the
364  * "second" time.
365  */
366  pr->orig_frecv = soap->frecv;
367  soap->frecv = _soap_proxyreq_frecv_read;
368 
369  /*
370  * Adjust soap struct to send a proxyreq response when it finishes.
371  * Also, force it to buffer the response internally before sending
372  * anything. This ensures we send a complete response, which is
373  * what we want to do. Wait, this doesn't work; even SOAP_IO_STORE
374  * buffering results in two part msgs: the HTTP header, and the
375  * content :(. Still buffer internally to avoid lots of
376  * mallocs/memcpys hopefully, but this stinks a bit.
377  */
378  pr->orig_fsend = pr->soap->fsend;
379  pr->soap->fsend = _soap_proxyreq_fsend;
380 
381  /* Force it to buffer internally. */
382  soap_set_omode(pr->soap,SOAP_IO_STORE);
383 
384  return pr;
385 }
386 
389 
390  /*
391  * Adjust soap struct to replay the request as it processes it the
392  * "second" time.
393  */
394  pr->orig_frecv = pr->soap->frecv;
395  pr->soap->frecv = _soap_proxyreq_frecv_read;
396 
397  return 0;
398 }
399 
400 int proxyreq_attach_objid(struct proxyreq *pr,int objid) {
401  if (pr->monitor) {
402  verror("proxyreq already attached to a monitor!\n");
403  return SOAP_ERR;
404  }
405 
406  if (!monitor_lookup_objid(objid,NULL,NULL,&pr->monitor)) {
407  verror("no monitor for object %d!\n",objid);
408  return SOAP_ERR;
409  }
410 
411  /*
412  * We save off the object separately in case the monitor disappears
413  * asynchronous w.r.t. our functions; this helps us avoid locking
414  * the monitor's (and the global monitor lock).
415  */
416  pr->objid = objid;
417 
418  return SOAP_OK;
419 }
420 
422  struct monitor *monitor) {
423  if (pr->monitor) {
424  verror("proxyreq already attached to a monitor!\n");
425  return SOAP_ERR;
426  }
427 
428  pr->monitor = monitor;
429  /*
430  * We save off the object separately in case the monitor disappears
431  * asynchronous w.r.t. our functions; this helps us avoid locking
432  * the monitor's (and the global monitor lock).
433  */
434  pr->objid = objid;
435 
436  pr->monitor_is_new = 1;
437 
438  return SOAP_OK;
439 }
440 
441 /*
442  * Msg commands.
443  */
444 #define PROXYREQ_REQUEST 1
445 #define PROXYREQ_RESPONSE 2
446 
448  struct monitor *monitor;
449  int rc;
450  struct monitor_msg *msg;
451 
452  if (pr->state != PROXYREQ_STATE_BUFFERED) {
453  verror("request in bad state %d!\n",pr->state);
454  errno = EINVAL;
455  return SOAP_ERR;
456  }
457 
458  monitor = pr->monitor;
459 
460  /*
461  * This is tricky. We NULL out the buffer in pr once the message
462  * has been created. Then once the message is sent, we fully free
463  * the msg, which frees the original request buffer. We have to do
464  * it in this sequence because if we tried to alter the proxyreq
465  * *after* sending, and the child happens to respond to it first, it
466  * could get overwritten before we can free it. Of course, that is
467  * all but impossible, but we're careful.
468  */
469  /*
470  * Also, if it is unidirectional, assume that the child can access
471  * @pr in its address space, so don't send the request over the
472  * pipe; trust that it can retrieve pr as a msg_obj later.
473  */
474  if (monitor->type == MONITOR_TYPE_THREAD) {
476  0,NULL,pr);
477  }
478  else {
479  /*
480  * Associate pr as the "msg_obj" in the monitor's hashtable, for
481  * later use.
482  */
484  pr->len,pr->buf,pr);
485 
486  pr->buf = NULL;
487  pr->len = pr->bufsiz = pr->bufidx = 0;
488  }
489 
490  rc = monitor_send(msg);
491 
492  /* This results in the buffer being freed for msgs to
493  * MONITOR_TYPE_PROCESS monitored children;
494  * in the other case, we assume that whoever uses @pr (the receiver
495  * of our 0-len notification msg will free it).
496  */
497  monitor_msg_free(msg);
498 
499  if (rc) {
500  verror("could not send msg to monitored child!\n");
501  return SOAP_ERR;
502  }
503 
504  return SOAP_OK;
505 }
506 
508  struct monitor *monitor;
509  int rc;
510  struct monitor_msg *msg;
511 
512  if (pr->state != PROXYREQ_STATE_SERVING) {
513  verror("request in bad state %d!\n",pr->state);
514  errno = EINVAL;
515  return SOAP_ERR;
516  }
517 
518  monitor = pr->monitor;
519 
520  if (!(monitor->flags & MONITOR_FLAG_BIDI)) {
521  verror("monitor is not bidirectional!\n");
522  errno = EINVAL;
523  return SOAP_ERR;
524  }
525 
526  /*
527  * We just send the contents of pr->buf using pr->len as the
528  * length. WE DO NOT FREE THE BUFFER -- we just null them out.
529  * It's the caller's job to handle that.
530  *
531  * DO NOT associate pr as the "msg_obj" in the monitor's hashtable;
532  * there is no later use. If we ever did need to send chunked
533  * messages, this would be how we would do it.
534  */
536  pr->len,pr->buf,NULL);
537 
538  rc = monitor_child_send(msg,monitor);
540 
541  if (rc) {
542  verror("could not send msg to monitor!\n");
543  return SOAP_ERR;
544  }
545 
546  pr->buf = NULL;
547  pr->len = pr->bufsiz = pr->bufidx = 0;
548 
549  return SOAP_OK;
550 }
551 
553  struct proxyreq *pr;
554  struct soap *soap;
555 
556  if (!(pr = (struct proxyreq *)msg->msg_obj)) {
557  pr = proxyreq_create_proxied(msg->objid,msg->msg,msg->len);
558  /* Steal the message's buf in proxyreq_create_proxied. */
559  msg->len = 0;
560  msg->msg = NULL;
561 
562  soap = pr->soap;
563 
565  pr->msg_id = msg->id;
566 
567  soap_serve(soap);
568 
569  /* XXX: get rid of these! They pollute child STDERR! */
570  if (soap->error == SOAP_OK) {
571  vdebug(5,LA_XML,LF_RPC,
572  "finished forked proxied request from %d.%d.%d.%d\n",
573  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
574  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
575  }
576  else {
577  vdebug(5,LA_XML,LF_RPC,
578  "failingly finished forked proxied request from %d.%d.%d.%d\n",
579  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
580  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
581  }
582 
584  }
585  else {
586  /* Use the soap struct in the existing proxyreq. */
587  soap = pr->soap;
588 
590 
592 
593  soap_serve(soap);
594 
595  if (soap->error == SOAP_OK) {
596  vdebug(5,LA_XML,LF_RPC,
597  "finished threaded proxied request from %d.%d.%d.%d\n",
598  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
599  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
600  }
601  else {
602  vdebug(5,LA_XML,LF_RPC,
603  "failingly finished threaded proxied request from %d.%d.%d.%d\n",
604  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
605  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
606  }
607  }
608 
609  //monitor_msg_free(msg);
610 
611  proxyreq_free(pr);
612 
613  soap_destroy(soap);
614  soap_end(soap);
615  soap_done(soap);
616  free(soap);
617 
618  return 0;
619 }
620 
622  struct proxyreq *pr;
623  struct soap *soap;
624  char buf[16];
625  char *sptr;
626  int rc;
627 
628  if (!(pr = (struct proxyreq *)msg->msg_obj)) {
629  verror("cannot associated a proxyreq request handler thread with monitor child msg!\n");
630  return SOAP_ERR;
631  }
632 
633  /*
634  * We're in the monitor thread now; our original request thread
635  * returned after it proxied the request.
636  *
637  * XXX: should have a thread pool for responses so we don't
638  * block the main monitor thread on a response...
639  */
640 
641  soap = pr->soap;
642 
643  /* Dump out the soap response. */
644  soap_begin_send(soap);
645 
646  /*
647  * NB: if the monitor is a process monitor, the underlying gSOAP will
648  * not have a valid socket, and it will respond in CGI mode. So,
649  * the first line will *not* be "HTTP/1.x ..."; it will be "Status: ...".
650  * We need to fix this up. So, just take the http_version of the
651  * original request, and splat it in :).
652  */
653  if (strncmp(msg->msg,"Status:",7) == 0) {
654  sptr = msg->msg + 7;
655  rc = snprintf(buf,16,"HTTP/%s",soap->http_version);
656  soap_send_raw(soap,buf,rc);
657  }
658  else
659  sptr = msg->msg;
660 
661  /* Then only send the part of msg->msg we care about. */
662  soap_send_raw(soap,sptr,msg->len - (sptr - msg->msg));
663 
664  soap_end_send(soap);
665  soap_closesock(soap);
666 
667  if (soap->error == SOAP_OK) {
668  vdebug(5,LA_XML,LF_RPC,
669  "finished proxied request from %d.%d.%d.%d\n",
670  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
671  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
672  }
673  else {
674  vdebug(5,LA_XML,LF_RPC,
675  "failingly finished proxy request from %d.%d.%d.%d\n",
676  (soap->ip >> 24) & 0xff,(soap->ip >> 16) & 0xff,
677  (soap->ip >> 8) & 0xff,soap->ip & 0xff);
678  }
679 
680  monitor_msg_free(msg);
681 
682  proxyreq_free(pr);
683 
684  soap_destroy(soap);
685  soap_end(soap);
686  soap_done(soap);
687  free(soap);
688 
689  return 0;
690 }
691 
692 void proxyreq_detach_soap(struct proxyreq *pr) {
693  if (!pr->soap)
694  return;
695 
696  if (pr->orig_frecv) {
697  pr->soap->frecv = pr->orig_frecv;
698  pr->orig_frecv = NULL;
699  }
700 
701  if (pr->orig_fclose) {
702  pr->soap->fclose = pr->orig_fclose;
703  pr->orig_fclose = NULL;
704  }
705 }
706 
707 void proxyreq_free_buffer(struct proxyreq *pr) {
708  if (pr->buf) {
709  free(pr->buf);
710  pr->buf = NULL;
711  pr->len = 0;
712  pr->bufsiz = 0;
713  pr->bufidx = 0;
714  }
715 }
716 
717 void proxyreq_free(struct proxyreq *pr) {
718 
719  if (pr->soap)
721 
723 
724  pr->tid = -1;
725  pr->monitor = NULL;
726  pr->objid = -1;
727 
728  free(pr);
729 }
730 
731 
732 /*
733  * "Call" in the RPC once you know if you would proxy or not. Calls
734  * either splitreq_split or splitreq_fini().
735  */
736 #define THREAD_SPLITREQ(soap,tm) { \
737  struct splitreq *_sr; \
738  _sr = (struct splitreq *)(soap)->user; \
739  if (!_sr) { \
740  verror("no splitreq state!\n"); \
741  return SOAP_ERR; \
742  } \
743  if ((soap)->frecv == splitreq_frecv_save) { \
744  splitreq_split((soap),0); \
745  /* XXX: normally have to queue for thread or send to pid */ \
746  return SOAP_STOP; \
747  } \
748  else if ((soap)->frecv == splitreq_frecv_read) { \
749  splitreq_fini(soap); \
750  /* Caller normally executes RPC here... */ \
751  } \
752  else { \
753  verror("unexpected soap->frecv value; user error?!\n"); \
754  return SOAP_ERR; \
755  } \
756 }
757 #define FORK_SPLITREQ(soap,tm) { \
758  struct splitreq *_sr; \
759  struct splitreq_data srd; \
760  \
761  _sr = (struct splitreq *)(soap)->user; \
762  if (!_sr) { \
763  verror("no splitreq state!\n"); \
764  return SOAP_ERR; \
765  } \
766  if ((soap)->frecv == splitreq_frecv_save) { \
767  splitreq_split((soap),1); \
768  _srd.buf = _sr->buf; \
769  _srd.buflen = _sr->buflen; \
770  if (process_monitor_send_request(tm,&srd)) { \
771  verror("could not send request to pid %d",tm->p.pid); \
772  return SOAP_ERR; \
773  } \
774  else \
775  return SOAP_STOP; \
776  } \
777  else if ((soap)->frecv == splitreq_frecv_read) { \
778  splitreq_fini(soap); \
779  /* Caller normally executes RPC here... */ \
780  } \
781  else { \
782  verror("unexpected soap->frecv value; user error?!\n"); \
783  return SOAP_ERR; \
784  } \
785 }
void monitor_msg_free_save_buffer(struct monitor_msg *msg)
Definition: monitor.c:2521
int proxyreq_recv_request(struct monitor *monitor, struct monitor_msg *msg)
Definition: proxyreq.c:552
proxyreq_state_t state
Definition: proxyreq.h:129
int monitor_objects(struct monitor *monitor)
Definition: monitor.c:2251
#define PROXYREQ_REQUEST
Definition: proxyreq.c:444
int proxyreq_attach_objid(struct proxyreq *pr, int objid)
Definition: proxyreq.c:400
#define PROXYREQ_RESPONSE
Definition: proxyreq.c:445
int bufidx
Definition: proxyreq.h:179
struct monitor_msg * monitor_msg_create(int objid, int id, short cmd, short seqno, int buflen, char *buf, void *msg_obj)
Definition: monitor.c:2525
struct monitor * monitor
Definition: proxyreq.h:136
int monitor_is_done(struct monitor *monitor)
Definition: monitor.c:2224
int objid
Definition: monitor.h:335
struct monitor * monitor
char * msg
Definition: monitor.h:352
int monitor_send(struct monitor_msg *msg)
Definition: monitor.c:2607
monitor_type_t type
Definition: monitor.h:175
struct soap * soap
Definition: proxyreq.h:160
uint8_t monitor_is_new
Definition: proxyreq.h:157
#define verror(format,...)
Definition: log.h:30
int objid
Definition: monitor.h:243
int proxyreq_attach_new_objid(struct proxyreq *pr, int objid, struct monitor *monitor)
Definition: proxyreq.c:421
#define vwarn(format,...)
Definition: log.h:33
void free(void *ptr)
Definition: debugserver.c:207
int proxyreq_switchto_proxied(struct proxyreq *pr)
Definition: proxyreq.c:387
int len
Definition: proxyreq.h:177
int objid
Definition: proxyreq.h:142
int monitor_child_send(struct monitor_msg *msg, struct monitor *monitor)
Definition: monitor.c:2798
Definition: log.h:203
void proxyreq_detach_soap(struct proxyreq *pr)
Definition: proxyreq.c:692
int(* orig_fsend)(struct soap *soap, const char *s, size_t n)
Definition: proxyreq.h:171
int proxyreq_send_response(struct proxyreq *pr)
Definition: proxyreq.c:507
int bufsiz
Definition: proxyreq.h:178
pthread_t mtid
Definition: monitor.h:180
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
void * realloc(void *ptr, size_t size)
Definition: debugserver.c:221
void monitor_msg_free(struct monitor_msg *msg)
Definition: monitor.c:2515
Definition: log.h:72
#define PROXY_REQUEST_HANDLE_STOP(soap)
Definition: proxyreq.h:337
int(* orig_fclose)(struct soap *soap)
Definition: proxyreq.h:169
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
unsigned long tid
Definition: proxyreq.h:127
int monitor_shutdown(struct monitor *monitor)
Definition: monitor.c:947
int proxyreq_handle_request(struct soap *soap, char *svc_name)
Definition: proxyreq.c:30
monitor_flags_t flags
Definition: monitor.h:177
int msg_id
Definition: proxyreq.h:143
size_t(* orig_frecv)(struct soap *soap, char *s, size_t n)
Definition: proxyreq.h:167
int monitor_lookup_objid(int objid, int *objtype, void **obj, struct monitor **monitor)
Definition: monitor.c:219
int proxyreq_recv_response(struct monitor *monitor, struct monitor_msg *msg)
Definition: proxyreq.c:621
void proxyreq_free_buffer(struct proxyreq *pr)
Definition: proxyreq.c:707
void * malloc(size_t size)
Definition: debugserver.c:214
struct proxyreq * proxyreq_create(struct soap *soap)
Definition: proxyreq.c:298
int proxyreq_send_request(struct proxyreq *pr)
Definition: proxyreq.c:447
int monitor_destroy(struct monitor *monitor)
Definition: monitor.c:1039
void proxyreq_free(struct proxyreq *pr)
Definition: proxyreq.c:717
int monitor_run(struct monitor *monitor)
Definition: monitor.c:2274
struct proxyreq * proxyreq_create_proxied(int objid, char *buf, int buflen)
Definition: proxyreq.c:332
void * msg_obj
Definition: monitor.h:364
char * buf
Definition: proxyreq.h:176