net_sockets: client library checks all available net_socket services
[barrelfish] / usr / drivers / net_socket_server / e1000_net_sockets_server.c
1 /**
2  * @brief
3  *  E1000 net socket server
4  */
5
6 /*
7  * Copyright (c) 2017, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #include <getopt.h>
16
17 #include <barrelfish/barrelfish.h>
18 #include <barrelfish/deferred.h>
19 #include <barrelfish/nameservice_client.h>
20
21 #include <arpa/inet.h>
22
23 #include <net/net.h>
24 #include <net/dhcp.h>
25
26 #include <barrelfish/waitset_chan.h>
27
28 #include <octopus/octopus.h>
29
30 #include <devif/queue_interface.h>
31 #include <devif/backends/descq.h>
32
33 #include <if/net_sockets_defs.h>
34 #include <net_sockets/net_sockets_types.h>
35 #include <debug_log/debug_log.h>
36
37 #include <lwip/ip.h>
38 #include <lwip/udp.h>
39 #include <lwip/tcp.h>
40 #include <lwip/pbuf.h>
41
42 #define NO_OF_BUFFERS 128
43 #define BUFFER_SIZE 16384
44
45 struct socket_connection;
46
47 struct network_connection {
48     struct network_connection *next;
49
50     struct capref buffer_cap;
51     struct descq *queue;
52     uint64_t queue_id;
53     regionid_t region_id;
54     void *buffer_start;
55     uint64_t buffer_size;
56
57     void *buffers[NO_OF_BUFFERS];
58     uint64_t next_free, next_used;
59
60     struct net_sockets_binding *binding;
61
62     struct descq *buffer_queue;
63     struct socket_connection *sockets;
64 };
65
66 #define MAX_SEND_FRAMES 2
67
68 struct send_frame {
69     genoffset_t offset;
70     genoffset_t sent, length;
71 };
72
73 struct socket_connection {
74     struct socket_connection *next;
75     struct network_connection *connection;
76     uint32_t descriptor;
77     struct send_frame send_frames[MAX_SEND_FRAMES];
78
79     struct udp_pcb *udp_socket;
80     struct tcp_pcb *tcp_socket;
81 };
82
83 static struct network_connection *network_connections = NULL;
84
85 static struct socket_connection * find_socket_connection(struct network_connection *nc, uint32_t descriptor)
86 {
87     struct socket_connection *socket;
88
89     socket = nc->sockets;
90     while (socket) {
91         if (socket->descriptor == descriptor)
92             break;
93         socket = socket->next;
94     }
95     return socket;
96 }
97
98 static struct socket_connection * allocate_socket(struct network_connection *nc)
99 {
100     struct socket_connection *last, *socket;
101     uint32_t last_descriptor = 0;
102
103     last = NULL;
104     socket = nc->sockets;
105     while (socket) {
106         if (socket->descriptor != last_descriptor + 1)
107             break;
108         last = socket;
109         last_descriptor = last->descriptor;
110         socket = socket->next;
111     }
112
113     socket = malloc(sizeof(struct socket_connection));
114     assert(socket);
115     memset(socket, 0, sizeof(struct socket_connection));
116
117     if (last) {
118         socket->next = last->next;
119         last->next = socket;
120     } else {
121         nc->sockets = socket;
122     }
123
124     socket->descriptor = last_descriptor + 1;
125     
126     socket->connection = nc;
127     socket->udp_socket = NULL;
128     socket->tcp_socket = NULL;
129
130     memset(socket->send_frames, 0, sizeof(socket->send_frames));
131
132     return socket;
133 }
134
135 static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
136 {
137     struct socket_connection *connection = arg;
138     struct network_connection *nc = connection->connection;
139     errval_t err;
140
141     assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
142
143     uint32_t length = p->tot_len;
144     void *buffer = nc->buffers[nc->next_free];
145
146     if (!buffer) {
147         debug_printf("%s: drop\n", __func__);
148         pbuf_free(p);
149         return;
150     }
151
152     assert(buffer);
153     nc->buffers[nc->next_free] = NULL;
154     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
155     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
156     struct net_buffer *nb = buffer;
157
158     nb->size = length;
159     nb->descriptor = connection->descriptor;
160     nb->host_address.s_addr = addr->addr;
161     nb->port = port;
162     // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
163
164     void *shb_data = buffer + sizeof(struct net_buffer);
165     
166     struct pbuf *it;
167     uint32_t pos;
168     
169     it = p;
170     for (pos = 0; pos < length; ) {
171         assert(it);
172         memcpy((void *)shb_data + pos, it->payload, it->len);
173         pos += it->len;
174         it = it->next;
175     }
176     pbuf_free(p);
177     // debug_printf("%s.%d: enqueue 1 %lx:%ld\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length);
178     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
179                        0, 0, NET_EVENT_RECEIVED);
180     assert(err_is_ok(err));
181     err = devq_notify((struct devq *)nc->queue);
182     assert(err_is_ok(err));
183
184     // debug_printf("%s: notifing\n", __func__);
185     // struct net_sockets_binding *binding = connection->connection->binding;
186     // debug_printf("%s: done\n", __func__);
187 }
188
189
190 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
191 {
192     struct socket_connection *socket = arg;
193     struct network_connection *nc = socket->connection;
194     errval_t err;
195     uint32_t length = 0;
196     void *buffer = nc->buffers[nc->next_free];
197     struct net_buffer *nb = buffer;
198
199     // debug_printf("%s(%d): pcb:%p  p:%p\n", __func__, socket->descriptor, pcb, p);
200     if (p) {
201         // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
202         assert(p->len == p->tot_len);
203         length = p->tot_len;
204         if (!buffer) {
205             debug_printf("%s: drop\n", __func__);
206             pbuf_free(p);
207             return ERR_OK;
208         }
209         assert(buffer);
210         nb->size = length;
211         nb->descriptor = socket->descriptor;
212         nb->accepted_descriptor = 0;
213         nb->host_address.s_addr = 0;
214         nb->port = 0;
215         // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
216
217         void *shb_data = buffer + sizeof(struct net_buffer);
218         memcpy((void *)shb_data, p->payload, length);
219         tcp_recved(pcb, p->tot_len);
220         pbuf_free(p);
221     } else {
222         assert(buffer);
223         nb->size = 0;
224         nb->descriptor = socket->descriptor;
225         nb->accepted_descriptor = 0;
226         nb->host_address.s_addr = 0;
227         nb->port = 0;
228         // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
229         // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
230         tcp_err(socket->tcp_socket, NULL);
231         // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
232         // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
233     }
234     nc->buffers[nc->next_free] = NULL;
235     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
236     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
237     
238     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
239     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
240                        0, 0, NET_EVENT_RECEIVED);
241     assert(err_is_ok(err));
242     err = devq_notify((struct devq *)nc->queue);
243     assert(err_is_ok(err));
244
245     // debug_printf("%s: notifing\n", __func__);
246     // struct net_sockets_binding *binding = connection->connection->binding;
247     // debug_printf("%s: done\n", __func__);
248     return ERR_OK;
249 }
250
251 static void net_tcp_error(void *arg, err_t tcp_err)
252 {
253     struct socket_connection *socket = arg;
254     struct network_connection *nc = socket->connection;
255     errval_t err;
256
257     // debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, tcp_err);
258     // debug_printf_to_log("%s(%d): error %d", __func__, socket->descriptor, tcp_err);
259     tcp_sent(socket->tcp_socket, NULL);
260     tcp_recv(socket->tcp_socket, NULL);
261     socket->tcp_socket = NULL; // invalidate
262
263     void *buffer = nc->buffers[nc->next_free];
264     assert(buffer);
265     struct net_buffer *nb = buffer;
266     nb->size = 0;
267     nb->descriptor = socket->descriptor;
268     nb->accepted_descriptor = 0;
269     nb->host_address.s_addr = 0;
270     nb->port = 0;
271     nc->buffers[nc->next_free] = NULL;
272     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
273     
274     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer),
275                        0, 0, NET_EVENT_RECEIVED);
276     assert(err_is_ok(err));
277     // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
278     
279     err = devq_notify((struct devq *)nc->queue);
280     assert(err_is_ok(err));
281
282
283     // uint32_t length = 0;
284     // void *buffer = nc->buffers[nc->next_free];
285     // struct net_buffer *nb = buffer;
286     //
287     // assert(buffer);
288     // nb->size = 0;
289     // nb->descriptor = socket->descriptor;
290     // nb->accepted_descriptor = 0;
291     // nb->host_address.s_addr = 0;
292     // nb->port = 0;
293     // debug_printf("%s(%d): close on error\n", __func__, socket->descriptor);
294     // nc->buffers[nc->next_free] = NULL;
295     // nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
296     // assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
297     //
298     // // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
299     // err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
300     //                    0, 0, 1);
301     // assert(err_is_ok(err));
302     // err = devq_notify((struct devq *)nc->queue);
303     // assert(err_is_ok(err));
304 }
305
306 static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
307 {
308     struct socket_connection *socket = arg;
309     struct network_connection *nc = socket->connection;
310     bool notify = false;
311     errval_t err;
312
313     while (len > 0) {
314         // debug_printf_to_log("%s(%d): %d  %lx:%ld:%ld  %lx:%ld:%ld", __func__, socket->descriptor, len,
315             // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
316             // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
317         // debug_printf("%s(%d): %d  %zx:%zd:%zd %zx:%zd:%zd\n", __func__, socket->descriptor, len,
318         //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
319         //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
320         if (!socket->send_frames[0].length)
321             debug_print_log();
322         assert(socket->send_frames[0].length);
323         if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
324             socket->send_frames[0].sent += len;
325             len = 0;
326         } else {
327             len -= socket->send_frames[0].length - socket->send_frames[0].sent;
328             
329             socket->send_frames[0].length += sizeof(struct net_buffer);
330             // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
331             err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, NET_EVENT_SENT);
332             if (!err_is_ok(err))
333                 debug_printf("%s: err %zd\n", __func__, err);
334             assert(err_is_ok(err));
335             notify = true;
336             socket->send_frames[0] = socket->send_frames[1];
337             socket->send_frames[1].sent = 0;
338             socket->send_frames[1].length = 0;
339             socket->send_frames[1].offset = 0;
340         }
341     }
342     if (notify) {
343         err = devq_notify((struct devq *)nc->queue);
344         assert(err_is_ok(err));
345     }
346     return ERR_OK;
347 }
348
349 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
350 {
351     struct socket_connection *socket = arg;
352     struct network_connection *nc = socket->connection;
353     struct socket_connection *accepted_socket;
354
355     newpcb->flags |= TF_NODELAY;
356
357     accepted_socket = allocate_socket(nc);
358     accepted_socket->udp_socket = NULL;
359     accepted_socket->tcp_socket = newpcb;
360     tcp_arg(accepted_socket->tcp_socket, accepted_socket);
361     tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
362     tcp_err(accepted_socket->tcp_socket, net_tcp_error);
363     tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
364
365     // debug_printf("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
366     // errval_t err = nc->binding->tx_vtbl.accepted(nc->binding, BLOCKING_CONT, socket->descriptor, accepted_socket->descriptor, 0, 0, SYS_ERR_OK);
367     // assert(err_is_ok(err));
368
369     errval_t err;
370     uint32_t length = 0;
371     void *buffer = nc->buffers[nc->next_free];
372     struct net_buffer *nb = buffer;
373
374     nb->size = 0;
375     nb->descriptor = socket->descriptor;
376     nb->accepted_descriptor = accepted_socket->descriptor;
377     nb->host_address.s_addr = newpcb->remote_ip.addr;
378     nb->port = newpcb->remote_port;
379     // debug_printf_to_log("%s(%d): accepted", __func__, accepted_socket->descriptor);
380
381     nc->buffers[nc->next_free] = NULL;
382     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
383     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
384     
385     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
386     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
387                        0, 0, NET_EVENT_ACCEPT);
388     assert(err_is_ok(err));
389     err = devq_notify((struct devq *)nc->queue);
390     assert(err_is_ok(err));
391
392     return ERR_OK;
393 }
394
395
396 static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
397 {
398     struct network_connection *nc;
399
400     nc = network_connections;
401     while (nc) {
402         if (nc->queue_id == queue_id)
403             break;
404         nc = nc->next;
405     }
406     assert(nc);
407
408     binding->st = nc;
409     nc->binding = binding;
410     devq_set_state((struct devq *)nc->queue, nc);
411
412     return SYS_ERR_OK;
413 }
414
415 static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
416 {
417     struct network_connection *nc;
418     struct socket_connection *socket;
419
420     nc = binding->st;
421     socket = allocate_socket(nc);
422     *descriptor = socket->descriptor;
423
424     struct udp_pcb *pcb = udp_new();
425     assert(pcb);
426     socket->udp_socket = pcb;
427     udp_recv(socket->udp_socket, net_udp_receive, socket);
428
429     return SYS_ERR_OK;
430 }
431
432 static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
433 {
434     struct network_connection *nc;
435     struct socket_connection *socket;
436
437     nc = binding->st;
438     socket = allocate_socket(nc);
439     *descriptor = socket->descriptor;
440
441     struct tcp_pcb *pcb = tcp_new();
442     assert(pcb);
443     pcb->flags |= TF_NODELAY;
444     socket->tcp_socket = pcb;
445     tcp_arg(pcb, socket);
446     tcp_recv(socket->tcp_socket, net_tcp_receive);
447
448     return SYS_ERR_OK;
449 }
450
451 static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error, uint16_t *bound_port)
452 {
453     struct network_connection *nc;
454     struct socket_connection *socket;
455
456     nc = binding->st;
457     socket = find_socket_connection(nc, descriptor);
458     assert(socket);
459
460     if (socket->udp_socket) {
461         ip_addr_t ip;
462
463         ip.addr = ip_address;
464         *error = udp_bind(socket->udp_socket, &ip, port);
465         assert(err_is_ok(*error));
466         *bound_port = socket->udp_socket->local_port;
467         *error = SYS_ERR_OK;
468     } else if (socket->tcp_socket) {
469         ip_addr_t ip;
470
471         ip.addr = ip_address;
472         // debug_printf("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
473         *error = tcp_bind(socket->tcp_socket, &ip, port);
474         assert(err_is_ok(*error));
475         *bound_port = socket->tcp_socket->local_port;
476         *error = SYS_ERR_OK;
477     }
478     return SYS_ERR_OK;
479 }
480
481 static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
482 {
483     struct network_connection *nc;
484     struct socket_connection *socket;
485
486     if (descriptor == -1) {
487         debug_print_log();
488         return SYS_ERR_OK;
489     }
490     nc = binding->st;
491     socket = find_socket_connection(nc, descriptor);
492     assert(socket);
493     assert(socket->tcp_socket);
494     socket->tcp_socket = tcp_listen(socket->tcp_socket);
495     // debug_printf("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
496     tcp_accept(socket->tcp_socket, net_tcp_accepted);
497     tcp_err(socket->tcp_socket, net_tcp_error);
498     // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
499     assert(socket->tcp_socket);
500
501     *error = SYS_ERR_OK;
502     return SYS_ERR_OK;
503 }
504
505 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
506 {
507     struct socket_connection *socket = arg;
508     struct network_connection *nc = socket->connection;
509
510     errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK, tpcb->remote_ip.addr, tpcb->remote_port);
511     assert(err_is_ok(err));
512
513     return SYS_ERR_OK;
514 }
515
516 static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
517 {
518     struct network_connection *nc;
519     struct socket_connection *socket;
520
521     nc = binding->st;
522     socket = find_socket_connection(nc, descriptor);
523     assert(socket);
524
525     if (socket->udp_socket) {
526         ip_addr_t addr;
527         err_t e;
528
529         addr.addr = ip_address;
530         e = udp_connect(socket->udp_socket, &addr, port);
531         assert(e == ERR_OK);
532         *error = SYS_ERR_OK;
533     } else if (socket->tcp_socket) {
534         ip_addr_t addr;
535         err_t e;
536
537         addr.addr = ip_address;
538         e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
539         assert(e == ERR_OK);
540         *error = SYS_ERR_OK;
541     }
542
543     return SYS_ERR_OK;
544 }
545
546 static void net_delete_socket(struct network_connection *nc, uint32_t descriptor)
547 {
548     struct socket_connection *socket, *last;
549     errval_t err;
550
551     // debug_printf_to_log("%s(%d): tcp_close", __func__, descriptor);
552     socket = nc->sockets;
553     last = NULL;
554     while (socket) {
555         if (socket->descriptor == descriptor)
556             break;
557         last = socket;
558         socket = socket->next;
559     }
560     if (!socket)
561         debug_print_log();
562     assert(socket);
563     if (socket->udp_socket) {
564         udp_recv(socket->udp_socket, NULL, NULL);
565         udp_remove(socket->udp_socket);
566     } else if (socket->tcp_socket) {
567         tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
568         tcp_sent(socket->tcp_socket, NULL);
569         // tcp_accept(socket->tcp_socket, NULL);
570         err_t e;
571         e = tcp_close(socket->tcp_socket);
572         assert(e == ERR_OK);
573     }
574
575     // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
576         // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
577         // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
578     while (socket->send_frames[0].length) { // invaldate all sent frames
579         void *buffer;
580         struct net_buffer *nb;
581
582         // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
583         //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
584         //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
585
586         socket->send_frames[0].length += sizeof(struct net_buffer);
587         buffer = socket->send_frames[0].offset + nc->buffer_start;
588         nb = buffer;
589         nb->descriptor = descriptor;
590         // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
591         err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, NET_EVENT_SENT);
592         assert(err_is_ok(err));
593         socket->send_frames[0] = socket->send_frames[1];
594         socket->send_frames[1].sent = 0;
595         socket->send_frames[1].length = 0;
596         socket->send_frames[1].offset = 0;
597     }
598     // debug_printf("%s(%d):\n", __func__, descriptor);
599     // debug_printf("%s: %ld:%p  %ld:%p\n", __func__, nc->next_free, nc->buffers[nc->next_free], nc->next_used, nc->buffers[nc->next_used]);
600     if (last)
601         last->next = socket->next;
602     else
603         nc->sockets = socket->next;
604     free(socket);
605 }
606
607 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
608                        uint64_t* queue_id)
609 {
610     struct network_connection *nc;
611     static uint64_t qid = 1;
612
613     nc = malloc(sizeof(struct network_connection));
614     assert(nc);
615     nc->next = network_connections;
616     network_connections = nc;
617
618     nc->sockets = NULL;
619     nc->binding = NULL;
620     nc->queue = q;
621     *queue_id = qid++;
622     nc->queue_id = *queue_id;
623     memset(nc->buffers, 0, sizeof(nc->buffers));
624     nc->next_free = 0;
625     nc->next_used = 0;
626     return SYS_ERR_OK;
627 }
628
629 static errval_t q_destroy(struct descq* q)
630 {
631     return SYS_ERR_OK;
632 }
633
634
635 static errval_t q_notify(struct descq* q)
636 {
637     struct devq* queue = (struct devq *)q;
638     errval_t err = SYS_ERR_OK;
639     //errval_t err2 = SYS_ERR_OK;
640     regionid_t rid;
641     genoffset_t offset;
642     genoffset_t length;
643     genoffset_t valid_data;
644     genoffset_t valid_length;
645     uint64_t event;
646     struct network_connection *nc;
647     bool notify = 0;
648
649     // debug_printf("%s: \n", __func__);
650     nc = devq_get_state(queue);
651     for (;;) {
652         err = devq_dequeue(queue, &rid, &offset, &length,
653                            &valid_data, &valid_length, &event);
654         if (err_is_fail(err)) {
655             break;
656         } else {
657             void *buffer;
658             buffer = offset + nc->buffer_start;
659             struct net_buffer *nb = buffer;
660
661             // debug_printf_to_log("%s: dequeue %lx:%ld %ld  %d:%d", __func__, offset, length, event, nb->descriptor, nb->size);
662             if (event == NET_EVENT_RECEIVE) {
663                 assert(!nc->buffers[nc->next_used]);
664                 nc->buffers[nc->next_used] = nc->buffer_start + offset;
665                 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
666             } else if (event == NET_EVENT_SEND) {
667                 struct socket_connection *socket;
668                 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
669
670                 // debug_printf("%s: %p\n", __func__, buffer);
671 // find the socket
672                 socket = find_socket_connection(nc, nb->descriptor);
673                 if (!socket)
674                     debug_printf("%s(%d): %p\n", __func__, nb->descriptor, socket);
675                 assert(socket);
676
677                 // debug_printf("buffer: %d %d %x %d  %p %p\n", nb->size, nb->descriptor, nb->host_address, nb->port, socket->udp_socket, socket->tcp_socket);
678                 if (socket->udp_socket) {
679                     struct udp_pcb *pcb = socket->udp_socket;
680                     struct pbuf *p;
681
682                     p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
683                     assert(p);
684                     memcpy(p->payload, shb_data, nb->size);
685
686                     ip_addr_t addr;
687                     uint16_t port;
688                     port = nb->port;
689                     addr.addr = nb->host_address.s_addr;
690                     // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
691                     err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
692                     assert(err_is_ok(err));
693                     notify = 1;
694                     // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
695                     if (port && addr.addr) {
696                         err_t e;
697
698                         e = udp_sendto(pcb, p, &addr, port);
699                         if (e != ERR_OK)
700                             debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
701                         assert(e == ERR_OK);
702                     } else {
703                         err_t e;
704
705                         e = udp_send(pcb, p);
706                         if (e != ERR_OK)
707                             debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
708                         assert(e == ERR_OK);
709                     }
710                     pbuf_free(p);
711                 } else if (socket->tcp_socket) {
712                     err_t e;
713                     // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, event);
714                     
715                     if (socket->send_frames[0].length == 0) {
716                         
717                     } else {
718                         assert(socket->send_frames[1].length == 0);
719                     }
720                     // debug_printf("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
721                     e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
722                     if (e != ERR_OK)
723                         debug_printf("%s: e=%d\n", __func__, e);
724                     assert(e == ERR_OK);
725                     e = tcp_output(socket->tcp_socket);
726                     assert(e == ERR_OK);
727                     
728                     if (socket->send_frames[0].length == 0) {
729                         socket->send_frames[0].offset = offset;
730                         socket->send_frames[0].length = length - sizeof(struct net_buffer);
731                     } else {
732                         socket->send_frames[1].offset = offset;
733                         socket->send_frames[1].length = length - sizeof(struct net_buffer);
734                     }
735                     // debug_printf_to_log("%s(%d): tcp_send %lx:%ld    %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor, offset, length,
736                     //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
737                     //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
738                     // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, offset, length);
739                     // err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
740                     // assert(err_is_ok(err));
741                     // notify = 1;
742                 } else {
743                     err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
744                     assert(err_is_ok(err));
745                     notify = 1;
746                 }
747             } else if (event == NET_EVENT_CLOSE) {
748                 // struct net_buffer *nb = offset + nc->buffer_start;
749
750                 // debug_printf("%s(%d): close\n", __func__, nb->descriptor);
751                 net_delete_socket(nc, nb->descriptor);
752                 err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_CLOSED);
753                 assert(err_is_ok(err));
754                 notify = 1;
755             } else {
756                 debug_printf("%s: unknown event %ld!", __func__, event);
757                 assert(0);
758             }
759         }
760     }
761
762     if (notify) {
763         // debug_printf("notify>\n");
764         err = devq_notify(queue);
765         // debug_printf("notify<\n");
766         assert(err_is_ok(err));
767     }
768
769     return SYS_ERR_OK;
770 }
771
772 static errval_t q_reg(struct descq* q, struct capref cap,
773                     regionid_t rid)
774 {
775     struct frame_identity pa;
776     struct network_connection *nc;
777
778     nc = devq_get_state((struct devq *)q);
779
780     errval_t err = frame_identify(cap, &pa);
781     assert(err_is_ok(err));
782     nc->buffer_cap = cap;
783     nc->region_id = rid;
784
785     nc->buffer_size = pa.bytes;
786     err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
787     assert(err_is_ok(err));
788
789     return SYS_ERR_OK;
790 }
791
792
793 static errval_t q_dereg(struct descq* q, regionid_t rid)
794 {
795     return SYS_ERR_OK;
796 }
797     
798
799 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
800 {
801     return SYS_ERR_OK;
802 }
803
804
805 static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
806     .register_queue_call = net_register_queue,
807     .new_udp_socket_call = net_udp_socket,
808     .new_tcp_socket_call = net_tcp_socket,
809     .bind_call = net_bind,
810     .connect_call = net_connect,
811     .listen_call = net_listen,
812 };
813
814
815 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
816 {
817     binding->rpc_rx_vtbl = rpc_rx_vtbl;
818     return SYS_ERR_OK;
819 }
820
821
822 static void export_cb(void *st, errval_t err, iref_t iref)
823 {
824     assert(err_is_ok(err));
825     err = nameservice_register("net_sockets", iref);
826     assert(err_is_ok(err));
827 }
828
829 int main(int argc, char *argv[])
830 {
831     errval_t err;
832
833     if (argc < 1) {
834         printf("%s: missing card argument!\n", argv[0]);
835         return -1;
836     }
837     debug_printf("Net socket server started for e1000 %s.\n", argv[argc - 1]);
838
839     char servicename[64];
840     snprintf(servicename, sizeof(servicename), "e1000:%s", argv[argc - 1]);
841
842     char *ip = NULL;
843     char *netmask = NULL;
844     char *gw = NULL;
845
846     while (1) {
847         int option_index = 0;
848         int c;
849         static struct option long_options[] = {
850             {"ip",  required_argument,  0,  1},
851             {"netmask",  required_argument,  0,  2},
852             {"gw",  required_argument,  0,  3},
853             {0, 0,  0,  0}
854         };
855         c = getopt_long_only(argc, argv, "", long_options, &option_index);
856         if (c == -1)
857             break;
858
859         switch (c) {
860         case 1:
861             ip = optarg;
862             break;
863         case 2:
864             netmask = optarg;
865             break;
866         case 3:
867             gw = optarg;
868             break;
869         default:
870             break;
871         }
872     }
873
874     if (ip)
875         printf("option ip [%s]\n", ip);
876     if (netmask)
877         printf("option nm [%s]\n", netmask);
878     if (gw)
879         printf("option gw [%s]\n", gw);
880
881     if (ip) { // setting static IP, no DHCP
882         err = oct_init();
883         assert(err_is_ok(err));
884         err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr(ip), gw ? inet_addr(gw): 0, netmask ? inet_addr(netmask): 0);
885         assert(err_is_ok(err));
886     }
887
888     /* connect to the network */
889     err = networking_init(servicename, (!ip ? NET_FLAGS_DO_DHCP: 0) | NET_FLAGS_NO_NET_FILTER | NET_FLAGS_BLOCKING_INIT);
890     if (err_is_fail(err)) {
891         USER_PANIC_ERR(err, "Failed to initialize the network");
892     }
893
894     struct descq *exp_queue;
895     struct descq_func_pointer f;
896
897     f.notify = q_notify;
898     f.create = q_create;
899     f.destroy = q_destroy;
900     f.reg = q_reg;
901     f.dereg = q_dereg;
902     f.control = q_control;
903
904     err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
905                        true, true, 0, NULL, &f);
906     assert(err_is_ok(err));
907
908
909     err = net_sockets_export(NULL, export_cb, connect_cb, get_default_waitset(),
910                             IDC_EXPORT_FLAGS_DEFAULT);
911     assert(err_is_ok(err));
912
913     while(1) {
914         event_dispatch(get_default_waitset());
915         // networking_poll();
916     }
917
918     debug_printf("UDP ECHO termiated.\n");
919
920     return 0;
921 }