PERFORCE change 125284 for review
Matus Harvan
mharvan at FreeBSD.org
Fri Aug 17 19:37:01 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125284
Change 125284 by mharvan at mharvan_bike-planet on 2007/08/18 02:36:44
plugin_icmp works correctly with multi-user support
Affected files ...
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.c#4 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.h#3 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin.h#7 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_icmp.c#10 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_tcp.c#12 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_udp.c#10 edit
Differences ...
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.c#4 (text+ko) ====
@@ -35,7 +35,7 @@
/* max transfered unit - encapsulated packet size */
#define MTU 1500
/* how many pings can fail before the plugin is declared broken */
-#define PING_INTERVAL 2
+#define PING_INTERVAL 5
#define PING_FAIL_PLUGIN 3
#define PING_FAIL_COMPLETE 10
#define IDREQUEST_RETRIES 3
@@ -100,7 +100,8 @@
/*
* Pass data received from the tun interface to the daemon.
*/
-static int process_data_from_tun(struct client *cl,char *data, int len);
+static int process_data_from_tun(struct client *cl, struct plugin *pl,
+ uint8_t dispatch, char *data, int len);
static int send_next_frag();
static void cleanup();
@@ -231,7 +232,8 @@
do {
nread = tun_read(cl->tun_fd, packet, PACKETLEN);
if (nread > 0) {
- nwrite = process_data_from_tun(cl, packet, nread);
+ nwrite = process_data_from_tun(cl, cl->pl,
+ DISPATCH_DATA, packet, nread);
}
/* continue the loop if we read something
* and the plugin has sent it immediately
@@ -845,6 +847,13 @@
break;
+ case DISPATCH_PLUGIN_DATA:
+ printf("process_data_from_plugin(): PLUGIN_DATA\n");
+ pl->conn_map(pl, *clid, CONN_TEMP);
+ pl->custom_receive(pl, 0, data + 1, len - 1);
+
+ break;
+
default:
fprintf(stderr, "unknown dispatch 0x%X in data from plugin "
"%s\n", dispatch, pl->name);
@@ -856,30 +865,34 @@
* Pass data received from the tun interface to the daemon.
*/
static int
-process_data_from_tun(struct client *cl, char *data, int len)
+process_data_from_tun(struct client *cl, struct plugin *pl, uint8_t dispatch,
+ char *data, int len)
{
char ldata[MTU+3];
- if (cl->pl == NULL) {
+ if (pl == NULL)
+ pl = cl->pl;
+
+ if (pl == NULL) {
debug("no plugin connected yet, discarding tun data\n");
- plugin_report(cl->pl, cl->clid, REPORT_BOOTSTRAP);
+ plugin_report(pl, cl->clid, REPORT_BOOTSTRAP);
return SEND_ERROR;
}
- printf("process_data_from_tun: len: %d, cl->pl->mtu: %d\n",
- len, cl->pl->mtu);
+ printf("process_data_from_tun: len: %d, pl->mtu: %d\n",
+ len, pl->mtu);
/* no need to add the fragmentation header */
- if (len < cl->pl->mtu) {
+ if (len < pl->mtu || dispatch == DISPATCH_PLUGIN_DATA) {
if (server) {
- *(ldata) = DISPATCH_DATA;
+ *(ldata) = dispatch;
memcpy(ldata + 1, data, min(sizeof(ldata)-1, len));
- return (cl->pl->send(cl->pl, cl->clid, ldata,
+ return (pl->send(pl, cl->clid, ldata,
min(sizeof(ldata), len + 1), NORMAL_DATA));
} else { /* client */
*ldata = myclid;
- *(ldata + 1) = DISPATCH_DATA;
+ *(ldata + 1) = dispatch;
memcpy(ldata+2, data, min(sizeof(ldata)-2, len));
- return (cl->pl->send(cl->pl, myclid, ldata,
+ return (pl->send(pl, myclid, ldata,
min(sizeof(ldata), len + 2), NORMAL_DATA));
}
/* add the fragmentation header */
@@ -909,6 +922,14 @@
}
}
+int
+plugin_custom_send(struct plugin *pl, uint8_t clid,
+ char *data, int len)
+{
+ return process_data_from_tun(&clients[clid], pl, DISPATCH_PLUGIN_DATA,
+ data, len);
+}
+
/* send the next fragment */
static int
send_next_frag(struct client *cl)
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.h#3 (text+ko) ====
@@ -32,6 +32,7 @@
int (*is_ready_to_send)(struct plugin*, uint8_t);
void (*conn_close)(struct plugin*, uint8_t);
void (*conn_map)(struct plugin*, uint8_t, int);
+ void (*custom_receive)(struct plugin*, uint8_t, char*, int);
char *name;
int mtu;
void* data;
@@ -81,9 +82,10 @@
DISPATCH_ECHO_REQUEST = 1,
DISPATCH_ECHO_REPLY = 2,
DISPATCH_FRAG = 3,
- DISPATCH_ID_REQUEST, /* client requesting an ID */
- DISPATCH_ID_OFFER, /* daemon offering an ID to the client */
- //DISPATCH_ID_CANCEL, /* client ending a session */
+ DISPATCH_ID_REQUEST, /* client requesting an ID */
+ DISPATCH_ID_OFFER, /* daemon offering an ID to the client */
+ //DISPATCH_ID_CANCEL, /* client ending a session */
+ DISPATCH_PLUGIN_DATA, /* plugin to plugin communication */
DISPATCH_DATA = 0x42,
DIPATCH_PLUGIN_RESERVED_MIN = 128, /* dispatch values used by plugins, */
DIPATCH_PLUGIN_RESERVED_MAX = 255, /* i.e., not passed to the daemon */
@@ -112,6 +114,8 @@
*/
void plugin_report(struct plugin *pl, uint8_t clid, int err);
+int plugin_custom_send(struct plugin *pl, uint8_t clid, char *data, int len);
+
extern int server; /* are we a server (0) or a client (1)? */
#endif
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin.h#7 (text+ko) ====
@@ -84,6 +84,11 @@
int plugin_send(struct plugin *pl, uint8_t clid,
char *data, int len, int data_type);
+/*
+ * Data for the plugin from plugin to plugin communication.
+ */
+void
+plugin_custom_receive(struct plugin *pl, uint8_t clid,
+ char *data, int len);
#endif
-
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_icmp.c#10 (text+ko) ====
@@ -85,6 +85,9 @@
};
+static void plugin_send_queued_data();
+static void plugin_send_empty_request(struct plugin *pl, struct conn *conn);
+
static u_int16_t
in_cksum(u_int16_t *addr, int len)
{
@@ -146,6 +149,7 @@
pl->receive = plugin_receive;
pl->conn_close = plugin_conn_close;
pl->conn_map = plugin_conn_map;
+ pl->custom_receive = plugin_custom_receive;
pl->data = malloc(sizeof(struct plugin_icmp_data));
if (!pl->data) {
@@ -179,7 +183,7 @@
evtimer_add(ev, &tv);
}
-/* handler function for the libevent timer event */
+/* handler function for the libevent timer event - client only */
void
plugin_icmp_timer_ev_handler(int fd, short ev_type, void *arg)
{
@@ -187,7 +191,8 @@
/* send a request to the server */
if (server == 0) { /* client */
- plugin_receive(data->fd, EV_TIMEOUT, arg);
+ plugin_send_empty_request(arg, data->conn);
+ //plugin_receive(data->fd, EV_TIMEOUT, arg);
}
/* register a timer event again */
@@ -303,8 +308,7 @@
}
static int
-send_icmp_pkt(struct plugin *pl, struct conn *conn,
- int id, int seq, char *data, int len)
+send_icmp_pkt(struct plugin *pl, struct conn *conn, char *data, int len)
{
struct plugin_icmp_data *datapl = pl->data;
int n = 0;
@@ -330,8 +334,8 @@
}
icmp->code = 0;
- icmp->id = htons(id);
- icmp->seq = htons(seq);
+ icmp->id = htons(conn->id);
+ icmp->seq = htons(conn->seq);
icmp->cksum = 0;
icmp->cksum = in_cksum((u_int16_t*)packet,
sizeof(struct my_icmp_hdr) + len);
@@ -343,8 +347,15 @@
fprintf(stderr, "plugin_send: send returned %d\n", n);
/* the client has to reset the timer for keep-alive requests */
- if (!server) /* client */
+ if (!server) { /* client */
+ /* increment the sequence number */
+ if (conn->seq == 65535)
+ conn->seq = 0;
+ else
+ conn->seq++;
+
register_timer_ev(&datapl->timer_ev);
+ }
return n;
}
@@ -370,7 +381,7 @@
(struct sockaddr *) &from, &fromlen);
if (n == -1) {
if (errno == EAGAIN)
- return;
+ goto send_request;
warn("plugin_cimp: plugin_receive(): recvfrom() returned %d",
n);
@@ -406,7 +417,9 @@
icmp = (void*)packetp;
packetp += sizeof(struct my_icmp_hdr);
n -= sizeof(struct my_icmp_hdr);
-
+ data->conn->id = ntohs(icmp->id);
+ data->conn->seq = ntohs(icmp->seq);
+
/* check values in the ICMP header */
if (server) {
if (icmp->type != ICMP_ECHO) // or 123
@@ -416,53 +429,24 @@
goto pkt_not_for_us;
}
- if (n <= 0)
- return;
-
/* payload */
data->conn->data_sent_after_last_receive = 0;
- process_data_from_plugin(pl, packetp, n, &clid, &conn_flag);
+ if (n > 0)
+ process_data_from_plugin(pl, packetp, n, &clid, &conn_flag);
/* conn_map() called here */
- /* if no data was queued then ask the daemon for more data */
- if (data->conn->queued_urgent_data == NULL &&
- data->conn->queued_normal_data == NULL)
- plugin_report(pl, data->conn->clid, REPORT_READY_TO_SEND);
-
/* use the reply to send data */
- if (data->conn->queued_urgent_data != NULL ||
- data->conn->queued_normal_data != NULL) {
- if (data->conn->queued_urgent_data != NULL) {
- send_icmp_pkt(pl, data->conn,
- ntohs(icmp->id), ntohs(icmp->seq),
- data->conn->queued_urgent_data,
- data->conn->queued_urgent_data_len);
- free(data->conn->queued_urgent_data);
- data->conn->queued_urgent_data = NULL;
- data->conn->queued_urgent_data_len = 0;
- } else {
- send_icmp_pkt(pl, data->conn,
- ntohs(icmp->id), ntohs(icmp->seq),
- data->conn->queued_normal_data,
- data->conn->queued_normal_data_len);
- free(data->conn->queued_normal_data);
- data->conn->queued_normal_data = NULL;
- data->conn->queued_normal_data_len = 0;
- }
- }
+ if (server)
+ plugin_send_queued_data(pl, data->conn);
+
/*
* The client should send back an empty request if there was no
* data to send. This allows the server to send more data back.
*/
+ send_request:
if (!server && !data->conn->data_sent_after_last_receive) {
- /* increment the sequence number */
- if (data->conn->seq == 65535)
- data->conn->seq = 0;
- else
- data->conn->seq++;
- send_icmp_pkt(pl, data->conn,
- data->conn->id, data->conn->seq, NULL, 0);
+ plugin_send_empty_request(pl, data->conn);
}
return;
@@ -470,16 +454,67 @@
fprintf(stderr, "discarding data from a different client\n");
}
+static void
+plugin_send_empty_request(struct plugin *pl, struct conn *conn)
+{
+ plugin_custom_send(pl, conn->clid, NULL, 0);
+}
+
+/* server only */
+static void
+plugin_send_queued_data(struct plugin *pl, struct conn *conn)
+{
+ printf("plugin_icmp: plugin_send_queued_data(): clid: %hhu,\n"
+ "\turgent_data: %d, normal_data: %d\n",
+ conn->clid,
+ conn->queued_urgent_data_len, conn->queued_normal_data_len);
+
+ /* if no data was queued then ask the daemon for more data */
+ if (conn->queued_urgent_data == NULL &&
+ conn->queued_normal_data == NULL)
+ plugin_report(pl, conn->clid, REPORT_READY_TO_SEND);
+
+ printf("after plugin_report(READY_TO_SEND)...\n"
+ "\turgent_data: %d, normal_data: %d\n",
+ conn->queued_urgent_data_len, conn->queued_normal_data_len);
+
+ /* send the queued data */
+ if (conn->queued_urgent_data != NULL ||
+ conn->queued_normal_data != NULL) {
+ if (conn->queued_urgent_data != NULL) {
+ send_icmp_pkt(pl, conn,
+ conn->queued_urgent_data,
+ conn->queued_urgent_data_len);
+ free(conn->queued_urgent_data);
+ conn->queued_urgent_data = NULL;
+ conn->queued_urgent_data_len = 0;
+ } else {
+ send_icmp_pkt(pl, conn,
+ conn->queued_normal_data,
+ conn->queued_normal_data_len);
+ free(conn->queued_normal_data);
+ conn->queued_normal_data = NULL;
+ conn->queued_normal_data_len = 0;
+ }
+ }
+ printf("after send_icmp_pkt()...\n"
+ "\turgent_data: %d, normal_data: %d\n",
+ conn->queued_urgent_data_len, conn->queued_normal_data_len);
+}
+
int
plugin_is_ready_to_send(struct plugin *pl, clientid_t clid)
{
struct plugin_icmp_data *data = pl->data;
struct conn *conn = conn_by_clid(data, clid);
- if (conn->queued_normal_data == NULL)
- return WILL_QUEUE;
- else
- return QUEUE_FULL;
+ if (server) {
+ if (conn->queued_normal_data == NULL)
+ return WILL_QUEUE;
+ else
+ return QUEUE_FULL;
+ } else /* client */
+ return WILL_SEND_IMMEDIATELY;
}
void
@@ -507,7 +542,7 @@
struct plugin_icmp_data *data = pl->data;
struct conn *conn = conn_by_clid(data, clid);
- if (!server)
+ if (!server) /* client */
return;
if (conn_flag == CONN_PERM && clid != 0) {
@@ -515,11 +550,18 @@
printf("plugin_send: CONN_PERM, clid: %hhd, "
"updating...\n", clid);
conn_init(conn);
+ conn->used = 1;
}
- conn->used = 1;
conn->clid = clid;
memcpy(&conn->addr, &data->conn->addr, data->conn->addrlen);
conn->addrlen = data->conn->addrlen;
+ conn->id = data->conn->id;
+ conn->seq = data->conn->seq;
+ data->conn = conn;
+ }
+ if (conn_flag == CONN_TEMP && clid != 0) {
+ conn->id = data->conn->id;
+ conn->seq = data->conn->seq;
data->conn = conn;
}
}
@@ -575,16 +617,7 @@
}
} else { /* client - send the data straight away */
- /* increment the sequence number */
- if (pldata->conn->seq == 65535)
- pldata->conns->seq = 0;
- else
- pldata->conns->seq++;
-
- n = send_icmp_pkt(pl, pldata->conns,
- pldata->conns->id, pldata->conns->seq,
- data, len);
- pldata->conns->seq++;
+ n = send_icmp_pkt(pl, pldata->conns, data, len);
fprintf(stderr, "send_icmp_pkt: send returned %d\n", n);
if (n > 0) {
conn->data_sent_after_last_receive = 1;
@@ -593,3 +626,10 @@
return SEND_ERROR;
}
}
+
+void
+plugin_custom_receive(struct plugin *pl, uint8_t clid,
+ char *data, int len)
+{
+ plugin_send_queued_data(pl, conn_by_clid(pl->data, clid));
+}
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_tcp.c#12 (text+ko) ====
@@ -236,6 +236,7 @@
pl->receive = plugin_receive;
pl->conn_close = plugin_conn_close;
pl->conn_map = plugin_conn_map;
+ pl->custom_receive = plugin_custom_receive;
pl->data = malloc(sizeof(struct plugin_tcp_data));
if (!pl->data)
@@ -544,3 +545,9 @@
return SEND_PKT_SENT;
}
+
+void
+plugin_custom_receive(struct plugin *pl, uint8_t clid,
+ char *data, int len)
+{
+}
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_udp.c#10 (text+ko) ====
@@ -170,6 +170,7 @@
pl->receive = plugin_receive;
pl->conn_close = plugin_conn_close;
pl->conn_map = plugin_conn_map;
+ pl->custom_receive = plugin_custom_receive;
pl->data = malloc(sizeof(struct plugin_udp_data));
if (!pl->data) {
@@ -335,3 +336,9 @@
return (SEND_PKT_SENT);
}
}
+
+void
+plugin_custom_receive(struct plugin *pl, uint8_t clid,
+ char *data, int len)
+{
+}
More information about the p4-projects
mailing list