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