net_sockets: change service so it can be used for all the NICS.
[barrelfish] / usr / net_socket_server / 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     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
178                        0, 0, NET_EVENT_RECEIVED);
179     assert(err_is_ok(err));
180     err = devq_notify((struct devq *)nc->queue);
181     assert(err_is_ok(err));
182     // debug_printf("%s: notifing\n", __func__);
183     // struct net_sockets_binding *binding = connection->connection->binding;
184     // debug_printf("%s: done\n", __func__);
185 }
186
187
188 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
189 {
190     struct socket_connection *socket = arg;
191     struct network_connection *nc = socket->connection;
192     errval_t err;
193     uint32_t length = 0;
194     void *buffer = nc->buffers[nc->next_free];
195     struct net_buffer *nb = buffer;
196
197     // debug_printf("%s(%d): pcb:%p  p:%p\n", __func__, socket->descriptor, pcb, p);
198     if (p) {
199         // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
200         assert(p->len == p->tot_len);
201         length = p->tot_len;
202
203         if (!buffer) {
204             debug_printf("%s: drop\n", __func__);
205             pbuf_free(p);
206             return ERR_OK;
207         }
208         assert(buffer);
209         nb->size = length;
210         nb->descriptor = socket->descriptor;
211         nb->accepted_descriptor = 0;
212         nb->host_address.s_addr = 0;
213         nb->port = 0;
214         // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
215
216         void *shb_data = buffer + sizeof(struct net_buffer);
217         memcpy((void *)shb_data, p->payload, length);
218         tcp_recved(pcb, p->tot_len);
219         pbuf_free(p);
220     } else {
221         assert(buffer);
222         nb->size = 0;
223         nb->descriptor = socket->descriptor;
224         nb->accepted_descriptor = 0;
225         nb->host_address.s_addr = 0;
226         nb->port = 0;
227         // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
228         // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
229         tcp_err(socket->tcp_socket, NULL);
230         // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
231         // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
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     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
238     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
239                        0, 0, NET_EVENT_RECEIVED);
240
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             //
332             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);
333             if (!err_is_ok(err))
334                 debug_printf("%s: err %zd\n", __func__, err);
335             assert(err_is_ok(err));
336             notify = true;
337             socket->send_frames[0] = socket->send_frames[1];
338             socket->send_frames[1].sent = 0;
339             socket->send_frames[1].length = 0;
340             socket->send_frames[1].offset = 0;
341         }
342     }
343     if (notify) {
344         err = devq_notify((struct devq *)nc->queue);
345         assert(err_is_ok(err));
346     }
347     return ERR_OK;
348 }
349
350 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
351 {
352     struct socket_connection *socket = arg;
353     struct network_connection *nc = socket->connection;
354     struct socket_connection *accepted_socket;
355
356     newpcb->flags |= TF_NODELAY;
357
358     accepted_socket = allocate_socket(nc);
359     accepted_socket->udp_socket = NULL;
360     accepted_socket->tcp_socket = newpcb;
361     tcp_arg(accepted_socket->tcp_socket, accepted_socket);
362     tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
363     tcp_err(accepted_socket->tcp_socket, net_tcp_error);
364     tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
365
366     // debug_printf("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
367     // errval_t err = nc->binding->tx_vtbl.accepted(nc->binding, BLOCKING_CONT, socket->descriptor, accepted_socket->descriptor, 0, 0, SYS_ERR_OK);
368     // assert(err_is_ok(err));
369
370     errval_t err;
371     uint32_t length = 0;
372     void *buffer = nc->buffers[nc->next_free];
373     struct net_buffer *nb = buffer;
374
375     nb->size = 0;
376     nb->descriptor = socket->descriptor;
377     nb->accepted_descriptor = accepted_socket->descriptor;
378     nb->host_address.s_addr = newpcb->remote_ip.addr;
379     nb->port = newpcb->remote_port;
380     // debug_printf_to_log("%s(%d): accepted", __func__, accepted_socket->descriptor);
381
382     nc->buffers[nc->next_free] = NULL;
383     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
384     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
385     
386     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
387     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
388                        0, 0, NET_EVENT_ACCEPT);
389     assert(err_is_ok(err));
390     err = devq_notify((struct devq *)nc->queue);
391     assert(err_is_ok(err));
392
393     return ERR_OK;
394 }
395
396
397 static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
398 {
399     struct network_connection *nc;
400
401     nc = network_connections;
402     while (nc) {
403         if (nc->queue_id == queue_id)
404             break;
405         nc = nc->next;
406     }
407     assert(nc);
408
409     binding->st = nc;
410     nc->binding = binding;
411     devq_set_state((struct devq *)nc->queue, nc);
412
413     return SYS_ERR_OK;
414 }
415
416 static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
417 {
418     struct network_connection *nc;
419     struct socket_connection *socket;
420
421     nc = binding->st;
422     socket = allocate_socket(nc);
423     *descriptor = socket->descriptor;
424
425     struct udp_pcb *pcb = udp_new();
426     assert(pcb);
427     socket->udp_socket = pcb;
428     udp_recv(socket->udp_socket, net_udp_receive, socket);
429
430     return SYS_ERR_OK;
431 }
432
433 static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
434 {
435     struct network_connection *nc;
436     struct socket_connection *socket;
437
438     nc = binding->st;
439     socket = allocate_socket(nc);
440     *descriptor = socket->descriptor;
441
442     struct tcp_pcb *pcb = tcp_new();
443     assert(pcb);
444     pcb->flags |= TF_NODELAY;
445     socket->tcp_socket = pcb;
446     tcp_arg(pcb, socket);
447     tcp_recv(socket->tcp_socket, net_tcp_receive);
448
449     return SYS_ERR_OK;
450 }
451
452 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)
453 {
454     struct network_connection *nc;
455     struct socket_connection *socket;
456
457     nc = binding->st;
458     socket = find_socket_connection(nc, descriptor);
459     assert(socket);
460
461     if (socket->udp_socket) {
462         ip_addr_t ip;
463
464         ip.addr = ip_address;
465         *error = udp_bind(socket->udp_socket, &ip, port);
466         assert(err_is_ok(*error));
467         *bound_port = socket->udp_socket->local_port;
468         *error = SYS_ERR_OK;
469     } else if (socket->tcp_socket) {
470         ip_addr_t ip;
471
472         ip.addr = ip_address;
473         // debug_printf("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
474         *error = tcp_bind(socket->tcp_socket, &ip, port);
475         assert(err_is_ok(*error));
476         *bound_port = socket->tcp_socket->local_port;
477         *error = SYS_ERR_OK;
478     }
479     return SYS_ERR_OK;
480 }
481
482 static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
483 {
484     struct network_connection *nc;
485     struct socket_connection *socket;
486
487     if (descriptor == -1) {
488         debug_print_log();
489         return SYS_ERR_OK;
490     }
491     nc = binding->st;
492     socket = find_socket_connection(nc, descriptor);
493     assert(socket);
494     assert(socket->tcp_socket);
495     socket->tcp_socket = tcp_listen(socket->tcp_socket);
496     // debug_printf("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
497     tcp_accept(socket->tcp_socket, net_tcp_accepted);
498     tcp_err(socket->tcp_socket, net_tcp_error);
499     // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
500     assert(socket->tcp_socket);
501
502     *error = SYS_ERR_OK;
503     return SYS_ERR_OK;
504 }
505
506 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
507 {
508     struct socket_connection *socket = arg;
509     struct network_connection *nc = socket->connection;
510
511     errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK, tpcb->remote_ip.addr, tpcb->remote_port);
512     assert(err_is_ok(err));
513
514     return SYS_ERR_OK;
515 }
516
517 static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
518 {
519     struct network_connection *nc;
520     struct socket_connection *socket;
521
522     nc = binding->st;
523     socket = find_socket_connection(nc, descriptor);
524     assert(socket);
525
526     if (socket->udp_socket) {
527         ip_addr_t addr;
528         err_t e;
529
530         addr.addr = ip_address;
531         e = udp_connect(socket->udp_socket, &addr, port);
532         assert(e == ERR_OK);
533         *error = SYS_ERR_OK;
534     } else if (socket->tcp_socket) {
535         ip_addr_t addr;
536         err_t e;
537
538         addr.addr = ip_address;
539         e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
540         assert(e == ERR_OK);
541         *error = SYS_ERR_OK;
542     }
543
544     return SYS_ERR_OK;
545 }
546
547 static void net_delete_socket(struct network_connection *nc, uint32_t descriptor)
548 {
549     struct socket_connection *socket, *last;
550     errval_t err;
551
552     // debug_printf_to_log("%s(%d): tcp_close", __func__, descriptor);
553     socket = nc->sockets;
554     last = NULL;
555     while (socket) {
556         if (socket->descriptor == descriptor)
557             break;
558         last = socket;
559         socket = socket->next;
560     }
561     if (!socket)
562         debug_print_log();
563     assert(socket);
564     if (socket->udp_socket) {
565         udp_recv(socket->udp_socket, NULL, NULL);
566         udp_remove(socket->udp_socket);
567     } else if (socket->tcp_socket) {
568         tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
569         tcp_sent(socket->tcp_socket, NULL);
570         // tcp_accept(socket->tcp_socket, NULL);
571         err_t e;
572         e = tcp_close(socket->tcp_socket);
573         assert(e == ERR_OK);
574     }
575
576     // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
577         // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
578         // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
579     while (socket->send_frames[0].length) { // invaldate all sent frames
580         void *buffer;
581         struct net_buffer *nb;
582
583         // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
584         //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
585         //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
586
587         socket->send_frames[0].length += sizeof(struct net_buffer);
588         buffer = socket->send_frames[0].offset + nc->buffer_start;
589         nb = buffer;
590         nb->descriptor = descriptor;
591         // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
592         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);
593         assert(err_is_ok(err));
594         socket->send_frames[0] = socket->send_frames[1];
595         socket->send_frames[1].sent = 0;
596         socket->send_frames[1].length = 0;
597         socket->send_frames[1].offset = 0;
598     }
599     // debug_printf("%s(%d):\n", __func__, descriptor);
600     // 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]);
601     if (last)
602         last->next = socket->next;
603     else
604         nc->sockets = socket->next;
605     free(socket);
606 }
607
608 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
609                        uint64_t* queue_id)
610 {
611     struct network_connection *nc;
612     static uint64_t qid = 1;
613
614     nc = malloc(sizeof(struct network_connection));
615     assert(nc);
616     nc->next = network_connections;
617     network_connections = nc;
618
619     nc->sockets = NULL;
620     nc->binding = NULL;
621     nc->queue = q;
622     *queue_id = qid++;
623     nc->queue_id = *queue_id;
624     memset(nc->buffers, 0, sizeof(nc->buffers));
625     nc->next_free = 0;
626     nc->next_used = 0;
627     return SYS_ERR_OK;
628 }
629
630 static errval_t q_destroy(struct descq* q)
631 {
632     return SYS_ERR_OK;
633 }
634
635
636 static errval_t q_notify(struct descq* q)
637 {
638     struct devq* queue = (struct devq *)q;
639     errval_t err = SYS_ERR_OK;
640     //errval_t err2 = SYS_ERR_OK;
641     regionid_t rid;
642     genoffset_t offset;
643     genoffset_t length;
644     genoffset_t valid_data;
645     genoffset_t valid_length;
646     uint64_t event;
647     struct network_connection *nc;
648     bool notify = 0;
649
650     // debug_printf("%s: \n", __func__);
651     nc = devq_get_state(queue);
652     for (;;) {
653         err = devq_dequeue(queue, &rid, &offset, &length,
654                            &valid_data, &valid_length, &event);
655         if (err_is_fail(err)) {
656             break;
657         } else {
658             void *buffer;
659             buffer = offset + nc->buffer_start;
660             struct net_buffer *nb = buffer;
661
662             //debug_printf_to_log("%s: dequeue %lx:%ld %ld  %d:%d", __func__, offset, length, event, nb->descriptor, nb->size);
663             //debug_printf(" offset %lu length %lu \n", offset, length);
664             if (event == NET_EVENT_RECEIVE) {
665                 assert(!nc->buffers[nc->next_used]);
666                 nc->buffers[nc->next_used] = nc->buffer_start + offset;
667                 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
668             } else if (event == NET_EVENT_SEND) {
669                 struct socket_connection *socket;
670                 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
671
672                 // debug_printf("%s: %p\n", __func__, buffer);
673 // find the socket
674                 socket = find_socket_connection(nc, nb->descriptor);
675                 if (!socket)
676                     debug_printf("%s(%d): %p\n", __func__, nb->descriptor, socket);
677                 assert(socket);
678
679                 // 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);
680                 if (socket->udp_socket) {
681                     struct udp_pcb *pcb = socket->udp_socket;
682                     struct pbuf *p;
683
684                     p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
685                     assert(p);
686                     memcpy(p->payload, shb_data, nb->size);
687
688                     ip_addr_t addr;
689                     uint16_t port;
690                     port = nb->port;
691                     addr.addr = nb->host_address.s_addr;
692                     // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
693                     err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
694                     assert(err_is_ok(err));
695                     notify = 1;
696                     // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
697                     if (port && addr.addr) {
698                         err_t e;
699
700                         e = udp_sendto(pcb, p, &addr, port);
701                         if (e != ERR_OK)
702                             debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
703                         assert(e == ERR_OK);
704                     } else {
705                         err_t e;
706
707                         e = udp_send(pcb, p);
708                         if (e != ERR_OK)
709                             debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
710                         assert(e == ERR_OK);
711                     }
712                     pbuf_free(p);
713                 } else if (socket->tcp_socket) {
714                     err_t e;
715                     // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, event);
716                     
717                     if (socket->send_frames[0].length == 0) {
718                         
719                     } else {
720                         assert(socket->send_frames[1].length == 0);
721                     }
722                     // debug_printf("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
723                     e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
724                     if (e != ERR_OK)
725                         debug_printf("%s: e=%d\n", __func__, e);
726                     assert(e == ERR_OK);
727                     e = tcp_output(socket->tcp_socket);
728                     assert(e == ERR_OK);
729                     
730                     if (socket->send_frames[0].length == 0) {
731                         socket->send_frames[0].offset = offset;
732                         socket->send_frames[0].length = length - sizeof(struct net_buffer);
733                     } else {
734                         socket->send_frames[1].offset = offset;
735                         socket->send_frames[1].length = length - sizeof(struct net_buffer);
736                     }
737                     // debug_printf_to_log("%s(%d): tcp_send %lx:%ld    %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor, offset, length,
738                     //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
739                     //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
740                     // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, offset, length);
741                     // err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
742                     // assert(err_is_ok(err));
743                     // notify = 1;
744                 } else {
745                     err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
746                     assert(err_is_ok(err));
747                     notify = 1;
748                 }
749             } else if (event == NET_EVENT_CLOSE) {
750                 // struct net_buffer *nb = offset + nc->buffer_start;
751
752                 // debug_printf("%s(%d): close\n", __func__, nb->descriptor);
753                 net_delete_socket(nc, nb->descriptor);
754                 err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_CLOSED);
755                 assert(err_is_ok(err));
756                 notify = 1;
757             } else {
758                 debug_printf("%s: unknown event %ld!", __func__, event);
759                 assert(0);
760             }
761         }
762     }
763
764     if (notify) {
765         // debug_printf("notify>\n");
766         err = devq_notify(queue);
767         // debug_printf("notify<\n");
768         assert(err_is_ok(err));
769     }
770
771     return SYS_ERR_OK;
772 }
773
774 static errval_t q_reg(struct descq* q, struct capref cap,
775                     regionid_t rid)
776 {
777     struct frame_identity pa;
778     struct network_connection *nc;
779
780     nc = devq_get_state((struct devq *)q);
781
782     errval_t err = frame_identify(cap, &pa);
783     assert(err_is_ok(err));
784     nc->buffer_cap = cap;
785     nc->region_id = rid;
786
787     nc->buffer_size = pa.bytes;
788     err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
789     assert(err_is_ok(err));
790
791     return SYS_ERR_OK;
792 }
793
794
795 static errval_t q_dereg(struct descq* q, regionid_t rid)
796 {
797     return SYS_ERR_OK;
798 }
799     
800
801 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
802 {
803     return SYS_ERR_OK;
804 }
805
806
807 static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
808     .register_queue_call = net_register_queue,
809     .new_udp_socket_call = net_udp_socket,
810     .new_tcp_socket_call = net_tcp_socket,
811     .bind_call = net_bind,
812     .connect_call = net_connect,
813     .listen_call = net_listen,
814 };
815
816
817 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
818 {
819     binding->rpc_rx_vtbl = rpc_rx_vtbl;
820     return SYS_ERR_OK;
821 }
822
823
824 static void export_cb(void *st, errval_t err, iref_t iref)
825 {
826     char* service_name = (char* ) st;
827     assert(err_is_ok(err));
828     err = nameservice_register(service_name, iref);
829     assert(err_is_ok(err));
830 }
831
832 int main(int argc, char *argv[])
833 {
834     errval_t err;
835     
836     if (argc < 4) {
837         printf("%s: missing arguments! \n", argv[0]);
838         return -1;
839     }
840
841     debug_printf("Net socket server started for %s.\n", argv[2]);
842
843     char card_name[64];
844     snprintf(card_name, sizeof(card_name), "%s:%s", argv[2], argv[argc - 1]);
845
846     char *ip = NULL;
847     char *netmask = NULL;
848     char *gw = NULL;
849
850     while (1) {
851         int option_index = 0;
852         int c;
853         static struct option long_options[] = {
854             {"ip",  required_argument,  0,  1},
855             {"netmask",  required_argument,  0,  2},
856             {"gw",  required_argument,  0,  3},
857             {0, 0,  0,  0}
858         };
859         c = getopt_long_only(argc, argv, "", long_options, &option_index);
860         if (c == -1)
861             break;
862
863         switch (c) {
864         case 1:
865             ip = optarg;
866             break;
867         case 2:
868             netmask = optarg;
869             break;
870         case 3:
871             gw = optarg;
872             break;
873         default:
874             break;
875         }
876     }
877
878     if (ip)
879         printf("option ip [%s]\n", ip);
880     if (netmask)
881         printf("option nm [%s]\n", netmask);
882     if (gw)
883         printf("option gw [%s]\n", gw);
884
885     if (ip) { // setting static IP, no DHCP
886         err = oct_init();
887         assert(err_is_ok(err));
888         err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr(ip), gw ? inet_addr(gw): 0, netmask ? inet_addr(netmask): 0);
889         assert(err_is_ok(err));
890     }
891
892     /* connect to the network */
893     err = networking_init(card_name, (!ip ? NET_FLAGS_DO_DHCP: 0) | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT );
894     if (err_is_fail(err)) {
895         USER_PANIC_ERR(err, "Failed to initialize the network");
896     }
897
898     struct descq *exp_queue;
899     struct descq_func_pointer f;
900
901     f.notify = q_notify;
902     f.create = q_create;
903     f.destroy = q_destroy;
904     f.reg = q_reg;
905     f.dereg = q_dereg;
906     f.control = q_control;
907
908     char queue_name[64];
909     char service_name[64];
910     sprintf(queue_name, "net_sockets_queue_%s", argv[2]);
911     sprintf(service_name, "net_sockets_service_%s", argv[2]);
912
913     err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, queue_name,
914                        true, true, 0, NULL, &f);
915     assert(err_is_ok(err));
916
917
918     err = net_sockets_export(service_name, export_cb, connect_cb, get_default_waitset(),
919                             IDC_EXPORT_FLAGS_DEFAULT);
920     assert(err_is_ok(err));
921
922     while(1) {
923         event_dispatch(get_default_waitset());
924         // networking_poll();
925     }
926
927     debug_printf("UDP ECHO termiated.\n");
928
929     return 0;
930 }