1/**
2 * @brief
3 *  Net socket server
4 */
5
6/*
7 * Copyright (c) 2017, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <getopt.h>
16
17#include <barrelfish/barrelfish.h>
18#include <barrelfish/deferred.h>
19#include <barrelfish/nameservice_client.h>
20
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#include "netss.h"
42
43struct socket_connection;
44
45struct network_connection {
46    struct network_connection *next;
47
48    struct capref buffer_cap;
49    struct descq *queue;
50    uint64_t queue_id;
51    regionid_t region_id;
52    void *buffer_start;
53    uint64_t buffer_size;
54
55    void *buffers[NO_OF_BUFFERS];
56    uint64_t next_free, next_used;
57
58    struct net_sockets_binding *binding;
59
60    struct descq *buffer_queue;
61    struct socket_connection *sockets;
62};
63
64#define MAX_SEND_FRAMES 2
65
66struct send_frame {
67    genoffset_t offset;
68    genoffset_t sent, length;
69};
70
71struct socket_connection {
72    struct socket_connection *next;
73    struct network_connection *connection;
74    uint32_t descriptor;
75    struct send_frame send_frames[MAX_SEND_FRAMES];
76
77    struct udp_pcb *udp_socket;
78    struct tcp_pcb *tcp_socket;
79};
80
81static struct network_connection *network_connections = NULL;
82static struct descq *exp_queue;
83
84static struct socket_connection * find_socket_connection(struct network_connection *nc, uint32_t descriptor)
85{
86    struct socket_connection *socket;
87
88    socket = nc->sockets;
89    while (socket) {
90        if (socket->descriptor == descriptor)
91            break;
92        socket = socket->next;
93    }
94    return socket;
95}
96
97static struct socket_connection * allocate_socket(struct network_connection *nc)
98{
99    struct socket_connection *last, *socket;
100    uint32_t last_descriptor = 0;
101
102    last = NULL;
103    socket = nc->sockets;
104    while (socket) {
105        if (socket->descriptor != last_descriptor + 1)
106            break;
107        last = socket;
108        last_descriptor = last->descriptor;
109        socket = socket->next;
110    }
111
112    socket = malloc(sizeof(struct socket_connection));
113    assert(socket);
114    memset(socket, 0, sizeof(struct socket_connection));
115
116    if (last) {
117        socket->next = last->next;
118        last->next = socket;
119    } else {
120        nc->sockets = socket;
121    }
122
123    socket->descriptor = last_descriptor + 1;
124
125    socket->connection = nc;
126    socket->udp_socket = NULL;
127    socket->tcp_socket = NULL;
128
129    memset(socket->send_frames, 0, sizeof(socket->send_frames));
130
131    return socket;
132}
133
134static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
135{
136    struct socket_connection *connection = arg;
137    struct network_connection *nc = connection->connection;
138    errval_t err;
139
140    assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
141
142    uint32_t length = p->tot_len;
143    void *buffer = nc->buffers[nc->next_free];
144
145    if (!buffer) {
146        debug_printf("%s: drop\n", __func__);
147        pbuf_free(p);
148        return;
149    }
150
151    assert(buffer);
152    nc->buffers[nc->next_free] = NULL;
153    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
154    assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
155    struct net_buffer *nb = buffer;
156
157    nb->size = length;
158    nb->descriptor = connection->descriptor;
159    nb->host_address.s_addr = addr->addr;
160    nb->port = port;
161    // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
162
163    void *shb_data = buffer + sizeof(struct net_buffer);
164
165    struct pbuf *it;
166    uint32_t pos;
167
168    it = p;
169    for (pos = 0; pos < length; ) {
170        assert(it);
171        memcpy((void *)shb_data + pos, it->payload, it->len);
172        pos += it->len;
173        it = it->next;
174    }
175    pbuf_free(p);
176    err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
177                       0, 0, NET_EVENT_RECEIVED);
178    assert(err_is_ok(err));
179    err = devq_notify((struct devq *)nc->queue);
180    assert(err_is_ok(err));
181    // debug_printf("%s: notifing\n", __func__);
182    // struct net_sockets_binding *binding = connection->connection->binding;
183    // debug_printf("%s: done\n", __func__);
184}
185
186
187static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
188{
189    struct socket_connection *socket = arg;
190    struct network_connection *nc = socket->connection;
191    errval_t err;
192    uint32_t length = 0;
193    void *buffer = nc->buffers[nc->next_free];
194    struct net_buffer *nb = buffer;
195
196    // debug_printf("%s(%d): pcb:%p  p:%p\n", __func__, socket->descriptor, pcb, p);
197    if (p) {
198        // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
199        assert(p->len == p->tot_len);
200        length = p->tot_len;
201
202        if (!buffer) {
203            debug_printf("%s: drop\n", __func__);
204            pbuf_free(p);
205            return ERR_OK;
206        }
207        assert(buffer);
208        nb->size = length;
209        nb->descriptor = socket->descriptor;
210        nb->accepted_descriptor = 0;
211        nb->host_address.s_addr = 0;
212        nb->port = 0;
213        // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
214
215        void *shb_data = buffer + sizeof(struct net_buffer);
216        memcpy((void *)shb_data, p->payload, length);
217        tcp_recved(pcb, p->tot_len);
218        pbuf_free(p);
219    } else {
220        assert(buffer);
221        nb->size = 0;
222        nb->descriptor = socket->descriptor;
223        nb->accepted_descriptor = 0;
224        nb->host_address.s_addr = 0;
225        nb->port = 0;
226        // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
227        // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
228        tcp_err(socket->tcp_socket, NULL);
229        // debug_printf("%s(%d): close\n", __func__, socket->descriptor);
230        // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
231    }
232    nc->buffers[nc->next_free] = NULL;
233    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
234    assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
235
236    // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
237    err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
238                       0, 0, NET_EVENT_RECEIVED);
239
240    assert(err_is_ok(err));
241    err = devq_notify((struct devq *)nc->queue);
242    assert(err_is_ok(err));
243
244    // debug_printf("%s: notifing\n", __func__);
245    // struct net_sockets_binding *binding = connection->connection->binding;
246    // debug_printf("%s: done\n", __func__);
247    return ERR_OK;
248}
249
250static void net_tcp_error(void *arg, err_t tcp_err)
251{
252    struct socket_connection *socket = arg;
253    struct network_connection *nc = socket->connection;
254    errval_t err;
255
256    // debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, tcp_err);
257    // debug_printf_to_log("%s(%d): error %d", __func__, socket->descriptor, tcp_err);
258    tcp_sent(socket->tcp_socket, NULL);
259    tcp_recv(socket->tcp_socket, NULL);
260    socket->tcp_socket = NULL; // invalidate
261
262    void *buffer = nc->buffers[nc->next_free];
263    assert(buffer);
264    struct net_buffer *nb = buffer;
265    nb->size = 0;
266    nb->descriptor = socket->descriptor;
267    nb->accepted_descriptor = 0;
268    nb->host_address.s_addr = 0;
269    nb->port = 0;
270    nc->buffers[nc->next_free] = NULL;
271    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
272
273    err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer),
274                       0, 0, NET_EVENT_RECEIVED);
275    assert(err_is_ok(err));
276    // debug_printf_to_log("%s(%d): close", __func__, socket->descriptor);
277
278    err = devq_notify((struct devq *)nc->queue);
279    assert(err_is_ok(err));
280
281
282    // uint32_t length = 0;
283    // void *buffer = nc->buffers[nc->next_free];
284    // struct net_buffer *nb = buffer;
285    //
286    // assert(buffer);
287    // nb->size = 0;
288    // nb->descriptor = socket->descriptor;
289    // nb->accepted_descriptor = 0;
290    // nb->host_address.s_addr = 0;
291    // nb->port = 0;
292    // debug_printf("%s(%d): close on error\n", __func__, socket->descriptor);
293    // nc->buffers[nc->next_free] = NULL;
294    // nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
295    // assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
296    //
297    // // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
298    // err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
299    //                    0, 0, 1);
300    // assert(err_is_ok(err));
301    // err = devq_notify((struct devq *)nc->queue);
302    // assert(err_is_ok(err));
303}
304
305static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
306{
307    struct socket_connection *socket = arg;
308    struct network_connection *nc = socket->connection;
309    bool notify = false;
310    errval_t err;
311
312    while (len > 0) {
313        // debug_printf_to_log("%s(%d): %d  %lx:%ld:%ld  %lx:%ld:%ld", __func__, socket->descriptor, len,
314            // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
315            // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
316        // debug_printf("%s(%d): %d  %zx:%zd:%zd %zx:%zd:%zd\n", __func__, socket->descriptor, len,
317        //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
318        //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
319        if (!socket->send_frames[0].length)
320            debug_print_log();
321        assert(socket->send_frames[0].length);
322        if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
323            socket->send_frames[0].sent += len;
324            len = 0;
325        } else {
326            len -= socket->send_frames[0].length - socket->send_frames[0].sent;
327
328            socket->send_frames[0].length += sizeof(struct net_buffer);
329            // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
330            //
331            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);
332            if (!err_is_ok(err))
333                debug_printf("%s: err %zd\n", __func__, err);
334            assert(err_is_ok(err));
335            notify = true;
336            socket->send_frames[0] = socket->send_frames[1];
337            socket->send_frames[1].sent = 0;
338            socket->send_frames[1].length = 0;
339            socket->send_frames[1].offset = 0;
340        }
341    }
342    if (notify) {
343        err = devq_notify((struct devq *)nc->queue);
344        assert(err_is_ok(err));
345    }
346    return ERR_OK;
347}
348
349static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
350{
351    struct socket_connection *socket = arg;
352    struct network_connection *nc = socket->connection;
353    struct socket_connection *accepted_socket;
354
355    newpcb->flags |= TF_NODELAY;
356
357    accepted_socket = allocate_socket(nc);
358    accepted_socket->udp_socket = NULL;
359    accepted_socket->tcp_socket = newpcb;
360    tcp_arg(accepted_socket->tcp_socket, accepted_socket);
361    tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
362    tcp_err(accepted_socket->tcp_socket, net_tcp_error);
363    tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
364
365    // debug_printf("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
366    // errval_t err = nc->binding->tx_vtbl.accepted(nc->binding, BLOCKING_CONT, socket->descriptor, accepted_socket->descriptor, 0, 0, SYS_ERR_OK);
367    // assert(err_is_ok(err));
368
369    errval_t err;
370    uint32_t length = 0;
371    void *buffer = nc->buffers[nc->next_free];
372    struct net_buffer *nb = buffer;
373
374    nb->size = 0;
375    nb->descriptor = socket->descriptor;
376    nb->accepted_descriptor = accepted_socket->descriptor;
377    nb->host_address.s_addr = newpcb->remote_ip.addr;
378    nb->port = newpcb->remote_port;
379    // debug_printf_to_log("%s(%d): accepted", __func__, accepted_socket->descriptor);
380
381    nc->buffers[nc->next_free] = NULL;
382    nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
383    assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
384
385    // debug_printf("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__, buffer - nc->buffer_start, sizeof(struct net_buffer) + length, nb->descriptor);
386    err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
387                       0, 0, NET_EVENT_ACCEPT);
388    assert(err_is_ok(err));
389    err = devq_notify((struct devq *)nc->queue);
390    assert(err_is_ok(err));
391
392    return ERR_OK;
393}
394
395static errval_t net_request_descq_ep(struct net_sockets_binding *binding, uint16_t core,
396                                     struct capref* ep)
397{
398    errval_t err;
399    err = slot_alloc(ep);
400    if (err_is_fail(err)) {
401        return err;
402    }
403
404    err = descq_create_ep(exp_queue, core, ep);
405    if (err_is_fail(err)) {
406        slot_free(*ep);
407    }
408    return err;
409}
410
411static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
412{
413    struct network_connection *nc;
414
415    nc = network_connections;
416    while (nc) {
417        if (nc->queue_id == queue_id)
418            break;
419        nc = nc->next;
420    }
421    assert(nc);
422
423    binding->st = nc;
424    nc->binding = binding;
425    devq_set_state((struct devq *)nc->queue, nc);
426
427    return SYS_ERR_OK;
428}
429
430static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
431{
432    struct network_connection *nc;
433    struct socket_connection *socket;
434
435    nc = binding->st;
436    socket = allocate_socket(nc);
437    *descriptor = socket->descriptor;
438
439    struct udp_pcb *pcb = udp_new();
440    assert(pcb);
441    socket->udp_socket = pcb;
442    udp_recv(socket->udp_socket, net_udp_receive, socket);
443
444    return SYS_ERR_OK;
445}
446
447static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
448{
449    struct network_connection *nc;
450    struct socket_connection *socket;
451
452    nc = binding->st;
453    socket = allocate_socket(nc);
454    *descriptor = socket->descriptor;
455
456    struct tcp_pcb *pcb = tcp_new();
457    assert(pcb);
458    pcb->flags |= TF_NODELAY;
459    socket->tcp_socket = pcb;
460    tcp_arg(pcb, socket);
461    tcp_recv(socket->tcp_socket, net_tcp_receive);
462
463    return SYS_ERR_OK;
464}
465
466static 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)
467{
468    struct network_connection *nc;
469    struct socket_connection *socket;
470
471    nc = binding->st;
472    socket = find_socket_connection(nc, descriptor);
473    assert(socket);
474
475    if (socket->udp_socket) {
476        ip_addr_t ip;
477
478        ip.addr = ip_address;
479        *error = udp_bind(socket->udp_socket, &ip, port);
480        assert(err_is_ok(*error));
481        *bound_port = socket->udp_socket->local_port;
482        *error = SYS_ERR_OK;
483    } else if (socket->tcp_socket) {
484        ip_addr_t ip;
485
486        ip.addr = ip_address;
487        // debug_printf("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
488        *error = tcp_bind(socket->tcp_socket, &ip, port);
489        assert(err_is_ok(*error));
490        *bound_port = socket->tcp_socket->local_port;
491        *error = SYS_ERR_OK;
492    }
493    return SYS_ERR_OK;
494}
495
496static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
497{
498    struct network_connection *nc;
499    struct socket_connection *socket;
500
501    if (descriptor == -1) {
502        debug_print_log();
503        return SYS_ERR_OK;
504    }
505    nc = binding->st;
506    socket = find_socket_connection(nc, descriptor);
507    assert(socket);
508    assert(socket->tcp_socket);
509    socket->tcp_socket = tcp_listen(socket->tcp_socket);
510    // debug_printf("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
511    tcp_accept(socket->tcp_socket, net_tcp_accepted);
512    tcp_err(socket->tcp_socket, net_tcp_error);
513    // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
514    assert(socket->tcp_socket);
515
516    *error = SYS_ERR_OK;
517    return SYS_ERR_OK;
518}
519
520static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
521{
522    struct socket_connection *socket = arg;
523    struct network_connection *nc = socket->connection;
524
525    errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK, tpcb->remote_ip.addr, tpcb->remote_port);
526    assert(err_is_ok(err));
527
528    return SYS_ERR_OK;
529}
530
531static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
532{
533    struct network_connection *nc;
534    struct socket_connection *socket;
535
536    nc = binding->st;
537    socket = find_socket_connection(nc, descriptor);
538    assert(socket);
539
540    if (socket->udp_socket) {
541        ip_addr_t addr;
542        err_t e;
543
544        addr.addr = ip_address;
545        e = udp_connect(socket->udp_socket, &addr, port);
546        assert(e == ERR_OK);
547        *error = SYS_ERR_OK;
548    } else if (socket->tcp_socket) {
549        ip_addr_t addr;
550        err_t e;
551
552        addr.addr = ip_address;
553        e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
554        assert(e == ERR_OK);
555        *error = SYS_ERR_OK;
556    }
557
558    return SYS_ERR_OK;
559}
560
561static void net_delete_socket(struct network_connection *nc, uint32_t descriptor)
562{
563    struct socket_connection *socket, *last;
564    errval_t err;
565
566    // debug_printf_to_log("%s(%d): tcp_close", __func__, descriptor);
567    socket = nc->sockets;
568    last = NULL;
569    while (socket) {
570        if (socket->descriptor == descriptor)
571            break;
572        last = socket;
573        socket = socket->next;
574    }
575    if (!socket)
576        debug_print_log();
577    assert(socket);
578    if (socket->udp_socket) {
579        udp_recv(socket->udp_socket, NULL, NULL);
580        udp_remove(socket->udp_socket);
581    } else if (socket->tcp_socket) {
582        tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
583        tcp_sent(socket->tcp_socket, NULL);
584        // tcp_accept(socket->tcp_socket, NULL);
585        err_t e;
586        e = tcp_close(socket->tcp_socket);
587        assert(e == ERR_OK);
588    }
589
590    // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
591        // socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
592        // socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
593    while (socket->send_frames[0].length) { // invaldate all sent frames
594        void *buffer;
595        struct net_buffer *nb;
596
597        // debug_printf_to_log("%s(%d): %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor,
598        //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
599        //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
600
601        socket->send_frames[0].length += sizeof(struct net_buffer);
602        buffer = socket->send_frames[0].offset + nc->buffer_start;
603        nb = buffer;
604        nb->descriptor = descriptor;
605        // debug_printf_to_log("%s.%d: enqueue %lx:%zd\n", __func__, __LINE__, socket->send_frames[0].offset, socket->send_frames[0].length);
606        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);
607        assert(err_is_ok(err));
608        socket->send_frames[0] = socket->send_frames[1];
609        socket->send_frames[1].sent = 0;
610        socket->send_frames[1].length = 0;
611        socket->send_frames[1].offset = 0;
612    }
613    // debug_printf("%s(%d):\n", __func__, descriptor);
614    // 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]);
615    if (last)
616        last->next = socket->next;
617    else
618        nc->sockets = socket->next;
619    free(socket);
620}
621
622static uint64_t qid = 1;
623
624static errval_t q_create(struct descq* q, uint64_t* queue_id)
625{
626    struct network_connection *nc;
627
628    nc = malloc(sizeof(struct network_connection));
629    assert(nc);
630    nc->next = network_connections;
631    network_connections = nc;
632
633    nc->sockets = NULL;
634    nc->binding = NULL;
635    nc->queue = q;
636    *queue_id = qid++;
637    nc->queue_id = *queue_id;
638    memset(nc->buffers, 0, sizeof(nc->buffers));
639    nc->next_free = 0;
640    nc->next_used = 0;
641    return SYS_ERR_OK;
642}
643
644static errval_t q_destroy(struct descq* q)
645{
646    return SYS_ERR_OK;
647}
648
649
650static errval_t q_notify(struct descq* q)
651{
652    struct devq* queue = (struct devq *)q;
653    errval_t err = SYS_ERR_OK;
654    //errval_t err2 = SYS_ERR_OK;
655    regionid_t rid;
656    genoffset_t offset;
657    genoffset_t length;
658    genoffset_t valid_data;
659    genoffset_t valid_length;
660    uint64_t event;
661    struct network_connection *nc;
662    bool notify = 0;
663
664    // debug_printf("%s: \n", __func__);
665    nc = devq_get_state(queue);
666    for (int i = 0; i < NETSOCKET_LOOP_ITER; i++) {
667        err = devq_dequeue(queue, &rid, &offset, &length,
668                           &valid_data, &valid_length, &event);
669        if (err_is_fail(err)) {
670            break;
671        } else {
672            void *buffer;
673            buffer = offset + nc->buffer_start;
674            struct net_buffer *nb = buffer;
675
676            //debug_printf_to_log("%s: dequeue %lx:%ld %ld  %d:%d", __func__, offset, length, event, nb->descriptor, nb->size);
677            //debug_printf(" offset %lu length %lu \n", offset, length);
678            if (event == NET_EVENT_RECEIVE) {
679                assert(!nc->buffers[nc->next_used]);
680                nc->buffers[nc->next_used] = nc->buffer_start + offset;
681                nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
682            } else if (event == NET_EVENT_SEND) {
683                struct socket_connection *socket;
684                void *shb_data = (void *)buffer + sizeof(struct net_buffer);
685
686                // debug_printf("%s: %p\n", __func__, buffer);
687// find the socket
688                socket = find_socket_connection(nc, nb->descriptor);
689                if (!socket)
690                    debug_printf("%s(%d): %p\n", __func__, nb->descriptor, socket);
691                assert(socket);
692
693                // 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);
694                if (socket->udp_socket) {
695                    struct udp_pcb *pcb = socket->udp_socket;
696                    struct pbuf *p;
697
698                    p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
699                    assert(p);
700                    memcpy(p->payload, shb_data, nb->size);
701
702                    ip_addr_t addr;
703                    uint16_t port;
704                    port = nb->port;
705                    addr.addr = nb->host_address.s_addr;
706                    // debug_printf("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
707                    err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
708                    assert(err_is_ok(err));
709                    notify = 1;
710                    // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
711                    if (port && addr.addr) {
712                        err_t e;
713
714                        e = udp_sendto(pcb, p, &addr, port);
715                        if (e != ERR_OK)
716                            debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
717                        assert(e == ERR_OK);
718                    } else {
719                        err_t e;
720
721                        e = udp_send(pcb, p);
722                        if (e != ERR_OK)
723                            debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
724                        assert(e == ERR_OK);
725                    }
726                    pbuf_free(p);
727                } else if (socket->tcp_socket) {
728                    err_t e;
729                    // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, event);
730
731                    if (socket->send_frames[0].length == 0) {
732
733                    } else {
734                        assert(socket->send_frames[1].length == 0);
735                    }
736                    // debug_printf("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
737                    e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
738                    if (e != ERR_OK)
739                        debug_printf("%s: e=%d\n", __func__, e);
740                    assert(e == ERR_OK);
741                    e = tcp_output(socket->tcp_socket);
742                    assert(e == ERR_OK);
743
744                    if (socket->send_frames[0].length == 0) {
745                        socket->send_frames[0].offset = offset;
746                        socket->send_frames[0].length = length - sizeof(struct net_buffer);
747                    } else {
748                        socket->send_frames[1].offset = offset;
749                        socket->send_frames[1].length = length - sizeof(struct net_buffer);
750                    }
751                    // debug_printf_to_log("%s(%d): tcp_send %lx:%ld    %p:%ld:%ld  %p:%ld:%ld", __func__, socket->descriptor, offset, length,
752                    //     socket->send_frames[0].offset, socket->send_frames[0].sent, socket->send_frames[0].length,
753                    //     socket->send_frames[1].offset, socket->send_frames[1].sent, socket->send_frames[1].length);
754                    // debug_printf("%s.%d: enqueue 2 %lx:%zd\n", __func__, __LINE__, offset, length);
755                    // err = devq_enqueue(queue, rid, offset, length, 0, 0, 2);
756                    // assert(err_is_ok(err));
757                    // notify = 1;
758                } else {
759                    err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
760                    assert(err_is_ok(err));
761                    notify = 1;
762                }
763            } else if (event == NET_EVENT_CLOSE) {
764                // struct net_buffer *nb = offset + nc->buffer_start;
765
766                // debug_printf("%s(%d): close\n", __func__, nb->descriptor);
767                net_delete_socket(nc, nb->descriptor);
768                err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_CLOSED);
769                assert(err_is_ok(err));
770                notify = 1;
771            } else {
772                debug_printf("%s: unknown event %ld!", __func__, event);
773                assert(0);
774            }
775        }
776    }
777
778    if (notify) {
779        // debug_printf("notify>\n");
780        err = devq_notify(queue);
781        // debug_printf("notify<\n");
782        assert(err_is_ok(err));
783    }
784
785    return SYS_ERR_OK;
786}
787
788static errval_t q_reg(struct descq* q, struct capref cap,
789                    regionid_t rid)
790{
791    struct frame_identity pa;
792    struct network_connection *nc;
793
794    nc = devq_get_state((struct devq *)q);
795
796    errval_t err = frame_identify(cap, &pa);
797    assert(err_is_ok(err));
798    nc->buffer_cap = cap;
799    nc->region_id = rid;
800
801    nc->buffer_size = pa.bytes;
802    err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
803    assert(err_is_ok(err));
804
805    return SYS_ERR_OK;
806}
807
808
809static errval_t q_dereg(struct descq* q, regionid_t rid)
810{
811    return SYS_ERR_OK;
812}
813
814
815static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
816{
817    return SYS_ERR_OK;
818}
819
820
821static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
822    .request_descq_ep_call = net_request_descq_ep,
823    .register_queue_call = net_register_queue,
824    .new_udp_socket_call = net_udp_socket,
825    .new_tcp_socket_call = net_tcp_socket,
826    .bind_call = net_bind,
827    .connect_call = net_connect,
828    .listen_call = net_listen,
829};
830
831
832static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
833{
834    binding->rpc_rx_vtbl = rpc_rx_vtbl;
835    return SYS_ERR_OK;
836}
837
838
839static void export_cb(void *st, errval_t err, iref_t iref)
840{
841    char* service_name = (char* ) st;
842    assert(err_is_ok(err));
843    err = nameservice_register(service_name, iref);
844    assert(err_is_ok(err));
845}
846
847int main(int argc, char *argv[])
848{
849    errval_t err;
850
851    if (argc < 4) {
852        printf("%s: missing arguments! \n", argv[0]);
853        return -1;
854    }
855
856    debug_printf("Net socket server started for %s.\n", argv[2]);
857
858    char card_name[64];
859    snprintf(card_name, sizeof(card_name), "%s:%s", argv[2], argv[argc - 1]);
860
861    char *ip = NULL;
862    char *netmask = NULL;
863    char *gw = NULL;
864
865    while (1) {
866        int option_index = 0;
867        int c;
868        static struct option long_options[] = {
869            {"ip",  required_argument,  0,  1},
870            {"netmask",  required_argument,  0,  2},
871            {"gw",  required_argument,  0,  3},
872            {0, 0,  0,  0}
873        };
874        c = getopt_long_only(argc, argv, "", long_options, &option_index);
875        if (c == -1)
876            break;
877
878        switch (c) {
879        case 1:
880            ip = optarg;
881            break;
882        case 2:
883            netmask = optarg;
884            break;
885        case 3:
886            gw = optarg;
887            break;
888        default:
889            break;
890        }
891    }
892
893    if (ip)
894        printf("option ip [%s]\n", ip);
895    if (netmask)
896        printf("option nm [%s]\n", netmask);
897    if (gw)
898        printf("option gw [%s]\n", gw);
899
900    if (ip) { // setting static IP, no DHCP
901        err = oct_init();
902        assert(err_is_ok(err));
903        err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr(ip), gw ? inet_addr(gw): 0, netmask ? inet_addr(netmask): 0);
904        assert(err_is_ok(err));
905    }
906
907    // EP to driver given by kaluga, TODO fix oldsytel driver like MLX4
908    struct capref ep =  {
909        .cnode = build_cnoderef(cap_argcn, CNODE_TYPE_OTHER),
910        .slot = 0
911    };
912
913    /* connect to the network */
914#ifdef POLLING
915    debug_printf("Net socket server polling \n");
916
917    err = networking_init_with_ep(card_name, ep, (!ip ? NET_FLAGS_DO_DHCP: 0)
918                                  | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT
919                                  | NET_FLAGS_POLLING );
920#else
921    debug_printf("Net socket server using interrupts \n");
922    err = networking_init_with_ep(card_name, ep, (!ip ? NET_FLAGS_DO_DHCP: 0)
923                                  | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT);
924#endif
925    if (err_is_fail(err)) {
926        USER_PANIC_ERR(err, "Failed to initialize the network");
927    }
928
929    struct descq_func_pointer f;
930
931    f.notify = q_notify;
932    f.create = q_create;
933    f.destroy = q_destroy;
934    f.reg = q_reg;
935    f.dereg = q_dereg;
936    f.control = q_control;
937
938    char queue_name[64];
939    char service_name[64];
940    sprintf(queue_name, "net_sockets_queue_%s", argv[2]);
941    sprintf(service_name, "net_sockets_service_%s", argv[2]);
942
943    err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, queue_name,
944                       true, NULL, &f);
945    assert(err_is_ok(err));
946
947
948    err = net_sockets_export(service_name, export_cb, connect_cb, get_default_waitset(),
949                            IDC_EXPORT_FLAGS_DEFAULT);
950    assert(err_is_ok(err));
951
952    struct waitset *ws = get_default_waitset();
953
954#ifdef POLLING
955#define POLLING_YIELD_IDLE 10
956    uint16_t polling_yield = POLLING_YIELD_IDLE;
957#endif
958    while(1) {
959#ifdef POLLING
960        err = event_dispatch_non_block(ws);
961        switch(err_no(err)) {
962            case SYS_ERR_OK:
963                polling_yield = POLLING_YIELD_IDLE;
964            break;
965            case LIB_ERR_NO_EVENT:
966                polling_yield--;
967            break;
968            default:
969            USER_PANIC_ERR(err, "error happened while dispatching event.");
970        }
971        err = networking_poll();
972        switch(err_no(err)) {
973            case SYS_ERR_OK:
974                polling_yield = POLLING_YIELD_IDLE;
975                break;
976            case LIB_ERR_NO_EVENT:
977                polling_yield--;
978                break;
979            default:
980                USER_PANIC_ERR(err, "error happened while dispatching event.");
981        }
982
983        if (polling_yield == 0) {
984            thread_yield();
985            polling_yield = POLLING_YIELD_IDLE;
986        }
987#else
988        event_dispatch(ws);
989#endif
990    }
991
992    debug_printf("Net socket server termiated.\n");
993
994    return 0;
995}
996