36a14e8cb5fe66a2cf4fff097042a9035985180f
[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 <barrelfish/barrelfish.h>
16 #include <barrelfish/deferred.h>
17 #include <barrelfish/nameservice_client.h>
18
19 #include <net/net.h>
20
21 #include <barrelfish/waitset_chan.h>
22
23 #include <devif/queue_interface.h>
24 #include <devif/backends/descq.h>
25
26 #include <if/net_sockets_defs.h>
27 #include <net_sockets/net_sockets_types.h>
28
29 #include <lwip/ip.h>
30 #include <lwip/udp.h>
31 #include <lwip/tcp.h>
32 #include <lwip/pbuf.h>
33
34 #define NO_OF_BUFFERS 128
35 #define BUFFER_SIZE 16384
36
37 struct socket_connection;
38
39 struct network_connection {
40     struct network_connection *next;
41
42     struct capref buffer_cap;
43     struct descq *queue;
44     uint64_t queue_id;
45     regionid_t region_id;
46     void *buffer_start;
47     uint64_t buffer_size;
48
49     void *buffers[NO_OF_BUFFERS];
50     uint64_t next_free, next_used;
51
52     struct net_sockets_binding *binding;
53
54     struct descq *buffer_queue;
55     struct socket_connection *sockets;
56 };
57
58 #define MAX_SEND_FRAMES 2
59
60 struct send_frame {
61     genoffset_t offset;
62     genoffset_t sent, length;
63 };
64
65 struct socket_connection {
66     struct socket_connection *next;
67     struct network_connection *connection;
68     uint32_t descriptor;
69     struct send_frame send_frames[MAX_SEND_FRAMES];
70
71     struct udp_pcb *udp_socket;
72     struct tcp_pcb *tcp_socket;
73 };
74
75 static struct network_connection *network_connections = NULL;
76
77 static struct socket_connection * allocate_socket(struct network_connection *nc)
78 {
79     struct socket_connection *last, *socket;
80     uint32_t last_descriptor = 0;
81
82     last = NULL;
83     socket = nc->sockets;
84     while (socket) {
85         if (socket->descriptor != last_descriptor + 1)
86             break;
87         last = socket;
88         last_descriptor = last->descriptor;
89         socket = socket->next;
90     }
91
92     socket = malloc(sizeof(struct socket_connection));
93     assert(socket);
94     memset(socket, 0, sizeof(struct socket_connection));
95
96     if (last) {
97         socket->next = last->next;
98         last->next = socket;
99     } else {
100         nc->sockets = socket;
101     }
102
103     socket->descriptor = last_descriptor + 1;
104     
105     socket->connection = nc;
106     socket->udp_socket = NULL;
107     socket->tcp_socket = NULL;
108
109     memset(socket->send_frames, 0, sizeof(socket->send_frames));
110
111     return socket;
112 }
113
114 static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
115 {
116     struct socket_connection *connection = arg;
117     struct network_connection *nc = connection->connection;
118     errval_t err;
119
120     assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
121
122     uint32_t length = p->tot_len;
123     void *buffer = nc->buffers[nc->next_free];
124
125     if (!buffer) {
126         debug_printf("%s: drop\n", __func__);
127         pbuf_free(p);
128         return;
129     }
130
131     assert(buffer);
132     nc->buffers[nc->next_free] = NULL;
133     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
134     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
135     struct net_buffer *nb = buffer;
136
137     nb->size = length;
138     nb->descriptor = connection->descriptor;
139     nb->host_address.s_addr = addr->addr;
140     nb->port = port;
141     // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
142
143     void *shb_data = buffer + sizeof(struct net_buffer);
144     
145     struct pbuf *it;
146     uint32_t pos;
147     
148     it = p;
149     for (pos = 0; pos < length; ) {
150         assert(it);
151         memcpy((void *)shb_data + pos, it->payload, it->len);
152         pos += it->len;
153         it = it->next;
154     }
155     pbuf_free(p);
156     // debug_printf("%s.%d: enqueue 1 %lx:%ld\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length);
157     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
158                        0, 0, 1);
159     assert(err_is_ok(err));
160     err = devq_notify((struct devq *)nc->queue);
161     assert(err_is_ok(err));
162
163     // debug_printf("%s: notifing\n", __func__);
164     // struct net_sockets_binding *binding = connection->connection->binding;
165     // debug_printf("%s: done\n", __func__);
166 }
167
168
169 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
170 {
171     struct socket_connection *socket = arg;
172     struct network_connection *nc = socket->connection;
173     errval_t err;
174     uint32_t length = 0;
175     void *buffer = nc->buffers[nc->next_free];
176     struct net_buffer *nb = buffer;
177
178     // debug_printf("%s: pcb:%p  p:%p\n", __func__, pcb, p);
179     if (p) {
180         // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
181         assert(p->len == p->tot_len);
182         length = p->tot_len;
183         if (!buffer) {
184             debug_printf("%s: drop\n", __func__);
185             pbuf_free(p);
186             return ERR_OK;
187         }
188         assert(buffer);
189         nb->size = length;
190         nb->descriptor = socket->descriptor;
191         nb->accepted_descriptor = 0;
192         nb->host_address.s_addr = 0;
193         nb->port = 0;
194         // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
195
196         void *shb_data = buffer + sizeof(struct net_buffer);
197         memcpy((void *)shb_data, p->payload, length);
198         tcp_recved(pcb, p->tot_len);
199         pbuf_free(p);
200     } else {
201         assert(buffer);
202         nb->size = 0;
203         nb->descriptor = socket->descriptor;
204         nb->accepted_descriptor = 0;
205         nb->host_address.s_addr = 0;
206         nb->port = 0;
207         debug_printf("%s(%d): close\n", __func__, socket->descriptor);
208         // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
209     }
210     nc->buffers[nc->next_free] = NULL;
211     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
212     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
213     
214     debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
215     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
216                        0, 0, 1);
217     assert(err_is_ok(err));
218     err = devq_notify((struct devq *)nc->queue);
219     assert(err_is_ok(err));
220
221     // debug_printf("%s: notifing\n", __func__);
222     // struct net_sockets_binding *binding = connection->connection->binding;
223     // debug_printf("%s: done\n", __func__);
224     return ERR_OK;
225 }
226
227 static void net_tcp_error(void *arg, err_t err)
228 {
229     struct socket_connection *socket = arg;
230     // struct network_connection *nc = socket->connection;
231     
232     debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, err);
233     socket->tcp_socket = NULL; // invalidate
234
235     // uint32_t length = 0;
236     // void *buffer = nc->buffers[nc->next_free];
237     // struct net_buffer *nb = buffer;
238     //
239     // assert(buffer);
240     // nb->size = 0;
241     // nb->descriptor = socket->descriptor;
242     // nb->accepted_descriptor = 0;
243     // nb->host_address.s_addr = 0;
244     // nb->port = 0;
245     // debug_printf("%s(%d): close on error\n", __func__, socket->descriptor);
246     // nc->buffers[nc->next_free] = NULL;
247     // nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
248     // assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
249     //
250     // // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
251     // err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
252     //                    0, 0, 1);
253     // assert(err_is_ok(err));
254     // err = devq_notify((struct devq *)nc->queue);
255     // assert(err_is_ok(err));
256 }
257
258 static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
259 {
260     struct socket_connection *socket = arg;
261     struct network_connection *nc = socket->connection;
262     bool notify = false;
263     errval_t err;
264
265     while (len > 0) {
266         // debug_printf("%s(%d): %d  %zx:%zd:%zd %zx:%zd:%zd\n", __func__, socket->descriptor, len,
267         //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
268         //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
269         assert(socket->send_frames[0].length);
270         if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
271             socket->send_frames[0].sent += len;
272             len = 0;
273         } else {
274             len -= socket->send_frames[0].length - socket->send_frames[0].sent;
275             
276             socket->send_frames[0].length += sizeof(struct net_buffer);
277             // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
278             err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, 2);
279             if (!err_is_ok(err))
280                 debug_printf("%s: err %zd\n", __func__, err);
281             assert(err_is_ok(err));
282             notify = true;
283             socket->send_frames[0] = socket->send_frames[1];
284             socket->send_frames[1].sent = 0;
285             socket->send_frames[1].length = 0;
286             socket->send_frames[1].offset = 0;
287         }
288     }
289     if (notify) {
290         err = devq_notify((struct devq *)nc->queue);
291         assert(err_is_ok(err));
292     }
293     return ERR_OK;
294 }
295
296 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
297 {
298     struct socket_connection *socket = arg;
299     struct network_connection *nc = socket->connection;
300     struct socket_connection *accepted_socket;
301
302     accepted_socket = allocate_socket(nc);
303     accepted_socket->udp_socket = NULL;
304     accepted_socket->tcp_socket = newpcb;
305     tcp_arg(accepted_socket->tcp_socket, accepted_socket);
306     tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
307     tcp_err(accepted_socket->tcp_socket, net_tcp_error);
308     tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
309
310     debug_printf("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
311     // errval_t err = nc->binding->tx_vtbl.accepted(nc->binding, BLOCKING_CONT, socket->descriptor, accepted_socket->descriptor, 0, 0, SYS_ERR_OK);
312     // assert(err_is_ok(err));
313
314     errval_t err;
315     uint32_t length = 0;
316     void *buffer = nc->buffers[nc->next_free];
317     struct net_buffer *nb = buffer;
318
319     nb->size = 0;
320     nb->descriptor = socket->descriptor;
321     nb->accepted_descriptor = accepted_socket->descriptor;
322     nb->host_address.s_addr = 0;
323     nb->port = 0;
324     debug_printf("%s(%d): accepted %p\n", __func__, socket->descriptor, newpcb);
325
326     nc->buffers[nc->next_free] = NULL;
327     nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
328     assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
329     
330     // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
331     err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
332                        0, 0, 1);
333     assert(err_is_ok(err));
334     err = devq_notify((struct devq *)nc->queue);
335     assert(err_is_ok(err));
336
337     return ERR_OK;
338 }
339
340
341 static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
342 {
343     struct network_connection *nc;
344
345     nc = network_connections;
346     while (nc) {
347         if (nc->queue_id == queue_id)
348             break;
349         nc = nc->next;
350     }
351     assert(nc);
352
353     binding->st = nc;
354     nc->binding = binding;
355     devq_set_state((struct devq *)nc->queue, nc);
356
357     return SYS_ERR_OK;
358 }
359
360 static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
361 {
362     struct network_connection *nc;
363     struct socket_connection *socket;
364
365     nc = binding->st;
366     socket = allocate_socket(nc);
367     *descriptor = socket->descriptor;
368
369     struct udp_pcb *pcb = udp_new();
370     assert(pcb);
371     socket->udp_socket = pcb;
372     udp_recv(socket->udp_socket, net_udp_receive, socket);
373
374     return SYS_ERR_OK;
375 }
376
377 static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
378 {
379     struct network_connection *nc;
380     struct socket_connection *socket;
381
382     nc = binding->st;
383     socket = allocate_socket(nc);
384     *descriptor = socket->descriptor;
385
386     struct tcp_pcb *pcb = tcp_new();
387     assert(pcb);
388     socket->tcp_socket = pcb;
389     tcp_arg(pcb, socket);
390     tcp_recv(socket->tcp_socket, net_tcp_receive);
391
392     return SYS_ERR_OK;
393 }
394
395 static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
396 {
397     struct network_connection *nc;
398     struct socket_connection *socket;
399
400     nc = binding->st;
401     socket = nc->sockets;
402     while (socket) {
403         if (socket->descriptor == descriptor)
404             break;
405         socket = socket->next;
406     }
407     assert(socket);
408
409     if (socket->udp_socket) {
410         ip_addr_t ip;
411
412         ip.addr = ip_address;
413         *error = udp_bind(socket->udp_socket, &ip, port);
414         assert(err_is_ok(*error));
415         *error = SYS_ERR_OK;
416
417         debug_printf("UDP ECHO bind done.\n");
418     } else if (socket->tcp_socket) {
419         ip_addr_t ip;
420
421         ip.addr = ip_address;
422         debug_printf("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
423         *error = tcp_bind(socket->tcp_socket, &ip, port);
424         assert(err_is_ok(*error));
425         *error = SYS_ERR_OK;
426
427         debug_printf("TCP ECHO bind done.\n");
428     }
429     return SYS_ERR_OK;
430 }
431
432 static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
433 {
434     struct network_connection *nc;
435     struct socket_connection *socket;
436
437     nc = binding->st;
438     socket = nc->sockets;
439     while (socket) {
440         if (socket->descriptor == descriptor)
441             break;
442         socket = socket->next;
443     }
444     assert(socket);
445     assert(socket->tcp_socket);
446     socket->tcp_socket = tcp_listen(socket->tcp_socket);
447     debug_printf("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
448     tcp_accept(socket->tcp_socket, net_tcp_accepted);
449     tcp_err(socket->tcp_socket, net_tcp_error);
450     // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
451     assert(socket->tcp_socket);
452
453     *error = SYS_ERR_OK;
454     return SYS_ERR_OK;
455 }
456
457 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
458 {
459     struct socket_connection *socket = arg;
460     struct network_connection *nc = socket->connection;
461
462     errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK);
463     assert(err_is_ok(err));
464
465     return SYS_ERR_OK;
466 }
467
468 static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
469 {
470     struct network_connection *nc;
471     struct socket_connection *socket;
472
473     nc = binding->st;
474     socket = nc->sockets;
475     while (socket) {
476         if (socket->descriptor == descriptor)
477             break;
478         socket = socket->next;
479     }
480     assert(socket);
481
482     if (socket->udp_socket) {
483         ip_addr_t addr;
484         addr.addr = ip_address;
485         assert(udp_connect(socket->udp_socket, &addr, port) == ERR_OK);
486         *error = SYS_ERR_OK;
487     } else if (socket->tcp_socket) {
488         ip_addr_t addr;
489         addr.addr = ip_address;
490         assert(tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected) == ERR_OK);
491         *error = SYS_ERR_OK;
492     }
493
494     return SYS_ERR_OK;
495 }
496
497 static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t descriptor, errval_t *error)
498 {
499     struct network_connection *nc;
500     struct socket_connection *socket, *last;
501
502     nc = binding->st;
503     socket = nc->sockets;
504     last = NULL;
505     while (socket) {
506         if (socket->descriptor == descriptor)
507             break;
508         last = socket;
509         socket = socket->next;
510     }
511     assert(socket);
512     if (socket->udp_socket) {
513         udp_recv(socket->udp_socket, NULL, NULL);
514         udp_remove(socket->udp_socket);
515     } else if (socket->tcp_socket) {
516         tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
517         // tcp_accept(socket->tcp_socket, NULL);
518         err_t e;
519         debug_printf("%s(%d): tcp_close %p\n", __func__, descriptor, socket->tcp_socket);
520         e = tcp_close(socket->tcp_socket);
521         assert(e == ERR_OK);
522     }
523
524     debug_printf("%s(%d):\n", __func__, descriptor);
525     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]);
526     if (last)
527         last->next = socket->next;
528     else
529         nc->sockets = socket->next;
530     free(socket);
531
532     *error = SYS_ERR_OK;
533     return SYS_ERR_OK;
534 }
535
536 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
537                        uint64_t* queue_id)
538 {
539     struct network_connection *nc;
540     static uint64_t qid = 1;
541
542     nc = malloc(sizeof(struct network_connection));
543     assert(nc);
544     nc->next = network_connections;
545     network_connections = nc;
546
547     nc->sockets = NULL;
548     nc->binding = NULL;
549     nc->queue = q;
550     *queue_id = qid++;
551     nc->queue_id = *queue_id;
552     memset(nc->buffers, 0, sizeof(nc->buffers));
553     nc->next_free = 0;
554     nc->next_used = 0;
555     return SYS_ERR_OK;
556 }
557
558 static errval_t q_destroy(struct descq* q)
559 {
560     return SYS_ERR_OK;
561 }
562
563
564 static errval_t q_notify(struct descq* q)
565 {
566     struct devq* queue = (struct devq *)q;
567     errval_t err = SYS_ERR_OK;
568     //errval_t err2 = SYS_ERR_OK;
569     regionid_t rid;
570     genoffset_t offset;
571     genoffset_t length;
572     genoffset_t valid_data;
573     genoffset_t valid_length;
574     uint64_t flags;
575     struct network_connection *nc;
576     bool notify = 0;
577
578     // debug_printf("%s: \n", __func__);
579     nc = devq_get_state(queue);
580     for (;;) {
581         err = devq_dequeue(queue, &rid, &offset, &length,
582                            &valid_data, &valid_length, &flags);
583         if (err_is_fail(err)) {
584             break;
585         } else {
586             // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
587             if (flags == 1) { // receiving buffer
588                 // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
589                 assert(!nc->buffers[nc->next_used]);
590                 nc->buffers[nc->next_used] = nc->buffer_start + offset;
591                 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
592             } else if (flags == 2) { // transmitting buffer
593                 struct socket_connection *socket;
594                 void *buffer;
595                 buffer = offset + nc->buffer_start;
596                 struct net_buffer *nb = buffer;
597                 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
598
599                 // debug_printf("%s: %p\n", __func__, buffer);
600
601                 socket = nc->sockets;
602                 while (socket) {
603                     if (socket->descriptor == nb->descriptor)
604                         break;
605                     socket = socket->next;
606                 }
607                 assert(socket);
608
609                 // 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);
610                 if (socket->udp_socket) {
611                     struct udp_pcb *pcb = socket->udp_socket;
612                     struct pbuf *p;
613
614                     p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
615                     assert(p);
616                     memcpy(p->payload, shb_data, nb->size);
617
618                     ip_addr_t addr;
619                     uint16_t port;
620                     port = nb->port;
621                     addr.addr = nb->host_address.s_addr;
622                     // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
623                     err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
624                     assert(err_is_ok(err));
625                     notify = 1;
626                     // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
627                     if (port && addr.addr) {
628                         assert(udp_sendto(pcb, p, &addr, port) == ERR_OK);
629                     } else {
630                         assert(udp_send(pcb, p) == ERR_OK);
631                     }
632                     pbuf_free(p);
633                 } else if (socket->tcp_socket) {
634                     err_t e;
635                     // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
636                     
637                     if (socket->send_frames[0].length == 0) {
638                         
639                     } else {
640                         assert(socket->send_frames[1].length == 0);
641                     }
642                     // debug_printf("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
643                     e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
644                     if (e != ERR_OK)
645                         debug_printf("%s: e=%d\n", __func__, e);
646                     assert(e == ERR_OK);
647                     e = tcp_output(socket->tcp_socket);
648                     assert(e == ERR_OK);
649                     
650                     if (socket->send_frames[0].length == 0) {
651                         socket->send_frames[0].offset = offset;
652                         socket->send_frames[0].length = length - sizeof(struct net_buffer);
653                     } else {
654                         socket->send_frames[1].offset = offset;
655                         socket->send_frames[1].length = length - sizeof(struct net_buffer);
656                     }
657                     // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, offset, length);
658                     // err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
659                     // assert(err_is_ok(err));
660                     // notify = 1;
661                 }
662             }
663         }
664     }
665
666     if (notify) {
667         // debug_printf("notify>\n");
668         err = devq_notify(queue);
669         // debug_printf("notify<\n");
670         assert(err_is_ok(err));
671     }
672
673     return SYS_ERR_OK;
674 }
675
676 static errval_t q_reg(struct descq* q, struct capref cap,
677                     regionid_t rid)
678 {
679     struct frame_identity pa;
680     struct network_connection *nc;
681
682     nc = devq_get_state((struct devq *)q);
683
684     errval_t err = frame_identify(cap, &pa);
685     assert(err_is_ok(err));
686     nc->buffer_cap = cap;
687     nc->region_id = rid;
688
689     nc->buffer_size = pa.bytes;
690     err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
691     assert(err_is_ok(err));
692
693     return SYS_ERR_OK;
694 }
695
696
697 static errval_t q_dereg(struct descq* q, regionid_t rid)
698 {
699     return SYS_ERR_OK;
700 }
701     
702
703 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
704 {
705     return SYS_ERR_OK;
706 }
707
708
709 static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
710     .register_queue_call = net_register_queue,
711     .new_udp_socket_call = net_udp_socket,
712     .new_tcp_socket_call = net_tcp_socket,
713     .bind_call = net_bind,
714     .connect_call = net_connect,
715     .delete_socket_call = net_delete_socket,
716     .listen_call = net_listen,
717 };
718
719
720 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
721 {
722     binding->rpc_rx_vtbl = rpc_rx_vtbl;
723     return SYS_ERR_OK;
724 }
725
726
727 static void export_cb(void *st, errval_t err, iref_t iref)
728 {
729     assert(err_is_ok(err));
730     err = nameservice_register("net_sockets", iref);
731     assert(err_is_ok(err));
732 }
733
734 int main(int argc, char *argv[])
735 {
736     errval_t err;
737
738     debug_printf("Net socket server started for e1000 %s.\n", argv[2]);
739
740     char servicename[64];
741     snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
742
743     /* connect to the network */
744     err = networking_init(servicename, 0);
745     if (err_is_fail(err)) {
746         USER_PANIC_ERR(err, "Failed to initialize the network");
747     }
748
749
750     struct descq *exp_queue;
751     struct descq_func_pointer f;
752
753     f.notify = q_notify;
754     f.create = q_create;
755     f.destroy = q_destroy;
756     f.reg = q_reg;
757     f.dereg = q_dereg;
758     f.control = q_control;
759
760     err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
761                        true, true, 0, NULL, &f);
762     assert(err_is_ok(err));
763
764
765     err = net_sockets_export(NULL, export_cb, connect_cb, get_default_waitset(),
766                             IDC_EXPORT_FLAGS_DEFAULT);
767     assert(err_is_ok(err));
768
769     while(1) {
770         event_dispatch(get_default_waitset());
771
772         // networking_poll();
773     }
774
775     debug_printf("UDP ECHO termiated.\n");
776
777     return 0;
778 }