net_socket_server: fixing part so that mlx4 works again
[barrelfish] / usr / net_socket_server / lib_netss.c
1 /**
2  * @brief
3  *  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 #include <driverkit/driverkit.h>
21
22 #include <arpa/inet.h>
23
24 #include <net/net.h>
25 #include <net/dhcp.h>
26
27 #include <barrelfish/waitset_chan.h>
28
29 #include <octopus/octopus.h>
30
31 #include <devif/queue_interface.h>
32 #include <devif/backends/descq.h>
33
34 #include <if/net_sockets_defs.h>
35 #include <net_sockets/net_sockets_types.h>
36 #include <debug_log/debug_log.h>
37
38 #include <lwip/ip.h>
39 #include <lwip/udp.h>
40 #include <lwip/tcp.h>
41 #include <lwip/pbuf.h>
42
43 #include "netss.h"
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 struct send_frame {
67     genoffset_t offset;
68     genoffset_t sent, length;
69 };
70
71 struct socket_connection {
72     struct socket_connection *next;
73     struct network_connection *connection;
74     uint32_t descriptor;
75     struct send_frame send_frames[MAX_SEND_FRAMES];
76
77     struct udp_pcb *udp_socket;
78     struct tcp_pcb *tcp_socket;
79 };
80
81 struct netss_state {
82     struct network_connection* ns;
83     char service_name[128];
84     bool exported;
85 };
86
87 static struct network_connection *network_connections = NULL;
88 static struct descq *exp_queue;
89
90 static struct socket_connection * find_socket_connection(struct network_connection *nc, uint32_t descriptor)
91 {
92     struct socket_connection *socket;
93
94     socket = nc->sockets;
95     while (socket) {
96         if (socket->descriptor == descriptor)
97             break;
98         socket = socket->next;
99     }
100     return socket;
101 }
102
103 static struct socket_connection * allocate_socket(struct network_connection *nc)
104 {
105     struct socket_connection *last, *socket;
106     uint32_t last_descriptor = 0;
107
108     last = NULL;
109     socket = nc->sockets;
110     while (socket) {
111         if (socket->descriptor != last_descriptor + 1)
112             break;
113         last = socket;
114         last_descriptor = last->descriptor;
115         socket = socket->next;
116     }
117
118     socket = malloc(sizeof(struct socket_connection));
119     assert(socket);
120     memset(socket, 0, sizeof(struct socket_connection));
121
122     if (last) {
123         socket->next = last->next;
124         last->next = socket;
125     } else {
126         nc->sockets = socket;
127     }
128
129     socket->descriptor = last_descriptor + 1;
130
131     socket->connection = nc;
132     socket->udp_socket = NULL;
133     socket->tcp_socket = NULL;
134
135     memset(socket->send_frames, 0, sizeof(socket->send_frames));
136
137     return socket;
138 }
139
140 static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
141 {
142     struct socket_connection *connection = arg;
143     struct network_connection *nc = connection->connection;
144     errval_t err;
145
146     assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
147
148     uint32_t length = p->tot_len;
149     void *buffer = nc->buffers[nc->next_free];
150
151     if (!buffer) {
152         NET_SOCK_DEBUG("%s: drop\n", __func__);
153         pbuf_free(p);
154         return;
155     }
156
157     assert(buffer);
158     nc->buffers[nc->next_free] = NULL;
159     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
160     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
161     struct net_buffer *nb = buffer;
162
163     nb->size = length;
164     nb->descriptor = connection->descriptor;
165     nb->host_address.s_addr = addr->addr;
166     nb->port = port;
167     NET_SOCK_DEBUG("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, 
168                    buffer, nb->user_callback, nb->user_state, nb->size);
169
170     void *shb_data = buffer + sizeof(struct net_buffer);
171
172     struct pbuf *it;
173     uint32_t pos;
174
175     it = p;
176     for (pos = 0; pos < length; ) {
177         assert(it);
178         memcpy((void *)shb_data + pos, it->payload, it->len);
179         pos += it->len;
180         it = it->next;
181     }
182     pbuf_free(p);
183     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, 
184                        sizeof(struct net_buffer) + length, 0, 0, NET_EVENT_RECEIVED);
185     assert(err_is_ok(err));
186     err = devq_notify((struct devq *)nc->queue);
187     assert(err_is_ok(err));
188 }
189
190
191 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
192 {
193     struct socket_connection *socket = arg;
194     struct network_connection *nc = socket->connection;
195     errval_t err;
196     uint32_t length = 0;
197     void *buffer = nc->buffers[nc->next_free];
198     struct net_buffer *nb = buffer;
199
200     NET_SOCK_DEBUG("%s(%d): pcb:%p  p:%p\n", __func__, socket->descriptor, pcb, p);
201     if (p) {
202         NET_SOCK_DEBUG("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
203         assert(p->len == p->tot_len);
204         length = p->tot_len;
205
206         if (!buffer) {
207             NET_SOCK_DEBUG("%s: drop\n", __func__);
208             pbuf_free(p);
209             return ERR_OK;
210         }
211         assert(buffer);
212         nb->size = length;
213         nb->descriptor = socket->descriptor;
214         nb->accepted_descriptor = 0;
215         nb->host_address.s_addr = 0;
216         nb->port = 0;
217         NET_SOCK_DEBUG("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, 
218                        nb->size);
219
220         void *shb_data = buffer + sizeof(struct net_buffer);
221         memcpy((void *)shb_data, p->payload, length);
222         tcp_recved(pcb, p->tot_len);
223         pbuf_free(p);
224     } else {
225         assert(buffer);
226         nb->size = 0;
227         nb->descriptor = socket->descriptor;
228         nb->accepted_descriptor = 0;
229         nb->host_address.s_addr = 0;
230         nb->port = 0;
231         tcp_err(socket->tcp_socket, NULL);
232     }
233     nc->buffers[nc->next_free] = NULL;
234     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
235     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
236
237     NET_SOCK_DEBUG("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, 
238                    buffer - nc->buffer_start, sizeof(struct net_buffer) + length, 
239                    nb->descriptor);
240     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, 
241                        sizeof(struct net_buffer) + length, 0, 0, NET_EVENT_RECEIVED);
242
243     assert(err_is_ok(err));
244     err = devq_notify((struct devq *)nc->queue);
245     assert(err_is_ok(err));
246
247     return ERR_OK;
248 }
249
250 static void net_tcp_error(void *arg, err_t tcp_err)
251 {
252     struct socket_connection *socket = arg;
253     struct network_connection *nc = socket->connection;
254     errval_t err;
255
256     NET_SOCK_DEBUG("%s(%d): error %d\n", __func__, socket->descriptor, tcp_err);
257     tcp_sent(socket->tcp_socket, NULL);
258     tcp_recv(socket->tcp_socket, NULL);
259     socket->tcp_socket = NULL; // invalidate
260
261     void *buffer = nc->buffers[nc->next_free];
262     assert(buffer);
263     struct net_buffer *nb = buffer;
264     nb->size = 0;
265     nb->descriptor = socket->descriptor;
266     nb->accepted_descriptor = 0;
267     nb->host_address.s_addr = 0;
268     nb->port = 0;
269     nc->buffers[nc->next_free] = NULL;
270     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
271
272     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer),
273                        0, 0, NET_EVENT_RECEIVED);
274     assert(err_is_ok(err));
275
276     err = devq_notify((struct devq *)nc->queue);
277     assert(err_is_ok(err));
278 }
279
280 static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
281 {
282     struct socket_connection *socket = arg;
283     struct network_connection *nc = socket->connection;
284     bool notify = false;
285     errval_t err;
286
287     while (len > 0) {
288         if (!socket->send_frames[0].length)
289             debug_print_log();
290         assert(socket->send_frames[0].length);
291         if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
292             socket->send_frames[0].sent += len;
293             len = 0;
294         } else {
295             len -= socket->send_frames[0].length - socket->send_frames[0].sent;
296
297             socket->send_frames[0].length += sizeof(struct net_buffer);
298             err = devq_enqueue((struct devq *)nc->queue, nc->region_id, 
299                                socket->send_frames[0].offset, 
300                                socket->send_frames[0].length, 0, 0, 
301                                NET_EVENT_SENT);
302             if (!err_is_ok(err))
303                 NET_SOCK_DEBUG("%s: err %zd\n", __func__, err);
304             assert(err_is_ok(err));
305             notify = true;
306             socket->send_frames[0] = socket->send_frames[1];
307             socket->send_frames[1].sent = 0;
308             socket->send_frames[1].length = 0;
309             socket->send_frames[1].offset = 0;
310         }
311     }
312     if (notify) {
313         err = devq_notify((struct devq *)nc->queue);
314         assert(err_is_ok(err));
315     }
316     return ERR_OK;
317 }
318
319 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
320 {
321     struct socket_connection *socket = arg;
322     struct network_connection *nc = socket->connection;
323     struct socket_connection *accepted_socket;
324
325     newpcb->flags |= TF_NODELAY;
326
327     accepted_socket = allocate_socket(nc);
328     accepted_socket->udp_socket = NULL;
329     accepted_socket->tcp_socket = newpcb;
330     tcp_arg(accepted_socket->tcp_socket, accepted_socket);
331     tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
332     tcp_err(accepted_socket->tcp_socket, net_tcp_error);
333     tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
334
335     NET_SOCK_DEBUG("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
336
337     errval_t err;
338     uint32_t length = 0;
339     void *buffer = nc->buffers[nc->next_free];
340     struct net_buffer *nb = buffer;
341
342     nb->size = 0;
343     nb->descriptor = socket->descriptor;
344     nb->accepted_descriptor = accepted_socket->descriptor;
345     nb->host_address.s_addr = newpcb->remote_ip.addr;
346     nb->port = newpcb->remote_port;
347
348     nc->buffers[nc->next_free] = NULL;
349     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
350     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
351
352     NET_SOCK_DEBUG("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, 
353                    buffer - nc->buffer_start, sizeof(struct net_buffer) + length, 
354                    nb->descriptor);
355     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, 
356                        sizeof(struct net_buffer) + length,
357                        0, 0, NET_EVENT_ACCEPT);
358     assert(err_is_ok(err));
359     err = devq_notify((struct devq *)nc->queue);
360     assert(err_is_ok(err));
361
362     return ERR_OK;
363 }
364
365 static errval_t net_request_descq_ep_rpc(struct net_sockets_binding *binding, uint16_t core, 
366                                          struct capref* ep)
367 {
368     errval_t err;
369     err = slot_alloc(ep);
370     if (err_is_fail(err)) {
371         return err;
372     }
373
374     err = descq_create_ep(exp_queue, core, ep);
375     if (err_is_fail(err)) {
376         slot_free(*ep);
377     }
378     return err;
379 }
380
381 static void net_request_descq_ep(struct net_sockets_binding *binding, uint16_t core)
382 {
383     struct capref ep;
384     errval_t err;
385
386     err = net_request_descq_ep_rpc(binding, core, &ep);
387     err = binding->tx_vtbl.request_descq_ep_response(binding, NOP_CONT, ep);
388     assert(err_is_ok(err));
389 }
390
391 static errval_t net_register_queue_rpc(struct net_sockets_binding *binding, uint64_t queue_id)
392 {
393     struct network_connection *nc;
394
395     nc = network_connections;
396     while (nc) {
397         if (nc->queue_id == queue_id)
398             break;
399         nc = nc->next;
400     }
401     assert(nc);
402
403     binding->st = nc;
404     nc->binding = binding;
405     devq_set_state((struct devq *)nc->queue, nc);
406
407     return SYS_ERR_OK;
408 }
409
410 static void net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
411 {
412     errval_t err;
413     err = net_register_queue_rpc(binding, queue_id);
414     err = binding->tx_vtbl.register_queue_response(binding, NOP_CONT);
415     assert(err_is_ok(err));
416 }
417
418 static errval_t net_udp_socket_rpc(struct net_sockets_binding *binding, 
419                                    uint32_t *descriptor)
420 {
421     struct network_connection *nc;
422     struct socket_connection *socket;
423
424     nc = binding->st;
425     socket = allocate_socket(nc);
426     *descriptor = socket->descriptor;
427
428     struct udp_pcb *pcb = udp_new();
429     assert(pcb);
430     socket->udp_socket = pcb;
431     udp_recv(socket->udp_socket, net_udp_receive, socket);
432
433     return SYS_ERR_OK;
434 }
435
436 static void net_udp_socket(struct net_sockets_binding *binding)
437 {
438     errval_t err;
439     uint32_t desc;
440     err = net_udp_socket_rpc(binding, &desc);
441     err = binding->tx_vtbl.new_udp_socket_response(binding, NOP_CONT, desc);
442     assert(err_is_ok(err));
443 }
444
445 static errval_t net_tcp_socket_rpc(struct net_sockets_binding *binding, uint32_t *descriptor)
446 {
447     struct network_connection *nc;
448     struct socket_connection *socket;
449
450     nc = binding->st;
451     socket = allocate_socket(nc);
452     *descriptor = socket->descriptor;
453
454     struct tcp_pcb *pcb = tcp_new();
455     assert(pcb);
456     pcb->flags |= TF_NODELAY;
457     socket->tcp_socket = pcb;
458     tcp_arg(pcb, socket);
459     tcp_recv(socket->tcp_socket, net_tcp_receive);
460
461     return SYS_ERR_OK;
462 }
463
464 static void net_tcp_socket(struct net_sockets_binding *binding)
465 {
466     errval_t err;
467     uint32_t desc;
468     err = net_tcp_socket_rpc(binding, &desc);
469     err = binding->tx_vtbl.new_tcp_socket_response(binding, NOP_CONT, desc);
470     assert(err_is_ok(err));
471 }
472
473 static errval_t net_bind_rpc(struct net_sockets_binding *binding, uint32_t descriptor, 
474                              uint32_t ip_address, uint16_t port, errval_t *error, 
475                              uint16_t *bound_port)
476 {
477     struct network_connection *nc;
478     struct socket_connection *socket;
479
480     nc = binding->st;
481     socket = find_socket_connection(nc, descriptor);
482     assert(socket);
483
484     if (socket->udp_socket) {
485         ip_addr_t ip;
486
487         ip.addr = ip_address;
488         *error = udp_bind(socket->udp_socket, &ip, port);
489         assert(err_is_ok(*error));
490         *bound_port = socket->udp_socket->local_port;
491         *error = SYS_ERR_OK;
492     } else if (socket->tcp_socket) {
493         ip_addr_t ip;
494
495         ip.addr = ip_address;
496         NET_SOCK_DEBUG("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
497         *error = tcp_bind(socket->tcp_socket, &ip, port);
498         assert(err_is_ok(*error));
499         *bound_port = socket->tcp_socket->local_port;
500         *error = SYS_ERR_OK;
501     }
502     return SYS_ERR_OK;
503 }
504
505 static void net_bind(struct net_sockets_binding *binding, uint32_t descriptor, 
506                      uint32_t ip_address, uint16_t port)
507 {
508     errval_t err;
509     uint16_t bound_port;
510     err = net_bind_rpc(binding, descriptor, ip_address , port, &err, &bound_port);
511     err = binding->tx_vtbl.bind_response(binding, NOP_CONT, err, bound_port);
512     assert(err_is_ok(err));
513 }
514
515 static errval_t net_listen_rpc(struct net_sockets_binding *binding, 
516                                uint32_t descriptor, uint8_t backlog, 
517                                errval_t *error)
518 {
519     struct network_connection *nc;
520     struct socket_connection *socket;
521
522     if (descriptor == -1) {
523         debug_print_log();
524         return SYS_ERR_OK;
525     }
526     nc = binding->st;
527     socket = find_socket_connection(nc, descriptor);
528     assert(socket);
529     assert(socket->tcp_socket);
530     socket->tcp_socket = tcp_listen(socket->tcp_socket);
531     NET_SOCK_DEBUG("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
532     tcp_accept(socket->tcp_socket, net_tcp_accepted);
533     tcp_err(socket->tcp_socket, net_tcp_error);
534     // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
535     assert(socket->tcp_socket);
536
537     *error = SYS_ERR_OK;
538     return SYS_ERR_OK;
539 }
540
541 static void net_listen(struct net_sockets_binding *binding, 
542                        uint32_t descriptor, uint8_t backlog)
543 {
544     errval_t err, err2;
545     err = net_listen_rpc(binding, descriptor, backlog, &err2);
546     err = binding->tx_vtbl.listen_response(binding, NOP_CONT, err2);
547     assert(err_is_ok(err));
548 }
549
550
551 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
552 {
553     struct socket_connection *socket = arg;
554     struct network_connection *nc = socket->connection;
555
556     errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK, tpcb->remote_ip.addr, tpcb->remote_port);
557     assert(err_is_ok(err));
558
559     return SYS_ERR_OK;
560 }
561
562 static errval_t net_connect_rpc(struct net_sockets_binding *binding, 
563                                 uint32_t descriptor, uint32_t ip_address, 
564                                 uint16_t port, errval_t *error)
565 {
566     struct network_connection *nc;
567     struct socket_connection *socket;
568
569     nc = binding->st;
570     socket = find_socket_connection(nc, descriptor);
571     assert(socket);
572
573     if (socket->udp_socket) {
574         ip_addr_t addr;
575         err_t e;
576
577         addr.addr = ip_address;
578         e = udp_connect(socket->udp_socket, &addr, port);
579         assert(e == ERR_OK);
580         *error = SYS_ERR_OK;
581     } else if (socket->tcp_socket) {
582         ip_addr_t addr;
583         err_t e;
584
585         addr.addr = ip_address;
586         e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
587         assert(e == ERR_OK);
588         *error = SYS_ERR_OK;
589     }
590
591     return SYS_ERR_OK;
592 }
593
594 static void net_connect(struct net_sockets_binding *binding, 
595                         uint32_t descriptor, uint32_t ip_address, 
596                         uint16_t port)
597 {
598     errval_t err, err2;
599     err = net_connect_rpc(binding, descriptor, ip_address, port, &err2);
600     err = binding->tx_vtbl.connect_response(binding, NOP_CONT, err2);
601     assert(err_is_ok(err));
602 }
603
604 static void net_delete_socket(struct network_connection *nc, uint32_t descriptor)
605 {
606     struct socket_connection *socket, *last;
607     errval_t err;
608
609     NET_SOCK_DEBUG("%s(%d): tcp_close", __func__, descriptor);
610     socket = nc->sockets;
611     last = NULL;
612     while (socket) {
613         if (socket->descriptor == descriptor)
614             break;
615         last = socket;
616         socket = socket->next;
617     }
618     if (!socket)
619         debug_print_log();
620     assert(socket);
621     if (socket->udp_socket) {
622         udp_recv(socket->udp_socket, NULL, NULL);
623         udp_remove(socket->udp_socket);
624     } else if (socket->tcp_socket) {
625         tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
626         tcp_sent(socket->tcp_socket, NULL);
627         // tcp_accept(socket->tcp_socket, NULL);
628         err_t e;
629         e = tcp_close(socket->tcp_socket);
630         assert(e == ERR_OK);
631     }
632
633     while (socket->send_frames[0].length) { // invaldate all sent frames
634         void *buffer;
635         struct net_buffer *nb;
636
637         socket->send_frames[0].length += sizeof(struct net_buffer);
638         buffer = socket->send_frames[0].offset + nc->buffer_start;
639         nb = buffer;
640         nb->descriptor = descriptor;
641         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);
642         assert(err_is_ok(err));
643         socket->send_frames[0] = socket->send_frames[1];
644         socket->send_frames[1].sent = 0;
645         socket->send_frames[1].length = 0;
646         socket->send_frames[1].offset = 0;
647     }
648     NET_SOCK_DEBUG("%s: %ld:%p  %ld:%p\n", __func__, nc->next_free, 
649                    nc->buffers[nc->next_free], nc->next_used, 
650                    nc->buffers[nc->next_used]);
651     if (last)
652         last->next = socket->next;
653     else
654         nc->sockets = socket->next;
655     free(socket);
656 }
657
658 static uint64_t qid = 1;
659
660 static errval_t q_create(struct descq* q, uint64_t* queue_id)
661 {
662     struct network_connection *nc;
663
664     nc = malloc(sizeof(struct network_connection));
665     assert(nc);
666     nc->next = network_connections;
667     network_connections = nc;
668
669     nc->sockets = NULL;
670     nc->binding = NULL;
671     nc->queue = q;
672     *queue_id = qid++;
673     nc->queue_id = *queue_id;
674     memset(nc->buffers, 0, sizeof(nc->buffers));
675     nc->next_free = 0;
676     nc->next_used = 0;
677     return SYS_ERR_OK;
678 }
679
680 static errval_t q_destroy(struct descq* q)
681 {
682     return SYS_ERR_OK;
683 }
684
685
686 static errval_t q_notify(struct descq* q)
687 {
688     struct devq* queue = (struct devq *)q;
689     errval_t err = SYS_ERR_OK;
690     //errval_t err2 = SYS_ERR_OK;
691     regionid_t rid;
692     genoffset_t offset;
693     genoffset_t length;
694     genoffset_t valid_data;
695     genoffset_t valid_length;
696     uint64_t event;
697     struct network_connection *nc;
698     bool notify = 0;
699
700     nc = devq_get_state(queue);
701     for (int i = 0; i < NETSOCKET_LOOP_ITER; i++) {
702         err = devq_dequeue(queue, &rid, &offset, &length,
703                            &valid_data, &valid_length, &event);
704         if (err_is_fail(err)) {
705             break;
706         } else {
707             void *buffer;
708             buffer = offset + nc->buffer_start;
709             struct net_buffer *nb = buffer;
710
711             NET_SOCK_DEBUG(" offset %lu length %lu \n", offset, length);
712             if (event == NET_EVENT_RECEIVE) {
713                 assert(!nc->buffers[nc->next_used]);
714                 nc->buffers[nc->next_used] = nc->buffer_start + offset;
715                 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
716             } else if (event == NET_EVENT_SEND) {
717                 struct socket_connection *socket;
718                 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
719
720                 NET_SOCK_DEBUG("%s: %p\n", __func__, buffer);
721                 // find the socket
722                 socket = find_socket_connection(nc, nb->descriptor);
723                 if (!socket)
724                     NET_SOCK_DEBUG("%s(%d): %p\n", __func__, nb->descriptor, socket);
725                 assert(socket);
726
727                 NET_SOCK_DEBUG("buffer: %d %d %x %d  %p %p\n", nb->size, nb->descriptor, 
728                                nb->host_address, nb->port, socket->udp_socket, 
729                                socket->tcp_socket);
730                 if (socket->udp_socket) {
731                     struct udp_pcb *pcb = socket->udp_socket;
732                     struct pbuf *p;
733
734                     p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
735                     assert(p);
736                     memcpy(p->payload, shb_data, nb->size);
737
738                     ip_addr_t addr;
739                     uint16_t port;
740                     port = nb->port;
741                     addr.addr = nb->host_address.s_addr;
742                     NET_SOCK_DEBUG("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
743                     err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
744                     assert(err_is_ok(err));
745                     notify = 1;
746                     NET_SOCK_DEBUG("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
747                     if (port && addr.addr) {
748                         err_t e;
749
750                         e = udp_sendto(pcb, p, &addr, port);
751                         if (e != ERR_OK)
752                             NET_SOCK_DEBUG("%s(%d): err:%d\n", __func__, socket->descriptor, e);
753                         assert(e == ERR_OK);
754                     } else {
755                         err_t e;
756
757                         e = udp_send(pcb, p);
758                         if (e != ERR_OK)
759                             NET_SOCK_DEBUG("%s(%d): err:%d\n", __func__, socket->descriptor, e);
760                         assert(e == ERR_OK);
761                     }
762                     pbuf_free(p);
763                 } else if (socket->tcp_socket) {
764                     err_t e;
765                     NET_SOCK_DEBUG("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, event);
766
767                     if (socket->send_frames[0].length == 0) {
768
769                     } else {
770                         assert(socket->send_frames[1].length == 0);
771                     }
772                     NET_SOCK_DEBUG("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
773                     e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
774                     if (e != ERR_OK)
775                         NET_SOCK_DEBUG("%s: e=%d\n", __func__, e);
776                     assert(e == ERR_OK);
777                     e = tcp_output(socket->tcp_socket);
778                     assert(e == ERR_OK);
779
780                     if (socket->send_frames[0].length == 0) {
781                         socket->send_frames[0].offset = offset;
782                         socket->send_frames[0].length = length - sizeof(struct net_buffer);
783                     } else {
784                         socket->send_frames[1].offset = offset;
785                         socket->send_frames[1].length = length - sizeof(struct net_buffer);
786                     }
787                 } else {
788                     err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
789                     assert(err_is_ok(err));
790                     notify = 1;
791                 }
792             } else if (event == NET_EVENT_CLOSE) {
793                 net_delete_socket(nc, nb->descriptor);
794                 err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_CLOSED);
795                 assert(err_is_ok(err));
796                 notify = 1;
797             } else {
798                 NET_SOCK_DEBUG("%s: unknown event %ld!", __func__, event);
799                 assert(0);
800             }
801         }
802     }
803
804     if (notify) {
805         // NET_SOCK_DEBUG("notify>\n");
806         err = devq_notify(queue);
807         // NET_SOCK_DEBUG("notify<\n");
808         assert(err_is_ok(err));
809     }
810
811     return SYS_ERR_OK;
812 }
813
814 static errval_t q_reg(struct descq* q, struct capref cap,
815                     regionid_t rid)
816 {
817     struct frame_identity pa;
818     struct network_connection *nc;
819
820     nc = devq_get_state((struct devq *)q);
821
822     errval_t err = frame_identify(cap, &pa);
823     assert(err_is_ok(err));
824     nc->buffer_cap = cap;
825     nc->region_id = rid;
826
827     nc->buffer_size = pa.bytes;
828     err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
829     assert(err_is_ok(err));
830
831     return SYS_ERR_OK;
832 }
833
834
835 static errval_t q_dereg(struct descq* q, regionid_t rid)
836 {
837     return SYS_ERR_OK;
838 }
839
840
841 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
842 {
843     return SYS_ERR_OK;
844 }
845
846
847 static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
848     .request_descq_ep_call = net_request_descq_ep_rpc,
849     .register_queue_call = net_register_queue_rpc,
850     .new_udp_socket_call = net_udp_socket_rpc,
851     .new_tcp_socket_call = net_tcp_socket_rpc,
852     .bind_call = net_bind_rpc,
853     .connect_call = net_connect_rpc,
854     .listen_call = net_listen_rpc,
855 };
856
857 static struct net_sockets_rx_vtbl rx_vtbl = {
858     .request_descq_ep_call = net_request_descq_ep,
859     .register_queue_call = net_register_queue,
860     .new_udp_socket_call = net_udp_socket,
861     .new_tcp_socket_call = net_tcp_socket,
862     .bind_call = net_bind,
863     .connect_call = net_connect,
864     .listen_call = net_listen,
865 };
866
867 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
868 {
869     binding->rx_vtbl = rx_vtbl;
870     binding->rpc_rx_vtbl = rpc_rx_vtbl;
871     return SYS_ERR_OK;
872 }
873
874
875 static void export_cb(void *st, errval_t err, iref_t iref)
876 {
877     struct netss_state* state = (struct netss_state* ) st;
878     debug_printf("service_name %s: err %s \n", state->service_name, err_getstring(err));
879     assert(err_is_ok(err));
880     err = nameservice_register(state->service_name, iref);
881     debug_printf("nameservice register err %s \n", err_getstring(err));
882     assert(err_is_ok(err));
883     state->exported = true;
884 }
885
886 /**
887  * Driver initialization function. This function is called by the driver domain
888  * (see also 'create_handler' in ddomain_service.c).
889  * Typically through a request from the device manager.
890  *
891  * The init function is supposed to set `dev` to the exported service iref.
892  * The init function may use `bfi->dstate` to store additional state about the device.
893  *
894  * \param[in]   bfi   The instance of this driver.
895  * \param[in]   name  The name of this driver instance.
896  * \param[in]   flags Additional flags (The exact flags supported is device/driver specific).
897  * \param[in]   c     Capabilities (for registers etc.) as provided by the device manager.
898  *                    The exact layout of the `c` is device specific.
899  * \param[out]  dev   The service iref over which the device can be contacted.
900  *
901  * \retval SYS_ERR_OK Device initialized successfully.
902  * \retval LIB_ERR_MALLOC_FAIL Unable to allocate memory for the driver.
903  */
904 static errval_t init(struct bfdriver_instance *bfi, uint64_t flags, iref_t *dev)
905 {
906     //barrelfish_usleep(10*1000*1000);
907     NET_SOCK_DEBUG("Netsock init\n");
908
909     errval_t err;
910
911     if (bfi->argc < 4) {
912         printf("%s: missing arguments! \n", bfi->argv[0]);
913         return -1;
914     }
915
916     debug_printf("Net socket server started for %s.\n", bfi->argv[bfi->argc - 2]);
917
918     char card_name[64];
919     snprintf(card_name, sizeof(card_name), "%s:%s", bfi->argv[bfi->argc - 2], bfi->argv[bfi->argc - 1]);
920
921     char *ip = NULL;
922     char *netmask = NULL;
923     char *gw = NULL;
924
925     while (1) {
926         int option_index = 0;
927         int c;
928         static struct option long_options[] = {
929             {"ip",  required_argument,  0,  1},
930             {"netmask",  required_argument,  0,  2},
931             {"gw",  required_argument,  0,  3},
932             {0, 0,  0,  0}
933         };
934
935         c = getopt_long_only(bfi->argc, bfi->argv, "", long_options, &option_index);
936         if (c == -1)
937             break;
938
939         switch (c) {
940         case 1:
941             ip = optarg;
942             break;
943         case 2:
944             netmask = optarg;
945             break;
946         case 3:
947             gw = optarg;
948             break;
949         default:
950             break;
951         }
952     }
953
954     if (ip)
955         printf("option ip [%s]\n", ip);
956     if (netmask)
957         printf("option nm [%s]\n", netmask);
958     if (gw)
959         printf("option gw [%s]\n", gw);
960
961     if (ip) { // setting static IP, no DHCP
962         err = oct_init();
963         assert(err_is_ok(err));
964         err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr(ip), 
965                       gw ? inet_addr(gw): 0, netmask ? inet_addr(netmask): 0);
966         assert(err_is_ok(err));
967     }
968
969
970     if (strncmp(card_name, "mlx4", 4) == 0) {
971         // MLX4 driver needs to creat argcn + copy the interrupt cap
972         // since we still use the old PCI code
973         struct capref dst_cap;
974
975         // TODO check if cnode already exists etc. 
976         struct capref argcn;
977         struct cnoderef argcn_ref;
978         err = cnode_create_l2(&argcn, &argcn_ref);
979         assert(err_is_ok(err));
980         err = cap_copy(cap_argcn, argcn);
981         assert(err_is_ok(err));
982
983         dst_cap.slot = 1; // TODO should not be hard coded
984         dst_cap.cnode = build_cnoderef(cap_argcn, CNODE_TYPE_OTHER);
985
986         err = cap_copy(dst_cap, bfi->caps[0]);
987         assert(err_is_ok(err));
988     }
989     /* connect to the network */
990 #ifdef POLLING
991     debug_printf("Net socket server polling \n");
992
993     err = networking_init_with_ep(card_name, bfi->caps[0], (!ip ? NET_FLAGS_DO_DHCP: 0)
994                                   | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT
995                                   | NET_FLAGS_POLLING );
996 #else
997     debug_printf("Net socket server using interrupts \n");
998     err = networking_init_with_ep(card_name, bfi->caps[0], (!ip ? NET_FLAGS_DO_DHCP: 0)
999                                   | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT);
1000 #endif
1001     if (err_is_fail(err)) {
1002         USER_PANIC_ERR(err, "Failed to initialize the network");
1003     }
1004
1005     struct descq_func_pointer f;
1006
1007     f.notify = q_notify;
1008     f.create = q_create;
1009     f.destroy = q_destroy;
1010     f.reg = q_reg;
1011     f.dereg = q_dereg;
1012     f.control = q_control;
1013
1014     char queue_name[128];
1015     struct netss_state* st = (struct netss_state*) malloc(sizeof(struct netss_state));
1016
1017     sprintf(queue_name, "net_sockets_queue_%s", bfi->argv[bfi->argc - 2]);
1018     sprintf(st->service_name, "net_sockets_service_%s", bfi->argv[bfi->argc - 2]);
1019
1020     err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, queue_name,
1021                        true, NULL, &f);
1022     assert(err_is_ok(err));
1023     
1024     st->exported = false;    
1025
1026     err = net_sockets_export(st, export_cb, connect_cb, get_default_waitset(),
1027                             IDC_EXPORT_FLAGS_DEFAULT);
1028     assert(err_is_ok(err));
1029     
1030     while(!st->exported) {
1031         event_dispatch(get_default_waitset());
1032     }
1033
1034     return SYS_ERR_OK;
1035 }
1036
1037
1038 /**
1039  * Instructs driver to attach to the device.
1040  * This function is only called if the driver has previously detached
1041  * from the device (see also detach).
1042  *
1043  * \note After detachment the driver can not assume anything about the
1044  * configuration of the device.
1045  *
1046  * \param[in]   bfi   The instance of this driver.
1047  * \retval SYS_ERR_OK Device initialized successfully.
1048  */
1049 static errval_t attach(struct bfdriver_instance* bfi) {
1050     return SYS_ERR_OK;
1051 }
1052
1053 /**
1054  * Instructs driver to detach from the device.
1055  * The driver must yield any control over to the device after this function returns.
1056  * The device may be left in any state.
1057  *
1058  * \param[in]   bfi   The instance of this driver.
1059  * \retval SYS_ERR_OK Device initialized successfully.
1060  */
1061 static errval_t detach(struct bfdriver_instance* bfi) {
1062     return SYS_ERR_OK;
1063 }
1064
1065 /**
1066  * Instructs the driver to go in a particular sleep state.
1067  * Supported states are platform/device specific.
1068  *
1069  * \param[in]   bfi   The instance of this driver.
1070  * \retval SYS_ERR_OK Device initialized successfully.
1071  */
1072 static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
1073     return SYS_ERR_OK;
1074 }
1075
1076 /**
1077  * Destroys this driver instance. The driver will yield any
1078  * control over the device and free any state allocated.
1079  *
1080  * \param[in]   bfi   The instance of this driver.
1081  * \retval SYS_ERR_OK Device initialized successfully.
1082  */
1083 static errval_t destroy(struct bfdriver_instance* bfi) {
1084     USER_PANIC("NIY \n");
1085     return SYS_ERR_OK;
1086 }
1087
1088 static errval_t get_ep(struct bfdriver_instance* bfi, bool lmp, struct capref* ret_cap)
1089 {
1090     errval_t err;
1091     struct net_sockets_binding* b;
1092     err = net_sockets_create_endpoint(lmp? IDC_ENDPOINT_LMP: IDC_ENDPOINT_UMP, 
1093                                       &rx_vtbl, NULL,
1094                                       get_default_waitset(),
1095                                       IDC_ENDPOINT_FLAGS_DUMMY,
1096                                       &b, *ret_cap);
1097     
1098     return err;
1099 }
1100 /**
1101  * Registers the driver module with the system.
1102  *
1103  * To link this particular module in your driver domain,
1104  * add it to the addModules list in the Hakefile.
1105  */
1106 DEFINE_MODULE(net_sockets_server_module, init, attach, detach, set_sleep_level, destroy, get_ep);