@@ -126,6 +126,20 @@
struct event_set_functions func;
};
+typedef enum {
+ EVENT_ARG_MULTI_INSTANCE = 0,
+ EVENT_ARG_LINK_SOCKET,
+} event_arg_t;
+
+/* generic event argument object to pass to event_ctl() */
+struct event_arg
+{
+ event_arg_t type;
+ union {
+ struct multi_instance *mi; /* if type = EVENT_ARG_MULTI_INSTANCE */
+ } u;
+};
+
/*
* maxevents on input: desired max number of event_t descriptors
* simultaneously set with event_ctl
@@ -54,7 +54,6 @@
/*
* Special tags passed to event.[ch] functions
*/
-#define MTCP_SOCKET ((void *)1)
#define MTCP_TUN ((void *)2)
#define MTCP_SIG ((void *)3) /* Only on Windows */
#define MTCP_MANAGEMENT ((void *)4)
@@ -253,7 +252,7 @@
socket_set(mi->context.c2.link_socket,
m->mtcp->es,
mbuf_defined(mi->tcp_link_out_deferred) ? EVENT_WRITE : EVENT_READ,
- mi,
+ &mi->ev_arg,
&mi->tcp_rwflags);
}
}
@@ -263,8 +262,8 @@
struct multi_tcp *mtcp)
{
int status;
- unsigned int *persistent = &mtcp->tun_rwflags;
- socket_set_listen_persistent(c->c2.link_socket, mtcp->es, MTCP_SOCKET);
+ socket_set_listen_persistent(c->c2.link_socket, mtcp->es,
+ &c->c2.link_socket->ev_arg);
#ifdef _WIN32
if (tuntap_is_wintun(c->c1.tuntap))
@@ -280,7 +279,7 @@
persistent = NULL;
}
#endif
- tun_set(c->c1.tuntap, mtcp->es, EVENT_READ, MTCP_TUN, persistent);
+ tun_set(c->c1.tuntap, mtcp->es, EVENT_READ, MTCP_TUN, &mtcp->tun_rwflags);
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
dco_event_set(&c->c1.tuntap->dco, mtcp->es, MTCP_DCO);
#endif
@@ -693,20 +692,43 @@
{
struct event_set_return *e = &mtcp->esr[i];
- /* incoming data for instance? */
+ /* incoming data for instance or listening socket? */
if (e->arg >= MTCP_N)
{
- struct multi_instance *mi = (struct multi_instance *) e->arg;
- if (mi)
+ struct event_arg *ev_arg = (struct event_arg *)e->arg;
+ switch (ev_arg->type)
{
- if (e->rwflags & EVENT_WRITE)
- {
- multi_tcp_action(m, mi, TA_SOCKET_WRITE_READY, false);
- }
- else if (e->rwflags & EVENT_READ)
- {
- multi_tcp_action(m, mi, TA_SOCKET_READ, false);
- }
+ struct multi_instance *mi;
+
+ /* react to event on child instance */
+ case EVENT_ARG_MULTI_INSTANCE:
+ if (!ev_arg->u.mi)
+ {
+ msg(D_MULTI_ERRORS, "MULTI: mtcp_proc_io: null minstance");
+ break;
+ }
+
+ mi = ev_arg->u.mi;
+ if (e->rwflags & EVENT_WRITE)
+ {
+ multi_tcp_action(m, mi, TA_SOCKET_WRITE_READY, false);
+ }
+ else if (e->rwflags & EVENT_READ)
+ {
+ multi_tcp_action(m, mi, TA_SOCKET_READ, false);
+ }
+ break;
+
+ /* new incoming TCP client attempting to connect? */
+ case EVENT_ARG_LINK_SOCKET:
+ ASSERT(m->top.c2.link_socket);
+ socket_reset_listen_persistent(m->top.c2.link_socket);
+ mi = multi_create_instance_tcp(m);
+ if (mi)
+ {
+ multi_tcp_action(m, mi, TA_INITIAL, false);
+ }
+ break;
}
}
else
@@ -731,18 +753,6 @@
multi_tcp_action(m, NULL, TA_TUN_READ, false);
}
}
- /* new incoming TCP client attempting to connect? */
- else if (e->arg == MTCP_SOCKET)
- {
- struct multi_instance *mi;
- ASSERT(m->top.c2.link_socket);
- socket_reset_listen_persistent(m->top.c2.link_socket);
- mi = multi_create_instance_tcp(m);
- if (mi)
- {
- multi_tcp_action(m, mi, TA_INITIAL, false);
- }
- }
#if defined(ENABLE_DCO) && (defined(TARGET_LINUX) || defined(TARGET_FREEBSD))
/* incoming data on DCO? */
else if (e->arg == MTCP_DCO)
@@ -823,6 +823,9 @@
goto err;
}
+ mi->ev_arg.type = EVENT_ARG_MULTI_INSTANCE;
+ mi->ev_arg.u.mi = mi;
+
perf_pop();
gc_free(&gc);
return mi;
@@ -102,6 +102,12 @@
struct schedule_entry se; /* this must be the first element of the structure,
* We cast between this and schedule_entry so the
* beginning of the struct must be identical */
+
+ struct event_arg ev_arg; /**< this struct will store a pointer to either mi or
+ * link_socket, depending on the event type, to keep
+ * it accessible it's placed within the same struct
+ * it points to. */
+
struct gc_arena gc;
bool halt;
int refcount;
@@ -1830,6 +1830,8 @@
ALLOC_OBJ_CLEAR(sock, struct link_socket);
sock->sd = SOCKET_UNDEFINED;
sock->ctrl_sd = SOCKET_UNDEFINED;
+ sock->ev_arg.type = EVENT_ARG_LINK_SOCKET;
+
return sock;
}
@@ -178,6 +178,11 @@
{
struct link_socket_info info;
+ struct event_arg ev_arg; /**< this struct will store a pointer to either mi or
+ * link_socket, depending on the event type, to keep
+ * it accessible it's placed within the same struct
+ * it points to. */
+
socket_descriptor_t sd;
socket_descriptor_t ctrl_sd; /* only used for UDP over Socks */