aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2013-06-28 21:10:52 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2013-06-28 21:10:52 +0000
commitcf647de6a1aa54bfbe0be1c43726d065b436ccac (patch)
treebc0d0aa418cf9b43776e1c313c4ddd6e2e27bddd
parent8ccfc17cf203f7f5d11f15af2ca43ef7fbbdbb14 (diff)
MS: new child
MS: ping child MS: set/get child parameter svn path=/trunk/; revision=50218
-rw-r--r--echld/child.c179
-rw-r--r--echld/common.c83
-rw-r--r--echld/dispatcher.c365
-rw-r--r--echld/echld-int.h16
-rw-r--r--echld/echld-util.h1
-rw-r--r--echld/echld.h1
-rw-r--r--echld/parent.c16
-rw-r--r--echld_test.c98
8 files changed, 486 insertions, 273 deletions
diff --git a/echld/child.c b/echld/child.c
index 5b8e89021f..1823cd2c24 100644
--- a/echld/child.c
+++ b/echld/child.c
@@ -33,7 +33,7 @@ typedef struct _child {
child_state_t state;
int pid;
- int ppid;
+ int dispatcher_pid;
int chld_id;
int reqh_id;
echld_reader_t parent;
@@ -56,36 +56,88 @@ typedef struct _child {
static echld_child_t child;
+struct _st_map {
+ child_state_t id;
+ const char* str;
+};
-#define CHILD_RESP(BYTEARR,TYPE) echld_write_frame(child.fds.pipe_to_parent, BYTEARR, child.chld_id, TYPE, child.reqh_id, NULL)
#ifdef DEBUG_CHILD
-static int dbg_level = DEBUG_CHILD;
+static int debug_lvl = DEBUG_CHILD;
+static FILE* debug_fp = NULL;
+#define DBG_BUF_LEN 1024
+
+#define DCOM()
-void child_debug(int level, const char* fmt, ...) {
+int child_debug(int level, const char* fmt, ...) {
va_list ap;
- char* str;
+ char str[DBG_BUF_LEN];
- if (dbg_level<level) return;
+ if (debug_lvl<level) return 1;
va_start(ap, fmt);
- str = g_strdup_vprintf(fmt,ap);
+ vsnprintf(str,DBG_BUF_LEN,fmt,ap);
va_end(ap);
- fprintf(stderr, "child[%d]: reqh_id=%d dbg_level=%d message='%s'", child.pid, child.reqh_id, level, str);
- g_free(str);
+ fprintf(debug_fp, "child[%d-%d]: reqh_id=%d debug_lvl=%d message='%s'\n",
+ child.chld_id, child.pid, child.reqh_id, level, str);
+
+ return 1;
+}
+
+static char* param_get_dbg_level(char** err _U_) {
+ return g_strdup_printf("%d",debug_lvl);
+}
+
+static echld_bool_t param_set_dbg_level(char* val , char** err ) {
+ char* p;
+ int lvl = (int)strtol(val, &p, 10);
+
+ if (p<=val) {
+ *err = g_strdup("not an integer");
+ return FALSE;
+ } else if (lvl < 0 || lvl > 5) {
+ *err = g_strdup_printf("invalid level=%d (min=0 max=5)",lvl);
+ return FALSE;
+ }
+
+ debug_lvl = lvl;
+ DCOM();
+ return TRUE;
+}
+
+
+static long dbg_resp(GByteArray* em, echld_msg_type_t t) {
+ long st = echld_write_frame(child.fds.pipe_to_parent, em, child.chld_id, t, child.reqh_id, NULL);
+ child_debug(1, "SND fd=%d ch=%d ty='%c' rh=%d msg='%s'",
+ child.fds.pipe_to_parent, child.chld_id, t, child.reqh_id, (st>0?"ok":strerror(errno)) );
+ return st;
}
#define CHILD_DBG(attrs) ( child_debug attrs )
+#define CHILD_DBG_INIT() do { debug_fp = stderr; DCOM(); } while(0)
+#define CHILD_DBG_START(fname) do { debug_fp = fopen(fname,"a"); DCOM(); CHILD_DBG((0,"Log Started")); } while(0)
+#define CHILD_RESP(BA,T) dbg_resp(BA,T)
+#define CHILD_STATE(ST) do { DISP_DBG((0,"State %s => %s")) } while(0)
#else
#define CHILD_DBG(attrs)
+#define CHILD_DBG_INIT()
+#define CHILD_DBG_START(fname)
+#define CHILD_RESP(BA,T) echld_write_frame(child.fds.pipe_to_parent,(BA),child.chld_id,T,child.reqh_id,NULL)
#endif
-void echld_child_initialize(int pipe_from_parent, int pipe_to_parent, int reqh_id) {
+
+static struct timeval close_sleep_time;
+
+void echld_child_initialize(echld_chld_id_t chld_id, int pipe_from_parent, int pipe_to_parent, int reqh_id) {
+
+ close_sleep_time.tv_sec = CHILD_CLOSE_SLEEP_TIME / 1000000;
+ close_sleep_time.tv_usec = CHILD_CLOSE_SLEEP_TIME % 1000000;
+
+ child.chld_id = chld_id;
child.state = IDLE;
child.pid = getpid();
- child.ppid = getppid();
- child.chld_id = 0;
+ child.dispatcher_pid = getppid();
child.reqh_id = reqh_id;
echld_init_reader( &(child.parent), pipe_from_parent,4096);
child.fds.pipe_to_parent = pipe_to_parent;
@@ -93,12 +145,15 @@ void echld_child_initialize(int pipe_from_parent, int pipe_to_parent, int reqh_i
child.fds.pipe_to_dumpcap = -1;
child.fds.file_being_read = -1;
gettimeofday(&child.started,NULL);
- gettimeofday(&child.now,NULL);
+ child.now.tv_sec = child.started.tv_sec;
+ child.now.tv_usec = child.started.tv_usec;
+
echld_get_all_codecs(&(child.enc), &(child.dec), NULL, NULL);
- /* epan stuff */
+ CHILD_DBG_INIT();
+ CHILD_DBG((5,"Child Initialized ch=%d from=%d to=%d rq=%d",chld_id, pipe_from_parent, pipe_to_parent, reqh_id));
- CHILD_DBG((5,"Child Initialized"));
+ /* epan stuff */
}
@@ -253,28 +308,6 @@ static echld_bool_t param_set_cookie(char* val , char** err _U_) {
return TRUE;
}
-#ifdef DEBUG_CHILD
-static char* param_get_dbg_level(char** err _U_) {
- return g_strdup_printf("%d",dbg_level);
-}
-
-static echld_bool_t param_set_dbg_level(char* val , char** err ) {
- char* p;
- int lvl = (int)strtol(val, &p, 10);
-
- if (p<=val) {
- *err = g_strdup("not an integer");
- return FALSE;
- } else if (lvl < 0 || lvl > 5) {
- *err = g_strdup_printf("invalid level=%d (min=0 max=5)",lvl);
- return FALSE;
- }
-
- dbg_level = lvl;
- return TRUE;
-}
-#endif
-
static param_t params[] = {
#ifdef DEBUG_CHILD
@@ -294,14 +327,13 @@ static param_t* get_paramset(char* name) {
}
-
static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data _U_) {
- GByteArray* ba = NULL;
+ GByteArray ba;
+ GByteArray* gba;
- child.chld_id = chld_id;
child.reqh_id = reqh_id;
- CHILD_DBG((2,"Message Received type='%c' len='%d'",type,len));
+ CHILD_DBG((2,"RCVD type='%s' len='%d'",TY(type),len));
// gettimeofday(&(child.now), NULL);
@@ -311,7 +343,7 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
child.chld_id = chld_id;
// more init needed for sure
CHILD_DBG((1,"chld_id set, sending HELLO"));
- CHILD_RESP(ba,ECHLD_HELLO);
+ CHILD_RESP(NULL,ECHLD_HELLO);
return 0;
} else {
child_err(ECHLD_ERR_WRONG_MSG,reqh_id,
@@ -328,15 +360,19 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
switch(type) {
case ECHLD_PING:
+ ba.data = b;
+ ba.len = (guint)len;
CHILD_DBG((1,"PONG"));
- CHILD_RESP(ba,ECHLD_PONG);
+ CHILD_RESP(&ba,ECHLD_PONG);
break;
case ECHLD_SET_PARAM:{
char* param;
char* value;
+
if ( child.dec->set_param && child.dec->set_param(b,len,&param,&value) ) {
param_t* p = get_paramset(param);
char* err;
+
if (!p) {
child_err(ECHLD_CANNOT_SET_PARAM,reqh_id,"no such param='%s'",param);
break;
@@ -353,9 +389,9 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
break;
}
- ba = child.enc->param(param,value);
- CHILD_RESP(ba,ECHLD_PARAM);
- g_byte_array_free(ba,TRUE);
+ gba = child.enc->param(param,value);
+ CHILD_RESP(gba,ECHLD_PARAM);
+ g_byte_array_free(gba,TRUE);
CHILD_DBG((1,"Set Param: param='%s' value='%s'",param,value));
break;
@@ -387,9 +423,9 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
break;
}
- ba = child.enc->param(param,val);
- CHILD_RESP(ba,ECHLD_PARAM);
- g_byte_array_free(ba,TRUE);
+ gba = child.enc->param(param,val);
+ CHILD_RESP(gba,ECHLD_PARAM);
+ g_byte_array_free(gba,TRUE);
CHILD_DBG((2,"Get Param: param='%s' value='%s'",param,val));
break;
} else {
@@ -397,10 +433,9 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
}
}
case ECHLD_CLOSE_CHILD:
- CHILD_RESP(ba,ECHLD_CLOSING);
+ CHILD_RESP(NULL,ECHLD_CLOSING);
CHILD_DBG((3,"Closing"));
-
- // select(0,NULL,NULL,NULL,sleep_time);
+ select(0,NULL,NULL,NULL,&close_sleep_time);
CHILD_DBG((1,"Bye"));
exit(0);
break;
@@ -459,61 +494,67 @@ static void child_read_file(void) {
}
int echld_child_loop(void) {
- int parent_fd = child.fds.pipe_to_parent;
+ int disp_from = child.parent.fd;
+ int disp_to = child.fds.pipe_to_parent;
#ifdef DEBUG_CHILD
int step = 0;
#endif
- CHILD_DBG((0,"child_loop()"));
+ CHILD_DBG((0,"entering child_loop()"));
do {
fd_set rfds;
fd_set wfds;
fd_set efds;
struct timeval timeout;
- int nfds = 0;
-
+ int nfds;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
- FD_SET(parent_fd,&rfds);
+ FD_SET(disp_from,&rfds);
+ FD_SET(disp_from,&efds);
+ FD_SET(disp_to,&efds);
if (child.fds.pipe_from_dumpcap > 0) {
FD_SET(child.fds.pipe_from_dumpcap,&rfds);
- nfds++;
}
if (child.fds.file_being_read > 0) {
FD_SET(child.fds.file_being_read,&rfds);
- nfds++;
}
- CHILD_DBG((4,"child_loop: before select() step=%d",step++));
- nfds = select(nfds, &rfds, &wfds, &efds, &timeout);
- CHILD_DBG((5,"child_loop: after select() step=%d",step++));
+ CHILD_DBG((4,"child_loop: select()ing step=%d",step++));
+ nfds = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout);
+ CHILD_DBG((4,"child_loop: select()ed nfds=%d",nfds));
+
+ if ( FD_ISSET(disp_from,&efds) ) {
+ CHILD_DBG((0,"Broken Parent Pipe 'From' step=%d",step));
+ break;
+ }
- if ( FD_ISSET(parent_fd,&efds) ) {
- CHILD_DBG((0,"Broken Parent Pipe step=%d",step++));
+ if ( FD_ISSET(disp_to,&efds) ) {
+ CHILD_DBG((0,"Broken Parent Pipe 'To' step=%d",step));
break;
}
+
if (child.fds.pipe_from_dumpcap > 0 && FD_ISSET(child.fds.pipe_from_dumpcap,&efds) ) {
- CHILD_DBG((0,"Broken Dumpcap Pipe step=%d",step++));
+ CHILD_DBG((0,"Broken Dumpcap Pipe step=%d",step));
break;
}
+
if (child.fds.file_being_read > 0 && FD_ISSET(child.fds.file_being_read,&efds) ) {
- CHILD_DBG((0,"Broken Readfile Pipe step=%d",step++));
+ CHILD_DBG((0,"Broken Readfile Pipe step=%d",step));
break;
}
- if (FD_ISSET(parent_fd, &rfds)) {
-
+ if (FD_ISSET(disp_from, &rfds)) {
long st = echld_read_frame(&(child.parent), child_receive, &child);
if (st < 0) {
- CHILD_DBG((0,"Read Frame Failed step=%d",step++));
+ CHILD_DBG((0,"Read Frame Failed step=%d",step));
return (int)st;
}
}
diff --git a/echld/common.c b/echld/common.c
index 548fd8127b..20fbe874fc 100644
--- a/echld/common.c
+++ b/echld/common.c
@@ -59,6 +59,89 @@ extern void echld_common_set_dbg(int level, FILE* fp, const char* prefix) {
#endif
+struct _st_map
+{
+ child_state_t id;
+ const char* str;
+};
+
+static struct _st_map st_map[] = {
+ { FREE, "FREE"},
+ { CREATING, "CREATING"},
+ { IDLE, "IDLE"},
+ { READY, "READY"},
+ { READING, "READING"},
+ { CAPTURING, "CAPTURING"},
+ { DONE, "DONE"},
+ { CLOSED, "CLOSED"},
+ { ERRORED, "ERRORED"},
+ {0,NULL}
+};
+
+const char* echld_state_str(child_state_t id) {
+ int i = 0;
+
+ for (;st_map[i].str;i++) {
+ if (id == st_map[i].id) return st_map[i].str;
+ }
+
+ return "UNKNOWN";
+}
+
+
+struct _t_map
+{
+ echld_msg_type_t type;
+ const char* str;
+};
+
+static struct _t_map t_map[] = {
+ {ECHLD_ERROR,"ERROR"},
+ {ECHLD_TIMED_OUT,"TIMED_OUT"},
+ {ECHLD_NEW_CHILD,"NEW_CHILD"},
+ {ECHLD_HELLO,"HELLO"},
+ {ECHLD_CHILD_DEAD,"CHILD_DEAD"},
+ {ECHLD_CLOSE_CHILD,"CLOSE_CHILD"},
+ {ECHLD_CLOSING,"CLOSING"},
+ {ECHLD_SET_PARAM,"SET_PARAM"},
+ {ECHLD_GET_PARAM,"GET_PARAM"},
+ {ECHLD_PARAM,"PARAM"},
+ {ECHLD_PING,"PING"},
+ {ECHLD_PONG,"PONG"},
+ {ECHLD_OPEN_FILE,"OPEN_FILE"},
+ {ECHLD_FILE_OPENED,"FILE_OPENED"},
+ {ECHLD_OPEN_INTERFACE,"OPEN_INTERFACE"},
+ {ECHLD_INTERFACE_OPENED,"INTERFACE_OPENED"},
+ {ECHLD_START_CAPTURE,"START_CAPTURE"},
+ {ECHLD_CAPTURE_STARTED,"CAPTURE_STARTED"},
+ {ECHLD_NOTIFY,"NOTIFY"},
+ {ECHLD_GET_SUM,"GET_SUM"},
+ {ECHLD_PACKET_SUM,"PACKET_SUM"},
+ {ECHLD_GET_TREE,"GET_TREE"},
+ {ECHLD_TREE,"TREE"},
+ {ECHLD_GET_BUFFER,"GET_BUFFER"},
+ {ECHLD_BUFFER,"BUFFER"},
+ {ECHLD_EOF,"EOF"},
+ {ECHLD_STOP_CAPTURE,"STOP_CAPTURE"},
+ {ECHLD_CAPTURE_STOPPED,"CAPTURE_STOPPED"},
+ {ECHLD_ADD_NOTE,"ADD_NOTE"},
+ {ECHLD_NOTE_ADDED,"NOTE_ADDED"},
+ {ECHLD_APPLY_FILTER,"APPLY_FILTER"},
+ {ECHLD_PACKET_LIST,"PACKET_LIST"},
+ {ECHLD_SAVE_FILE,"SAVE_FILE"},
+ {ECHLD_FILE_SAVED,"FILE_SAVED"},
+ {0,NULL}
+};
+
+const char* echld_msg_type_str(echld_msg_type_t id) {
+ int i = 0;
+
+ for (;t_map[i].str;i++) {
+ if (id == t_map[i].type) return t_map[i].str;
+ }
+
+ return "UNKNOWN";
+}
/**
diff --git a/echld/dispatcher.c b/echld/dispatcher.c
index d139c6ac6d..6357c2d49e 100644
--- a/echld/dispatcher.c
+++ b/echld/dispatcher.c
@@ -68,7 +68,7 @@ struct dispatcher* dispatcher;
static int debug_lvl = DEBUG_DISPATCHER;
static FILE* debug_fp = NULL;
-#define DCOM() echld_common_set_dbg(debug_lvl,debug_fp,"Disp")
+#define DCOM() /*echld_common_set_dbg(debug_lvl,debug_fp,"Disp")*/
int dispatcher_debug(int level, const char* fmt, ...) {
va_list ap;
@@ -120,23 +120,38 @@ static long dbg_r = 0;
#define DISP_DBG(attrs) ( dispatcher_debug attrs )
#define DISP_DBG_INIT() do { debug_fp = stderr; DCOM(); } while(0)
#define DISP_DBG_START(fname) do { debug_fp = fopen(fname,"a"); DCOM(); DISP_DBG((0,"Log Started")); } while(0)
-#define DISP_WRITE(FD,BA,CH,T,RH) ( dbg_r = echld_write_frame(FD,BA,CH,T,RH,NULL), DISP_DBG((1,"SND fd=%d ch=%d ty='%c' rh=%d msg='%s'",FD,CH,T,RH, (dbg_r>0?"ok":strerror(errno)))), dbg_r )
+#define DISP_WRITE(FD,BA,CH,T,RH) ( dbg_r = echld_write_frame(FD,BA,CH,T,RH,NULL), DISP_DBG((1,"SND fd=%d ch=%d ty='%s' rh=%d msg='%s'",FD,CH,TY(T),RH, (dbg_r>0?"ok":strerror(errno)))), dbg_r )
+#define CHLD_SET_STATE(c,st) DISP_DBG((1,"Child[%d] State %s => %s",(c)->chld_id,ST((c)->state),ST((c)->state=(st)) ))
#else
#define DISP_DBG(attrs)
#define DISP_DBG_INIT()
#define DISP_DBG_START(fname)
#define DISP_WRITE(FD,BA,CH,T,RH) echld_write_frame(FD,BA,CH,T,RH,NULL)
+#define CHLD_SET_STATE(c,st) ((c)->state=(st))
#endif
#define DISP_RESP(B,T) (DISP_WRITE( dispatcher->parent_out, (B), 0, (T), dispatcher->reqh_id))
+
+static void children_massacre(void) {
+ int i;
+ struct dispatcher_child* cc = dispatcher->children;
+ int max_children = dispatcher->max_children;
+
+ for(i = 0; i < max_children; i++) {
+ struct dispatcher_child* c = &(cc[i]);
+ if (c->pid > 0) {
+ DISP_DBG((0,"killing ch=%d pid=%d",c->chld_id,c->pid));
+ kill(c->pid,SIGTERM);
+ }
+ }
+}
+
+
static void dispatcher_fatal(int cause, const char* fmt, ...) {
size_t len= 1024;
gchar err_str[len];
va_list ap;
- int i;
- struct dispatcher_child* cc = dispatcher->children;
- int max_children = dispatcher->max_children;
va_start(ap, fmt);
g_vsnprintf(err_str,len,fmt,ap);
@@ -144,11 +159,7 @@ static void dispatcher_fatal(int cause, const char* fmt, ...) {
DISP_DBG((0,"fatal cause=%d msg=\"%s\"",cause ,err_str));
- /* the massacre */
- for(i = 0; i < max_children; i++) {
- struct dispatcher_child* c = &(cc[i]);
- if (c->chld_id > 0) kill(c->pid,SIGTERM);
- }
+ children_massacre();
exit(cause);
}
@@ -186,14 +197,14 @@ static char* intflist2json(GList* if_list) {
GSList *addr;
if_addr_t *if_addr;
char addr_str[ADDRSTRLEN];
- GString *str = g_string_new("={ ");
+ GString *str = g_string_new("{ what='interfaces', interfaces={ \n");
char* s;
i = 1; /* Interface id number */
for (if_entry = g_list_first(if_list); if_entry != NULL;
if_entry = g_list_next(if_entry)) {
if_info = (if_info_t *)if_entry->data;
- g_string_append_printf(str,"%d={ intf='%s',", i++, if_info->name);
+ g_string_append_printf(str," %s={ intf='%s',", if_info->name, if_info->name);
/*
* Print the contents of the if_entry struct in a parseable format.
@@ -216,25 +227,27 @@ static char* intflist2json(GList* if_list) {
case IF_AT_IPv4:
if (inet_ntop(AF_INET, &if_addr->addr.ip4_addr, addr_str,
ADDRSTRLEN)) {
- g_string_append_printf(str,"%s", addr_str);
+ g_string_append_printf(str,"'%s',", addr_str);
} else {
- g_string_append(str,"<unknown IPv4>");
+ g_string_append(str,"'<unknown IPv4>',");
}
break;
case IF_AT_IPv6:
if (inet_ntop(AF_INET6, &if_addr->addr.ip6_addr,
addr_str, ADDRSTRLEN)) {
- g_string_append_printf(str,"%s", addr_str);
+ g_string_append_printf(str,"'%s',", addr_str);
} else {
- g_string_append(str,"<unknown IPv6>");
+ g_string_append(str,"'<unknown IPv6>',");
}
break;
default:
- g_string_append_printf(str,"<type unknown %u>", if_addr->ifat_type);
+ g_string_append_printf(str,"'<type unknown %u>',", if_addr->ifat_type);
}
+
}
- g_string_append(str," ]"); /* addrs */
+ g_string_truncate(str,str->len - 1); /* the last comma or space (on empty list) */
+ g_string_append(str," ],"); /* addrs */
if (if_info->loopback)
@@ -242,10 +255,10 @@ static char* intflist2json(GList* if_list) {
else
g_string_append(str,", loopback=0");
- g_string_append(str,"}, ");
+ g_string_append(str,"},\n");
}
- g_string_truncate(str,str->len - 2); /* the comma and space */
+ g_string_truncate(str,str->len - 2); /* the comma and return */
g_string_append(str,"}");
s=str->str;
@@ -259,6 +272,11 @@ static char* param_get_interfaces(char** err) {
char* s;
*err = NULL;
+ if (dispatcher->dumpcap_pid) {
+ *err = g_strdup_printf("Dumpcap already running");
+ return NULL;
+ }
+
if_list = capture_interface_list(&err_no, err, NULL);
if (*err) {
@@ -275,7 +293,7 @@ static char* param_get_interfaces(char** err) {
static struct timeval disp_loop_timeout;
static char* param_get_loop_to(char** err _U_) {
- return g_strdup_printf("%d.%6ds",(int)disp_loop_timeout.tv_sec, (int)disp_loop_timeout.tv_usec );
+ return g_strdup_printf("%d.%06ds",(int)disp_loop_timeout.tv_sec, (int)disp_loop_timeout.tv_usec );
}
static echld_bool_t param_set_loop_to(char* val , char** err ) {
@@ -311,7 +329,8 @@ static param_t* get_paramset(char* name) {
}
-static struct dispatcher_child* dispatcher_get_child(struct dispatcher* d, guint16 chld_id) {
+
+static struct dispatcher_child* dispatcher_get_child(struct dispatcher* d, int chld_id) {
int i;
struct dispatcher_child* cc = d->children;
int max_children = d->max_children;
@@ -326,12 +345,13 @@ static struct dispatcher_child* dispatcher_get_child(struct dispatcher* d, guint
static void dispatcher_clear_child(struct dispatcher_child* c) {
- DISP_DBG((5,"dispatcher_clear_child chld_id=%d",c->chld_id));
echld_reset_reader(&(c->reader), -1, 4096);
- c->chld_id = 0;
- c->write_fd = 0;
- c->pid = 0;
- c->closing = 0;
+ c->chld_id = -1;
+ c->state = FREE;
+ c->reader.fd = -1;
+ c->write_fd = -1;
+ c->pid = -1;
+ c->closing = FALSE;
}
static void set_dumpcap_pid(int pid) {
@@ -356,7 +376,7 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) {
static void dispatcher_clear(void) {
- DISP_DBG((2,"Child chld_id=%d ->CAPTURING"));
+ DISP_DBG((2,"dispatcher_clear"));
/* remove unnecessary stuff for the working child */
}
@@ -415,6 +435,7 @@ void dispatcher_reaper(int sig) {
if (s) g_free(s);
}
+ CHLD_SET_STATE(c,CLOSED);
DISP_WRITE(dispatcher->parent_out, em, c->chld_id, ECHLD_CHILD_DEAD, 0);
dispatcher_clear_child(c);
g_byte_array_free(em,TRUE);
@@ -426,33 +447,21 @@ void dispatcher_reaper(int sig) {
if (pid == dispatcher->dumpcap_pid) {
dispatcher->dumpcap_pid = 0;
dispatcher->reqh_id = reqh_id_save;
+ DISP_DBG((2,"dumpcap dead pid=%d",pid));
return;
}
dispatcher_err(ECHLD_ERR_UNKNOWN_PID, "Unkown child pid: %d", pid);
dispatcher->reqh_id = reqh_id_save;
-
}
-
static void dispatcher_destroy(void) {
- int i;
- int max_children = dispatcher->max_children;
- struct dispatcher_child* cc = dispatcher->children;
/* destroy the dispatcher stuff at closing */
dispatcher->closing = TRUE;
- /* kill all alive children */
- for(i = 0; i < max_children; i++) {
- struct dispatcher_child* c = &(cc[i]);
- if ( c->chld_id ) {
- kill(c->pid,SIGTERM);
- DISP_DBG((1,"Killing chld_id=%d pid=%d"));
- continue;
- }
- }
+ children_massacre();
exit(0);
}
@@ -477,51 +486,34 @@ static long dispatch_to_parent(guint8* b, size_t len, echld_chld_id_t chld_id, e
switch(type) {
case ECHLD_ERROR: break;
case ECHLD_TIMED_OUT: break;
- case ECHLD_HELLO:
- c->state = IDLE;
- DISP_DBG((2,"Child chld_id=%d ->IDLE",c->chld_id));
- break;
- case ECHLD_CLOSING:
- c->closing = TRUE;
- c->state = CLOSED;
- DISP_DBG((2,"Child chld_id=%d ->CLOSED",c->chld_id));
- break;
+ case ECHLD_HELLO: CHLD_SET_STATE(c,IDLE); break;
+ case ECHLD_CLOSING: CHLD_SET_STATE(c,CLOSED); break;
case ECHLD_PARAM: break;
case ECHLD_PONG: break;
- case ECHLD_FILE_OPENED:
- c->state = READING;
- DISP_DBG((2,"Child chld_id=%d ->READING",c->chld_id));
- break;
- case ECHLD_INTERFACE_OPENED:
- c->state = READY;
- DISP_DBG((2,"Child chld_id=%d ->READY",c->chld_id));
- break;
- case ECHLD_CAPTURE_STARTED:
- c->state = CAPTURING;
- DISP_DBG((2,"Child chld_id=%d ->CAPTURING",c->chld_id));
- break;
- case ECHLD_NOTIFY: break; // notify(pre-encoded)
- case ECHLD_PACKET_SUM: break; // packet_sum(pre-encoded)
- case ECHLD_TREE: break; //tree(framenum, tree(pre-encoded) )
- case ECHLD_BUFFER: break; // buffer (name,range,totlen,data)
+ case ECHLD_FILE_OPENED: CHLD_SET_STATE(c,READING); break;
+ case ECHLD_INTERFACE_OPENED: CHLD_SET_STATE(c,READY); break;
+ case ECHLD_CAPTURE_STARTED: CHLD_SET_STATE(c,CAPTURING); break;
+ case ECHLD_NOTIFY: break;
+ case ECHLD_PACKET_SUM: break;
+ case ECHLD_TREE: break;
+ case ECHLD_BUFFER: break;
+
case ECHLD_EOF:
- case ECHLD_CAPTURE_STOPPED:
- c->state = DONE;
- DISP_DBG((2,"Child chld_id=%d ->DONE",c->chld_id));
- break;
+ case ECHLD_CAPTURE_STOPPED: CHLD_SET_STATE(c,DONE); break;
+
case ECHLD_NOTE_ADDED: break;
- case ECHLD_PACKET_LIST: break; // packet_list(name,filter,range);
+ case ECHLD_PACKET_LIST: break;
case ECHLD_FILE_SAVED: break;
default:
goto misbehabing;
}
- DISP_DBG((4,"Dispatching to child reqh_id=%d chld_id=%d type='%c'",reqh_id,c->chld_id,type));
+ DISP_DBG((4,"Dispatching to parent reqh_id=%d chld_id=%d type='%c'",reqh_id,c->chld_id,type));
return DISP_WRITE(dispatcher->parent_out, &in_ba, chld_id, type, reqh_id);
misbehabing:
- c->state = ERRORED;
+ CHLD_SET_STATE(c,ERRORED);
c->closing = TRUE;
kill(c->pid,SIGTERM);
dispatcher_err(ECHLD_ERR_CRASHED_CHILD,"chld_id=%d",chld_id);
@@ -529,65 +521,64 @@ misbehabing:
}
-void dispatch_new_child(struct dispatcher* dd) {
- struct dispatcher_child* c = dispatcher_get_child(dd, 0);
- int reqh_id = dd->reqh_id;
+static struct timeval start_wait_time;
+static long start_wait_time_us = CHILD_START_WAIT_TIME;
+
+static void detach_new_child(enc_msg_t* em, echld_chld_id_t chld_id) {
+ struct dispatcher_child* c;
+ int reqh_id = dispatcher->reqh_id;
int pid;
- if ( c ) {
- int parent_pipe_fds[2];
+ if (( c = dispatcher_get_child(dispatcher, chld_id) )) {
+ dispatcher_err(ECHLD_ERR_CHILD_EXISTS,"chld_id=%d exists already while creating new child",chld_id);
+ return;
+ } else if (( c = dispatcher_get_child(dispatcher, -1) )) {
+ int disp_pipe_fds[2];
int child_pipe_fds[2];
- int pipe_to_parent;
- int pipe_from_parent;
+ int pipe_to_disp;
+ int pipe_from_disp;
int pipe_to_child;
int pipe_from_child;
- DISP_DBG((5,"new_child pipe(parent)"));
- if( pipe(parent_pipe_fds) < 0) {
+ DISP_DBG((5,"new_child pipe(dispatcher)"));
+ if( pipe(disp_pipe_fds) < 0) {
dispatcher_err(ECHLD_ERR_CANNOT_FORK,"CANNOT OPEN PARENT PIPE: %s",strerror(errno));
return;
}
- pipe_from_parent = parent_pipe_fds[0];
- pipe_to_child = parent_pipe_fds[1];
+ pipe_from_disp = disp_pipe_fds[0];
+ pipe_to_child = disp_pipe_fds[1];
DISP_DBG((5,"new_child pipe(child)"));
if( pipe(child_pipe_fds) < 0) {
- close(pipe_from_parent);
+ close(pipe_from_disp);
close(pipe_to_child);
dispatcher_err(ECHLD_ERR_CANNOT_FORK,"CANNOT OPEN CHILD PIPE: %s",strerror(errno));
return;
}
pipe_from_child = child_pipe_fds[0];
- pipe_to_parent = child_pipe_fds[1];
+ pipe_to_disp = child_pipe_fds[1];
DISP_DBG((4,"New Child Forking()"));
switch (( pid = fork() )) {
case -1: {
close(pipe_to_child);
- close(pipe_to_parent);
+ close(pipe_to_disp);
close(pipe_from_child);
- close(pipe_from_parent);
+ close(pipe_from_disp);
dispatcher_err(ECHLD_ERR_CANNOT_FORK,"CANNOT FORK: %s",strerror(errno));
return;
}
- case 0: { /* I'm the child */
- int i;
- int fdt_len = getdtablesize();
-
+ case 0: {
+ /* I'm the child */
dispatcher_clear();
- for(i=0;i<fdt_len;i++) {
- if ( i != pipe_from_parent
- && i != pipe_to_parent
- && i != STDERR_FILENO ) {
- close(i);
- }
- }
+ close(pipe_to_child);
+ close(pipe_from_child);
- echld_child_initialize(pipe_from_parent,pipe_to_parent,reqh_id);
+ echld_child_initialize(chld_id, pipe_from_disp,pipe_to_disp,reqh_id);
exit( echld_child_loop() );
@@ -595,25 +586,28 @@ void dispatch_new_child(struct dispatcher* dd) {
return;
}
default: {
- /* I'm the parent */
- guint8 buf[4];
- GByteArray out_ba;
+ /* I'm the parent */
- out_ba.data = buf;
- out_ba.len = 0;
-
- close(pipe_to_parent);
- close(pipe_from_parent);
+ close(pipe_to_disp);
+ close(pipe_from_disp);
echld_reset_reader(&(c->reader), pipe_from_child,4096);
c->write_fd = pipe_to_child;
c->pid = pid;
- c->chld_id = dispatcher->nchildren++;
+ c->chld_id = chld_id;
+ c->state = CREATING;
+ c->closing = FALSE;
+
+ DISP_DBG((4,"Child Forked pid=%d chld_id=%d from_fd=%d to_fd=%d",
+ pid, c->chld_id, pipe_from_child, pipe_to_child));
- DISP_DBG((4,"Child Forked pid=%d chld_id=%d",pid,c->chld_id));
+ start_wait_time.tv_sec = (int)(start_wait_time_us / 1000000);
+ start_wait_time.tv_usec = (int)(start_wait_time_us % 1000000);
+
+ select(0,NULL,NULL,NULL,&start_wait_time);
/* configure child */
- DISP_WRITE(pipe_to_child, &out_ba, c->chld_id, ECHLD_NEW_CHILD, dispatcher->reqh_id);
+ DISP_WRITE(pipe_to_child, em, c->chld_id, ECHLD_NEW_CHILD, dispatcher->reqh_id);
return;
}
}
@@ -625,29 +619,30 @@ void dispatch_new_child(struct dispatcher* dd) {
/* process signals sent from parent */
-static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data) {
- struct dispatcher* disp = (struct dispatcher*)data;
+static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data _U_) {
+ GByteArray in_ba;
- disp->reqh_id = reqh_id;
+ in_ba.data = b;
+ in_ba.len = (guint)len;
+ dispatcher->reqh_id = reqh_id;
- if (chld_id == 0) { /* these are messages to the dispatcher itself */
- DISP_DBG((2,"Parent => Dispatcher"));
+ DISP_DBG((1,"RCV<- type='%s' chld_id=%d reqh_id=%d",TY(type),chld_id,reqh_id));
+
+ if (chld_id == 0) { /* these are messages sent to the dispatcher itself */
+ DISP_DBG((2,"Message to Dispatcher"));
switch(type) {
case ECHLD_CLOSE_CHILD:
dispatcher_destroy();
return 0;
case ECHLD_PING:
DISP_DBG((2,"PONG reqh_id=%d",reqh_id));
- DISP_WRITE(disp->parent_out, NULL, chld_id, ECHLD_PONG, reqh_id);
- return 0;
- case ECHLD_NEW_CHILD:
- dispatch_new_child(disp);
+ DISP_WRITE(dispatcher->parent_out, NULL, chld_id, ECHLD_PONG, reqh_id);
return 0;
case ECHLD_SET_PARAM:{
char* param;
char* value;
- if ( disp->dec.from_parent->set_param(b,len,&param,&value) ) {
+ if ( dispatcher->dec.from_parent->set_param(b,len,&param,&value) ) {
GByteArray* ba;
param_t* p = get_paramset(param);
char* err;
@@ -667,7 +662,7 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec
return 0;
}
- ba = disp->enc.to_parent->param(param,value);
+ ba = dispatcher->enc.to_parent->param(param,value);
DISP_RESP(ba,ECHLD_PARAM);
g_byte_array_free(ba,TRUE);
DISP_DBG((1,"Set Param: param='%s' value='%s'",param,value));
@@ -681,7 +676,7 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec
case ECHLD_GET_PARAM: {
GByteArray* ba;
char* param;
- if ( disp->dec.from_parent->get_param(b,len,&param) ) {
+ if ( dispatcher->dec.from_parent->get_param(b,len,&param) ) {
char* err;
char* val;
@@ -703,10 +698,10 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec
return 0;
}
- ba = disp->enc.to_parent->param(param,val);
+ ba = dispatcher->enc.to_parent->param(param,val);
DISP_RESP(ba,ECHLD_PARAM);
g_byte_array_free(ba,TRUE);
- DISP_DBG((2,"Get Param: param='%s' value='%s'",param,val));
+ DISP_DBG((1,"Get Param: param='%s' value='%s'",param,val));
return 0;
} else {
dispatcher_err(ECHLD_CANNOT_GET_PARAM,"reason='decoder error'");
@@ -723,58 +718,52 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec
DISP_DBG((2,"Parent => Child"));
if (! (c = dispatcher_get_child(dispatcher, chld_id)) ) {
- dispatcher_err(ECHLD_ERR_NO_SUCH_CHILD, "wrong chld_id %d", chld_id);
- return 0;
- }
-
- switch(type) {
- case ECHLD_CLOSE_CHILD:
- c->closing = TRUE;
- c->state = CLOSED;
- DISP_DBG((2,"Child chld_id=%d ->CLOSED",chld_id));
- goto relay_frame;
-
- case ECHLD_OPEN_FILE:
- c->state = READING;
- DISP_DBG((2,"Child chld_id=%d ->READING",chld_id));
- goto relay_frame;
-
- case ECHLD_OPEN_INTERFACE:
- c->state = READY;
- DISP_DBG((2,"Child chld_id=%d ->READY",chld_id));
- goto relay_frame;
-
- case ECHLD_START_CAPTURE:
- DISP_DBG((2,"Child chld_id=%d ->CAPTURING",chld_id));
- c->state = CAPTURING;
- goto relay_frame;
-
- case ECHLD_STOP_CAPTURE:
- DISP_DBG((2,"Child chld_id=%d ->DONE",chld_id));
- c->state = DONE;
- goto relay_frame;
-
- case ECHLD_SAVE_FILE:
- case ECHLD_APPLY_FILTER:
- case ECHLD_SET_PARAM:
- case ECHLD_GET_PARAM:
- case ECHLD_PING:
- case ECHLD_GET_SUM:
- case ECHLD_GET_TREE:
- case ECHLD_GET_BUFFER:
- case ECHLD_ADD_NOTE:
- relay_frame: {
- GByteArray in_ba;
-
- in_ba.data = b;
- in_ba.len = (guint)len;
-
- DISP_DBG((3,"Relay to Child chld_id=%d type='%c' req_id=%d",chld_id, type, reqh_id));
- return DISP_WRITE(c->write_fd, &in_ba, chld_id, type, reqh_id);
- }
- default:
- dispatcher_err(ECHLD_ERR_WRONG_MSG, "wrong message %d %c", reqh_id, type);
+ if (type == ECHLD_NEW_CHILD) {
+ detach_new_child(&in_ba,chld_id);
+ return 0;
+ } else {
+ dispatcher_err(ECHLD_ERR_NO_SUCH_CHILD, "wrong chld_id %d", chld_id);
return 0;
+ }
+ } else {
+ switch(type) {
+ case ECHLD_CLOSE_CHILD:
+ CHLD_SET_STATE(c,CLOSED);
+ goto relay_frame;
+
+ case ECHLD_OPEN_FILE:
+ CHLD_SET_STATE(c,READING);
+ goto relay_frame;
+
+ case ECHLD_OPEN_INTERFACE:
+ CHLD_SET_STATE(c,READY);
+ goto relay_frame;
+
+ case ECHLD_START_CAPTURE:
+ CHLD_SET_STATE(c,CAPTURING);
+ goto relay_frame;
+
+ case ECHLD_STOP_CAPTURE:
+ CHLD_SET_STATE(c,DONE);
+ goto relay_frame;
+
+ case ECHLD_SAVE_FILE:
+ case ECHLD_APPLY_FILTER:
+ case ECHLD_SET_PARAM:
+ case ECHLD_GET_PARAM:
+ case ECHLD_PING:
+ case ECHLD_GET_SUM:
+ case ECHLD_GET_TREE:
+ case ECHLD_GET_BUFFER:
+ case ECHLD_ADD_NOTE:
+ relay_frame: {
+ DISP_DBG((3,"Relay to Child chld_id=%d type='%c' req_id=%d",chld_id, type, reqh_id));
+ return DISP_WRITE(c->write_fd, &in_ba, chld_id, type, reqh_id);
+ }
+ default:
+ dispatcher_err(ECHLD_ERR_WRONG_MSG, "wrong message %d %c", reqh_id, type);
+ return 0;
+ }
}
}
}
@@ -844,12 +833,18 @@ int dispatcher_loop(void) {
for (c=children; c->pid; c++) {
- if (c->chld_id) {
- // if ( FD_ISSET(c->reader.fd,&efds) ) {
- // DISP_DBG((1,"errored child pipe chld_id=%d",c->chld_id));
- // dispatcher_clear_child(c);
- // continue;
- // }
+ if (c->reader.fd > 0) {
+ if ( FD_ISSET(c->reader.fd,&efds) ) {
+ struct timeval wait_time;
+ wait_time.tv_sec = 0;
+ wait_time.tv_usec = DISP_KILLED_CHILD_WAIT;
+
+ DISP_DBG((1,"errored child pipe chld_id=%d",c->chld_id));
+ kill(c->pid,SIGTERM);
+ select(0,NULL,NULL,NULL,&wait_time);
+ dispatcher_clear_child(c);
+ continue;
+ }
if (FD_ISSET(c->reader.fd,&rfds)) {
long st = echld_read_frame(&(c->reader), dispatch_to_parent, c);
@@ -872,6 +867,7 @@ int dispatcher_loop(void) {
void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, int (*main)(int, char **)) {
static struct dispatcher d;
+ int i;
#ifdef DEBUG_DISPATCHER
int dbg_fd;
#endif
@@ -880,7 +876,6 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, in
disp_loop_timeout.tv_usec = DISPATCHER_WAIT_INITIAL;
DISP_DBG_INIT();
- DISP_DBG_START("dispatcher.debug");
#ifdef DEBUG_DISPATCHER
dbg_fd = fileno(debug_fp);
#endif
@@ -906,6 +901,8 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, in
d.pid = getpid();
d.dumpcap_pid = 0;
+ for (i=0;i<ECHLD_MAX_CHILDREN;i++) dispatcher_clear_child(&(d.children[i]));
+
close(out_pipe_fds[0]);
close(in_pipe_fds[1]);
diff --git a/echld/echld-int.h b/echld/echld-int.h
index bb530fc960..5cdbef2a3a 100644
--- a/echld/echld-int.h
+++ b/echld/echld-int.h
@@ -108,6 +108,10 @@ typedef enum _cst {
ERRORED=-2
} child_state_t;
+extern const char* echld_state_str(child_state_t);
+extern const char* echld_msg_type_str(echld_msg_type_t id);
+#define ST(st) echld_state_str(st)
+#define TY(ty) echld_msg_type_str(ty)
/* these manage the de-framing machine in the receiver side */
typedef struct _echld_reader {
@@ -191,7 +195,7 @@ extern long echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data);
extern long echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data);
-extern void echld_child_initialize(int pipe_from_parent, int pipe_to_parent, int reqh_id);
+extern void echld_child_initialize(echld_chld_id_t chld_id, int pipe_from_parent, int pipe_to_parent, int reqh_id);
extern int echld_child_loop(void);
/* never returns*/
@@ -201,16 +205,20 @@ extern void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* ar
extern void dummy_switch(echld_msg_type_t type);
extern void echld_unused(void);
-/* initial debug levels */
+/* config stuff */
+/* initial debug levels */
+/* undefine to avoid debugging */
#define DEBUG_BASE 5
#define DEBUG_CHILD 5
#define DEBUG_DISPATCHER 5
#define DEBUG_PARENT 5
-/* config stuff */
+/* timers */
#define DISPATCHER_WAIT_INITIAL 999999 /* almost 1s */
-
+#define CHILD_CLOSE_SLEEP_TIME 2000000 /* 2s */
+#define CHILD_START_WAIT_TIME 100000 /* 0.1s */
+#define DISP_KILLED_CHILD_WAIT 100000 /* 0.1s */
/* fatalities */
#define BROKEN_PARENT_PIPE 123
diff --git a/echld/echld-util.h b/echld/echld-util.h
index 4c236b5854..a1a625d570 100644
--- a/echld/echld-util.h
+++ b/echld/echld-util.h
@@ -41,6 +41,7 @@ typedef void (*echild_get_packet_summary_cb_t)(char* summary, void* data);
WS_DLL_PUBLIC echld_state_t echld_open_file(int child_id, const char* filename,echild_get_packet_summary_cb_t,void*);
+
WS_DLL_PUBLIC echld_state_t echld_open_interface(int child_id, const char* intf_name, const char* params);
WS_DLL_PUBLIC echld_state_t echld_start_capture(int child_id, echild_get_packet_summary_cb_t);
WS_DLL_PUBLIC echld_state_t echld_stop_capture(int child_id);
diff --git a/echld/echld.h b/echld/echld.h
index c757760992..23c8f24f7c 100644
--- a/echld/echld.h
+++ b/echld/echld.h
@@ -366,6 +366,7 @@ enum _echld_error {
ECHLD_ERR_UNIMPLEMENTED,
ECHLD_ERR_WRONG_MSG,
ECHLD_ERR_NO_SUCH_CHILD,
+ ECHLD_ERR_CHILD_EXISTS,
ECHLD_ERR_UNKNOWN_PID,
ECHLD_ERR_CANNOT_FORK,
ECHLD_ERR_SET_FILTER,
diff --git a/echld/parent.c b/echld/parent.c
index 6496e4f6e8..6c518907dd 100644
--- a/echld/parent.c
+++ b/echld/parent.c
@@ -90,7 +90,7 @@ static void parent_dbg(int level, const char* fmt, ...) {
}
#define PARENT_DBG(attrs) parent_dbg attrs
-#define PARENT_SEND(BYTEARR,CHILDNUM,TYPE,R_ID) do { long st = echld_write_frame(parent.dispatcher_fd, BYTEARR, CHILDNUM, TYPE, R_ID, NULL); PARENT_DBG((1,"SEND type='%c' chld_id=%d reqh_id=%d msg='%s'",TYPE,CHILDNUM,R_ID, ( st >= 8 ? "ok" : ((st<0)?strerror(errno):"?") ) )); } while(0)
+#define PARENT_SEND(BYTEARR,CHILDNUM,TYPE,R_ID) do { long st = echld_write_frame(parent.dispatcher_fd, BYTEARR, CHILDNUM, TYPE, R_ID, NULL); PARENT_DBG((1,"SEND type='%s' chld_id=%d reqh_id=%d err_msg='%s'",TY(TYPE),CHILDNUM,R_ID, ( st >= 8 ? "ok" : ((st<0)?strerror(errno):"?") ) )); } while(0)
#else
#define PARENT_DBG(attrs)
@@ -221,7 +221,7 @@ void echld_initialize(echld_encoding_t enc, char* argv0, int (*main)(int, char *
reader_realloc_buf = parent_realloc_buff;
#endif
- echld_common_set_dbg(9,stderr,"parent");
+ /* echld_common_set_dbg(9,stderr,"parent"); */
PARENT_DBG((3,"Dispatcher forked"));
@@ -323,7 +323,7 @@ static echld_state_t reqh_snd(echld_t* c, echld_msg_type_t t, GByteArray* ba, ec
PARENT_DBG((4,"reqh_add: idx='%d'",idx));
- PARENT_DBG((1,"REQH_SND: type='%c' chld_id=%d reqh_id=%d",t, c->chld_id,reqh_id));
+ PARENT_DBG((3,"REQH_SND: type='%s' chld_id=%d reqh_id=%d",TY(t), c->chld_id,reqh_id));
PARENT_SEND(ba,c->chld_id,t,reqh_id);
@@ -466,16 +466,16 @@ int chld_cmp(const void *a, const void *b) {
static int msgh_attach(echld_t* c, echld_msg_type_t t, echld_msg_cb_t resp_cb, void* cb_data);
+static int next_chld_id = 1;
+
extern int echld_new(void* child_data) {
- int next_chld_id = 1;
echld_t* c = get_child(-1);
if (!c) return -1;
- c->chld_id = next_chld_id++;
+ c->chld_id = (next_chld_id++);
c->data = child_data;
c->state = CREATING;
- c->handlers = g_array_new(TRUE,TRUE,sizeof(hdlr_t));
g_byte_array_set_size(parent.snd,0);
@@ -484,8 +484,6 @@ extern int echld_new(void* child_data) {
msgh_attach(c,ECHLD_CHILD_DEAD, parent_dead_child , c);
reqh_snd(c, ECHLD_NEW_CHILD, parent.snd, parent_get_hello, c);
- qsort(parent.children,ECHLD_MAX_CHILDREN,sizeof(echld_t),chld_cmp);
-
return c->chld_id;
}
@@ -722,7 +720,7 @@ static long parent_read_frame(guint8* b, size_t len, echld_chld_id_t chld_id, ec
echld_t* c = get_child(chld_id);
GByteArray* ba = g_byte_array_new();
- PARENT_DBG((3,"parent_read_frame ch=%d t='%c' rh=%d",chld_id,t,reqh_id));
+ PARENT_DBG((1,"MSG_IN<- ch=%d t='%s' rh=%d",chld_id,TY(t),reqh_id));
g_byte_array_append(ba,b, (guint)len);
if (c) {
diff --git a/echld_test.c b/echld_test.c
index 8218f80a3c..dd0a6407c3 100644
--- a/echld_test.c
+++ b/echld_test.c
@@ -68,22 +68,27 @@ void ping_cb(long usec, void* data _U_) {
}
}
+int got_param = 0;
+
void param_cb(const char* param, const char* value, const char* error, void* data _U_) {
if (error) {
fprintf(stderr, "Param Set Error msg=%s\n", error );
+ got_param = 0;
return;
}
+ got_param = 1;
fprintf(stderr, "Param: param='%s' val='%s'\n", param, value );
-
}
int main(int argc _U_, char** argv _U_) {
struct timeval tv;
int tot_cycles = 0;
- int max_cycles = 20;
- int npings = 2;
+ int max_cycles = 50;
+ int child = -1;
+ int keep_going = 1;
+
tv.tv_sec = 0;
tv.tv_usec = 250000;
@@ -92,15 +97,94 @@ int main(int argc _U_, char** argv _U_) {
echld_initialize(ECHLD_ENCODING_JSON,argv[0],main);
do {
- if ( (tot_cycles > 2) && npings > 0 && npings-- ) echld_ping(0,ping_cb,NULL);
+ if ( tot_cycles == 2 ) echld_ping(0,ping_cb,NULL);
+
+ if ( tot_cycles == 4 ) {
+ if (pings!=1) {
+ fprintf(stderr, "No Dispatcher PONG 0\n");
+ break;
+ }
+ echld_ping(0,ping_cb,NULL);
+ }
+
+ if ( tot_cycles == 6 ) {
+ if (pings!=2) {
+ fprintf(stderr, "No Dispatcher PONG 1\n");
+ break;
+ }
+
+ echld_set_param(0,"dbg_level","5",param_cb,NULL);
+ }
+
+ if ( tot_cycles == 8) {
+ if (! got_param ) {
+ fprintf(stderr, "Set Dispatcher Param Failed\n");
+ break;
+ }
+
+ echld_get_param(0,"interfaces",param_cb,NULL);
+ }
+
+ if ( tot_cycles == 10) {
+ if (! got_param ) {
+ fprintf(stderr, "Set Dispatcher Param Failed\n");
+ break;
+ }
+
+ child = echld_new(NULL);
+
+ fprintf(stderr, "New chld_id=%d\n",child);
+
+ if (child <= 0) {
+ fprintf(stderr, "No child\n");
+ break;
+ }
+ }
+
+
+ if ( tot_cycles == 16 ) echld_ping(child,ping_cb,NULL);
+
+ if ( tot_cycles == 18 ) {
+ if (pings!=3) {
+ fprintf(stderr, "No Child PONG 0\n");
+ break;
+ }
+ echld_ping(child,ping_cb,NULL);
+ }
+
+
+
+ if ( tot_cycles == 20 ) {
+ if (pings!=4) {
+ fprintf(stderr, "No Child PONG 1\n");
+ break;
+ }
+
+ echld_set_param(child,"cookie","hello-hello",param_cb,NULL);
+ }
+
+
+ if ( tot_cycles == 22 ) {
+ if (!got_param) {
+ fprintf(stderr, "Set Child Param Failed\n");
+ break;
+ }
+
+ echld_get_param(child,"dbg_level",param_cb,NULL);
+ }
- if ( tot_cycles == 10) echld_set_param(0,"dbg_level","5",param_cb,NULL);
+ if ( tot_cycles == 24 ) {
+ if (!got_param) {
+ fprintf(stderr, "Get Child Param Failed\n");
+ break;
+ }
- if ( tot_cycles == 12) echld_get_param(0,"interfaces",param_cb,NULL);
+ keep_going = 0;
+ }
tot_cycles++;
echld_wait(&tv);
- } while( (pings < npings) || (tot_cycles < max_cycles));
+ } while( keep_going && (tot_cycles < max_cycles));
fprintf(stderr, "Done: pings=%d errors=%d tot_cycles=%d\n", pings, errors ,tot_cycles );