3 * E1000 net socket server
7 * Copyright (c) 2017, ETH Zurich.
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.
15 #include <barrelfish/barrelfish.h>
16 #include <barrelfish/deferred.h>
17 #include <barrelfish/nameservice_client.h>
21 #include <barrelfish/waitset_chan.h>
23 #include <devif/queue_interface.h>
24 #include <devif/backends/descq.h>
26 #include <if/net_sockets_defs.h>
27 #include <net_sockets/net_sockets_types.h>
32 #include <lwip/pbuf.h>
34 #define NO_OF_BUFFERS 128
35 #define BUFFER_SIZE 16384
37 struct socket_connection;
39 struct network_connection {
40 struct network_connection *next;
42 struct capref buffer_cap;
49 void *buffers[NO_OF_BUFFERS];
50 uint64_t next_free, next_used;
52 struct net_sockets_binding *binding;
54 struct descq *buffer_queue;
55 struct socket_connection *sockets;
58 #define MAX_SEND_FRAMES 2
62 genoffset_t sent, length;
65 struct socket_connection {
66 struct socket_connection *next;
67 struct network_connection *connection;
69 struct send_frame send_frames[MAX_SEND_FRAMES];
71 struct udp_pcb *udp_socket;
72 struct tcp_pcb *tcp_socket;
75 static struct network_connection *network_connections = NULL;
77 static struct socket_connection * allocate_socket(struct network_connection *nc)
79 struct socket_connection *last, *socket;
80 uint32_t last_descriptor = 0;
85 if (socket->descriptor != last_descriptor + 1)
88 last_descriptor = last->descriptor;
89 socket = socket->next;
92 socket = malloc(sizeof(struct socket_connection));
94 memset(socket, 0, sizeof(struct socket_connection));
97 socket->next = last->next;
100 nc->sockets = socket;
103 socket->descriptor = last_descriptor + 1;
105 socket->connection = nc;
106 socket->udp_socket = NULL;
107 socket->tcp_socket = NULL;
109 memset(socket->send_frames, 0, sizeof(socket->send_frames));
114 static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
116 struct socket_connection *connection = arg;
117 struct network_connection *nc = connection->connection;
120 assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
122 uint32_t length = p->tot_len;
123 void *buffer = nc->buffers[nc->next_free];
126 debug_printf("%s: drop\n", __func__);
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;
138 nb->descriptor = connection->descriptor;
139 nb->host_address.s_addr = addr->addr;
141 // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
143 void *shb_data = buffer + sizeof(struct net_buffer);
149 for (pos = 0; pos < length; ) {
151 memcpy((void *)shb_data + pos, it->payload, it->len);
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,
159 assert(err_is_ok(err));
160 err = devq_notify((struct devq *)nc->queue);
161 assert(err_is_ok(err));
163 // debug_printf("%s: notifing\n", __func__);
164 // struct net_sockets_binding *binding = connection->connection->binding;
165 // debug_printf("%s: done\n", __func__);
169 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
171 struct socket_connection *socket = arg;
172 struct network_connection *nc = socket->connection;
175 void *buffer = nc->buffers[nc->next_free];
176 struct net_buffer *nb = buffer;
178 // debug_printf("%s: pcb:%p p:%p\n", __func__, pcb, p);
180 // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
181 assert(p->len == p->tot_len);
184 debug_printf("%s: drop\n", __func__);
190 nb->descriptor = socket->descriptor;
191 nb->accepted_descriptor = 0;
192 nb->host_address.s_addr = 0;
194 // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
196 void *shb_data = buffer + sizeof(struct net_buffer);
197 memcpy((void *)shb_data, p->payload, length);
198 tcp_recved(pcb, p->tot_len);
203 nb->descriptor = socket->descriptor;
204 nb->accepted_descriptor = 0;
205 nb->host_address.s_addr = 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);
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);
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,
217 assert(err_is_ok(err));
218 err = devq_notify((struct devq *)nc->queue);
219 assert(err_is_ok(err));
221 // debug_printf("%s: notifing\n", __func__);
222 // struct net_sockets_binding *binding = connection->connection->binding;
223 // debug_printf("%s: done\n", __func__);
227 static void net_tcp_error(void *arg, err_t err)
229 struct socket_connection *socket = arg;
230 // struct network_connection *nc = socket->connection;
232 debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, err);
233 socket->tcp_socket = NULL; // invalidate
235 // uint32_t length = 0;
236 // void *buffer = nc->buffers[nc->next_free];
237 // struct net_buffer *nb = buffer;
241 // nb->descriptor = socket->descriptor;
242 // nb->accepted_descriptor = 0;
243 // nb->host_address.s_addr = 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);
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,
253 // assert(err_is_ok(err));
254 // err = devq_notify((struct devq *)nc->queue);
255 // assert(err_is_ok(err));
258 static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
260 struct socket_connection *socket = arg;
261 struct network_connection *nc = socket->connection;
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;
274 len -= socket->send_frames[0].length - socket->send_frames[0].sent;
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);
280 debug_printf("%s: err %zd\n", __func__, err);
281 assert(err_is_ok(err));
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;
290 err = devq_notify((struct devq *)nc->queue);
291 assert(err_is_ok(err));
296 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
298 struct socket_connection *socket = arg;
299 struct network_connection *nc = socket->connection;
300 struct socket_connection *accepted_socket;
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);
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));
316 void *buffer = nc->buffers[nc->next_free];
317 struct net_buffer *nb = buffer;
320 nb->descriptor = socket->descriptor;
321 nb->accepted_descriptor = accepted_socket->descriptor;
322 nb->host_address.s_addr = 0;
324 debug_printf("%s(%d): accepted %p\n", __func__, socket->descriptor, newpcb);
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);
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,
333 assert(err_is_ok(err));
334 err = devq_notify((struct devq *)nc->queue);
335 assert(err_is_ok(err));
341 static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
343 struct network_connection *nc;
345 nc = network_connections;
347 if (nc->queue_id == queue_id)
354 nc->binding = binding;
355 devq_set_state((struct devq *)nc->queue, nc);
360 static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
362 struct network_connection *nc;
363 struct socket_connection *socket;
366 socket = allocate_socket(nc);
367 *descriptor = socket->descriptor;
369 struct udp_pcb *pcb = udp_new();
371 socket->udp_socket = pcb;
372 udp_recv(socket->udp_socket, net_udp_receive, socket);
377 static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
379 struct network_connection *nc;
380 struct socket_connection *socket;
383 socket = allocate_socket(nc);
384 *descriptor = socket->descriptor;
386 struct tcp_pcb *pcb = tcp_new();
388 socket->tcp_socket = pcb;
389 tcp_arg(pcb, socket);
390 tcp_recv(socket->tcp_socket, net_tcp_receive);
395 static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
397 struct network_connection *nc;
398 struct socket_connection *socket;
401 socket = nc->sockets;
403 if (socket->descriptor == descriptor)
405 socket = socket->next;
409 if (socket->udp_socket) {
412 ip.addr = ip_address;
413 *error = udp_bind(socket->udp_socket, &ip, port);
414 assert(err_is_ok(*error));
417 debug_printf("UDP ECHO bind done.\n");
418 } else if (socket->tcp_socket) {
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));
427 debug_printf("TCP ECHO bind done.\n");
432 static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
434 struct network_connection *nc;
435 struct socket_connection *socket;
438 socket = nc->sockets;
440 if (socket->descriptor == descriptor)
442 socket = socket->next;
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);
457 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
459 struct socket_connection *socket = arg;
460 struct network_connection *nc = socket->connection;
462 errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK);
463 assert(err_is_ok(err));
468 static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
470 struct network_connection *nc;
471 struct socket_connection *socket;
474 socket = nc->sockets;
476 if (socket->descriptor == descriptor)
478 socket = socket->next;
482 if (socket->udp_socket) {
486 addr.addr = ip_address;
487 e = udp_connect(socket->udp_socket, &addr, port);
490 } else if (socket->tcp_socket) {
494 addr.addr = ip_address;
495 e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
503 static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t descriptor, errval_t *error)
505 struct network_connection *nc;
506 struct socket_connection *socket, *last;
509 socket = nc->sockets;
512 if (socket->descriptor == descriptor)
515 socket = socket->next;
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);
525 debug_printf("%s(%d): tcp_close %p\n", __func__, descriptor, socket->tcp_socket);
526 e = tcp_close(socket->tcp_socket);
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]);
533 last->next = socket->next;
535 nc->sockets = socket->next;
542 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
545 struct network_connection *nc;
546 static uint64_t qid = 1;
548 nc = malloc(sizeof(struct network_connection));
550 nc->next = network_connections;
551 network_connections = nc;
557 nc->queue_id = *queue_id;
558 memset(nc->buffers, 0, sizeof(nc->buffers));
564 static errval_t q_destroy(struct descq* q)
570 static errval_t q_notify(struct descq* q)
572 struct devq* queue = (struct devq *)q;
573 errval_t err = SYS_ERR_OK;
574 //errval_t err2 = SYS_ERR_OK;
578 genoffset_t valid_data;
579 genoffset_t valid_length;
581 struct network_connection *nc;
584 // debug_printf("%s: \n", __func__);
585 nc = devq_get_state(queue);
587 err = devq_dequeue(queue, &rid, &offset, &length,
588 &valid_data, &valid_length, &flags);
589 if (err_is_fail(err)) {
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;
601 buffer = offset + nc->buffer_start;
602 struct net_buffer *nb = buffer;
603 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
605 // debug_printf("%s: %p\n", __func__, buffer);
607 socket = nc->sockets;
609 if (socket->descriptor == nb->descriptor)
611 socket = socket->next;
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;
620 p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
622 memcpy(p->payload, shb_data, nb->size);
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));
632 // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
633 if (port && addr.addr) {
636 e = udp_sendto(pcb, p, &addr, port);
638 debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
643 e = udp_send(pcb, p);
645 debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
649 } else if (socket->tcp_socket) {
651 // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
653 if (socket->send_frames[0].length == 0) {
656 assert(socket->send_frames[1].length == 0);
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);
661 debug_printf("%s: e=%d\n", __func__, e);
663 e = tcp_output(socket->tcp_socket);
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);
670 socket->send_frames[1].offset = offset;
671 socket->send_frames[1].length = length - sizeof(struct net_buffer);
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));
683 // debug_printf("notify>\n");
684 err = devq_notify(queue);
685 // debug_printf("notify<\n");
686 assert(err_is_ok(err));
692 static errval_t q_reg(struct descq* q, struct capref cap,
695 struct frame_identity pa;
696 struct network_connection *nc;
698 nc = devq_get_state((struct devq *)q);
700 errval_t err = frame_identify(cap, &pa);
701 assert(err_is_ok(err));
702 nc->buffer_cap = cap;
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));
713 static errval_t q_dereg(struct descq* q, regionid_t rid)
719 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
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,
736 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
738 binding->rpc_rx_vtbl = rpc_rx_vtbl;
743 static void export_cb(void *st, errval_t err, iref_t iref)
745 assert(err_is_ok(err));
746 err = nameservice_register("net_sockets", iref);
747 assert(err_is_ok(err));
750 int main(int argc, char *argv[])
754 debug_printf("Net socket server started for e1000 %s.\n", argv[2]);
756 char servicename[64];
757 snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
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");
766 struct descq *exp_queue;
767 struct descq_func_pointer f;
771 f.destroy = q_destroy;
774 f.control = q_control;
776 err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
777 true, true, 0, NULL, &f);
778 assert(err_is_ok(err));
781 err = net_sockets_export(NULL, export_cb, connect_cb, get_default_waitset(),
782 IDC_EXPORT_FLAGS_DEFAULT);
783 assert(err_is_ok(err));
786 event_dispatch(get_default_waitset());
788 // networking_poll();
791 debug_printf("UDP ECHO termiated.\n");