741123876444bb5cfd1b88702b542530a823e0ec
[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         err_t e;
485
486         addr.addr = ip_address;
487         e = udp_connect(socket->udp_socket, &addr, port);
488         assert(e == ERR_OK);
489         *error = SYS_ERR_OK;
490     } else if (socket->tcp_socket) {
491         ip_addr_t addr;
492         err_t e;
493
494         addr.addr = ip_address;
495         e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
496         assert(e == ERR_OK);
497         *error = SYS_ERR_OK;
498     }
499
500     return SYS_ERR_OK;
501 }
502
503 static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t descriptor, errval_t *error)
504 {
505     struct network_connection *nc;
506     struct socket_connection *socket, *last;
507
508     nc = binding->st;
509     socket = nc->sockets;
510     last = NULL;
511     while (socket) {
512         if (socket->descriptor == descriptor)
513             break;
514         last = socket;
515         socket = socket->next;
516     }
517     assert(socket);
518     if (socket->udp_socket) {
519         udp_recv(socket->udp_socket, NULL, NULL);
520         udp_remove(socket->udp_socket);
521     } else if (socket->tcp_socket) {
522         tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
523         // tcp_accept(socket->tcp_socket, NULL);
524         err_t e;
525         debug_printf("%s(%d): tcp_close %p\n", __func__, descriptor, socket->tcp_socket);
526         e = tcp_close(socket->tcp_socket);
527         assert(e == ERR_OK);
528     }
529
530     debug_printf("%s(%d):\n", __func__, descriptor);
531     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]);
532     if (last)
533         last->next = socket->next;
534     else
535         nc->sockets = socket->next;
536     free(socket);
537
538     *error = SYS_ERR_OK;
539     return SYS_ERR_OK;
540 }
541
542 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
543                        uint64_t* queue_id)
544 {
545     struct network_connection *nc;
546     static uint64_t qid = 1;
547
548     nc = malloc(sizeof(struct network_connection));
549     assert(nc);
550     nc->next = network_connections;
551     network_connections = nc;
552
553     nc->sockets = NULL;
554     nc->binding = NULL;
555     nc->queue = q;
556     *queue_id = qid++;
557     nc->queue_id = *queue_id;
558     memset(nc->buffers, 0, sizeof(nc->buffers));
559     nc->next_free = 0;
560     nc->next_used = 0;
561     return SYS_ERR_OK;
562 }
563
564 static errval_t q_destroy(struct descq* q)
565 {
566     return SYS_ERR_OK;
567 }
568
569
570 static errval_t q_notify(struct descq* q)
571 {
572     struct devq* queue = (struct devq *)q;
573     errval_t err = SYS_ERR_OK;
574     //errval_t err2 = SYS_ERR_OK;
575     regionid_t rid;
576     genoffset_t offset;
577     genoffset_t length;
578     genoffset_t valid_data;
579     genoffset_t valid_length;
580     uint64_t flags;
581     struct network_connection *nc;
582     bool notify = 0;
583
584     // debug_printf("%s: \n", __func__);
585     nc = devq_get_state(queue);
586     for (;;) {
587         err = devq_dequeue(queue, &rid, &offset, &length,
588                            &valid_data, &valid_length, &flags);
589         if (err_is_fail(err)) {
590             break;
591         } else {
592             // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
593             if (flags == 1) { // receiving buffer
594                 // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
595                 assert(!nc->buffers[nc->next_used]);
596                 nc->buffers[nc->next_used] = nc->buffer_start + offset;
597                 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
598             } else if (flags == 2) { // transmitting buffer
599                 struct socket_connection *socket;
600                 void *buffer;
601                 buffer = offset + nc->buffer_start;
602                 struct net_buffer *nb = buffer;
603                 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
604
605                 // debug_printf("%s: %p\n", __func__, buffer);
606
607                 socket = nc->sockets;
608                 while (socket) {
609                     if (socket->descriptor == nb->descriptor)
610                         break;
611                     socket = socket->next;
612                 }
613                 assert(socket);
614
615                 // 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);
616                 if (socket->udp_socket) {
617                     struct udp_pcb *pcb = socket->udp_socket;
618                     struct pbuf *p;
619
620                     p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
621                     assert(p);
622                     memcpy(p->payload, shb_data, nb->size);
623
624                     ip_addr_t addr;
625                     uint16_t port;
626                     port = nb->port;
627                     addr.addr = nb->host_address.s_addr;
628                     // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
629                     err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
630                     assert(err_is_ok(err));
631                     notify = 1;
632                     // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
633                     if (port && addr.addr) {
634                         err_t e;
635
636                         e = udp_sendto(pcb, p, &addr, port);
637                         if (e != ERR_OK)
638                             debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
639                         assert(e == ERR_OK);
640                     } else {
641                         err_t e;
642
643                         e = udp_send(pcb, p);
644                         if (e != ERR_OK)
645                             debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
646                         assert(e == ERR_OK);
647                     }
648                     pbuf_free(p);
649                 } else if (socket->tcp_socket) {
650                     err_t e;
651                     // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
652                     
653                     if (socket->send_frames[0].length == 0) {
654                         
655                     } else {
656                         assert(socket->send_frames[1].length == 0);
657                     }
658                     // debug_printf("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
659                     e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
660                     if (e != ERR_OK)
661                         debug_printf("%s: e=%d\n", __func__, e);
662                     assert(e == ERR_OK);
663                     e = tcp_output(socket->tcp_socket);
664                     assert(e == ERR_OK);
665                     
666                     if (socket->send_frames[0].length == 0) {
667                         socket->send_frames[0].offset = offset;
668                         socket->send_frames[0].length = length - sizeof(struct net_buffer);
669                     } else {
670                         socket->send_frames[1].offset = offset;
671                         socket->send_frames[1].length = length - sizeof(struct net_buffer);
672                     }
673                     // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, offset, length);
674                     // err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
675                     // assert(err_is_ok(err));
676                     // notify = 1;
677                 }
678             }
679         }
680     }
681
682     if (notify) {
683         // debug_printf("notify>\n");
684         err = devq_notify(queue);
685         // debug_printf("notify<\n");
686         assert(err_is_ok(err));
687     }
688
689     return SYS_ERR_OK;
690 }
691
692 static errval_t q_reg(struct descq* q, struct capref cap,
693                     regionid_t rid)
694 {
695     struct frame_identity pa;
696     struct network_connection *nc;
697
698     nc = devq_get_state((struct devq *)q);
699
700     errval_t err = frame_identify(cap, &pa);
701     assert(err_is_ok(err));
702     nc->buffer_cap = cap;
703     nc->region_id = rid;
704
705     nc->buffer_size = pa.bytes;
706     err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
707     assert(err_is_ok(err));
708
709     return SYS_ERR_OK;
710 }
711
712
713 static errval_t q_dereg(struct descq* q, regionid_t rid)
714 {
715     return SYS_ERR_OK;
716 }
717     
718
719 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
720 {
721     return SYS_ERR_OK;
722 }
723
724
725 static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
726     .register_queue_call = net_register_queue,
727     .new_udp_socket_call = net_udp_socket,
728     .new_tcp_socket_call = net_tcp_socket,
729     .bind_call = net_bind,
730     .connect_call = net_connect,
731     .delete_socket_call = net_delete_socket,
732     .listen_call = net_listen,
733 };
734
735
736 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
737 {
738     binding->rpc_rx_vtbl = rpc_rx_vtbl;
739     return SYS_ERR_OK;
740 }
741
742
743 static void export_cb(void *st, errval_t err, iref_t iref)
744 {
745     assert(err_is_ok(err));
746     err = nameservice_register("net_sockets", iref);
747     assert(err_is_ok(err));
748 }
749
750 int main(int argc, char *argv[])
751 {
752     errval_t err;
753
754     debug_printf("Net socket server started for e1000 %s.\n", argv[2]);
755
756     char servicename[64];
757     snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
758
759     /* connect to the network */
760     err = networking_init(servicename, NET_FLAGS_DO_DHCP);
761     if (err_is_fail(err)) {
762         USER_PANIC_ERR(err, "Failed to initialize the network");
763     }
764
765
766     struct descq *exp_queue;
767     struct descq_func_pointer f;
768
769     f.notify = q_notify;
770     f.create = q_create;
771     f.destroy = q_destroy;
772     f.reg = q_reg;
773     f.dereg = q_dereg;
774     f.control = q_control;
775
776     err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
777                        true, true, 0, NULL, &f);
778     assert(err_is_ok(err));
779
780
781     err = net_sockets_export(NULL, export_cb, connect_cb, get_default_waitset(),
782                             IDC_EXPORT_FLAGS_DEFAULT);
783     assert(err_is_ok(err));
784
785     while(1) {
786         event_dispatch(get_default_waitset());
787
788         // networking_poll();
789     }
790
791     debug_printf("UDP ECHO termiated.\n");
792
793     return 0;
794 }