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>
19 #include <arpa/inet.h>
24 #include <barrelfish/waitset_chan.h>
26 #include <octopus/octopus.h>
27 #include <octopus_server/service.h>
28 #include <octopus/trigger.h>
30 #include <devif/queue_interface.h>
31 #include <devif/backends/descq.h>
33 #include <if/net_sockets_defs.h>
34 #include <net_sockets/net_sockets_types.h>
39 #include <lwip/pbuf.h>
41 #define NO_OF_BUFFERS 128
42 #define BUFFER_SIZE 16384
44 struct socket_connection;
46 struct network_connection {
47 struct network_connection *next;
49 struct capref buffer_cap;
56 void *buffers[NO_OF_BUFFERS];
57 uint64_t next_free, next_used;
59 struct net_sockets_binding *binding;
61 struct descq *buffer_queue;
62 struct socket_connection *sockets;
65 #define MAX_SEND_FRAMES 2
69 genoffset_t sent, length;
72 struct socket_connection {
73 struct socket_connection *next;
74 struct network_connection *connection;
76 struct send_frame send_frames[MAX_SEND_FRAMES];
78 struct udp_pcb *udp_socket;
79 struct tcp_pcb *tcp_socket;
82 static struct network_connection *network_connections = NULL;
84 static struct socket_connection * allocate_socket(struct network_connection *nc)
86 struct socket_connection *last, *socket;
87 uint32_t last_descriptor = 0;
92 if (socket->descriptor != last_descriptor + 1)
95 last_descriptor = last->descriptor;
96 socket = socket->next;
99 socket = malloc(sizeof(struct socket_connection));
101 memset(socket, 0, sizeof(struct socket_connection));
104 socket->next = last->next;
107 nc->sockets = socket;
110 socket->descriptor = last_descriptor + 1;
112 socket->connection = nc;
113 socket->udp_socket = NULL;
114 socket->tcp_socket = NULL;
116 memset(socket->send_frames, 0, sizeof(socket->send_frames));
121 static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
123 struct socket_connection *connection = arg;
124 struct network_connection *nc = connection->connection;
127 assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
129 uint32_t length = p->tot_len;
130 void *buffer = nc->buffers[nc->next_free];
133 debug_printf("%s: drop\n", __func__);
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;
145 nb->descriptor = connection->descriptor;
146 nb->host_address.s_addr = addr->addr;
148 // debug_printf("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor, buffer, nb->user_callback, nb->user_state, nb->size);
150 void *shb_data = buffer + sizeof(struct net_buffer);
156 for (pos = 0; pos < length; ) {
158 memcpy((void *)shb_data + pos, it->payload, it->len);
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,
166 assert(err_is_ok(err));
167 err = devq_notify((struct devq *)nc->queue);
168 assert(err_is_ok(err));
170 // debug_printf("%s: notifing\n", __func__);
171 // struct net_sockets_binding *binding = connection->connection->binding;
172 // debug_printf("%s: done\n", __func__);
176 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
178 struct socket_connection *socket = arg;
179 struct network_connection *nc = socket->connection;
182 void *buffer = nc->buffers[nc->next_free];
183 struct net_buffer *nb = buffer;
185 // debug_printf("%s: pcb:%p p:%p\n", __func__, pcb, p);
187 // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
188 assert(p->len == p->tot_len);
191 debug_printf("%s: drop\n", __func__);
197 nb->descriptor = socket->descriptor;
198 nb->accepted_descriptor = 0;
199 nb->host_address.s_addr = 0;
201 // debug_printf("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer, nb->size);
203 void *shb_data = buffer + sizeof(struct net_buffer);
204 memcpy((void *)shb_data, p->payload, length);
205 tcp_recved(pcb, p->tot_len);
210 nb->descriptor = socket->descriptor;
211 nb->accepted_descriptor = 0;
212 nb->host_address.s_addr = 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);
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);
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,
224 assert(err_is_ok(err));
225 err = devq_notify((struct devq *)nc->queue);
226 assert(err_is_ok(err));
228 // debug_printf("%s: notifing\n", __func__);
229 // struct net_sockets_binding *binding = connection->connection->binding;
230 // debug_printf("%s: done\n", __func__);
234 static void net_tcp_error(void *arg, err_t err)
236 struct socket_connection *socket = arg;
237 // struct network_connection *nc = socket->connection;
239 // debug_printf("%s(%d): error %d\n", __func__, socket->descriptor, err);
240 socket->tcp_socket = NULL; // invalidate
242 // uint32_t length = 0;
243 // void *buffer = nc->buffers[nc->next_free];
244 // struct net_buffer *nb = buffer;
248 // nb->descriptor = socket->descriptor;
249 // nb->accepted_descriptor = 0;
250 // nb->host_address.s_addr = 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);
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,
260 // assert(err_is_ok(err));
261 // err = devq_notify((struct devq *)nc->queue);
262 // assert(err_is_ok(err));
265 static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
267 struct socket_connection *socket = arg;
268 struct network_connection *nc = socket->connection;
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;
281 len -= socket->send_frames[0].length - socket->send_frames[0].sent;
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);
287 debug_printf("%s: err %zd\n", __func__, err);
288 assert(err_is_ok(err));
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;
297 err = devq_notify((struct devq *)nc->queue);
298 assert(err_is_ok(err));
303 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
305 struct socket_connection *socket = arg;
306 struct network_connection *nc = socket->connection;
307 struct socket_connection *accepted_socket;
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);
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));
323 void *buffer = nc->buffers[nc->next_free];
324 struct net_buffer *nb = buffer;
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);
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);
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,
340 assert(err_is_ok(err));
341 err = devq_notify((struct devq *)nc->queue);
342 assert(err_is_ok(err));
348 static errval_t net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
350 struct network_connection *nc;
352 nc = network_connections;
354 if (nc->queue_id == queue_id)
361 nc->binding = binding;
362 devq_set_state((struct devq *)nc->queue, nc);
367 static errval_t net_udp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
369 struct network_connection *nc;
370 struct socket_connection *socket;
373 socket = allocate_socket(nc);
374 *descriptor = socket->descriptor;
376 struct udp_pcb *pcb = udp_new();
378 socket->udp_socket = pcb;
379 udp_recv(socket->udp_socket, net_udp_receive, socket);
384 static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *descriptor)
386 struct network_connection *nc;
387 struct socket_connection *socket;
390 socket = allocate_socket(nc);
391 *descriptor = socket->descriptor;
393 struct tcp_pcb *pcb = tcp_new();
395 socket->tcp_socket = pcb;
396 tcp_arg(pcb, socket);
397 tcp_recv(socket->tcp_socket, net_tcp_receive);
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)
404 struct network_connection *nc;
405 struct socket_connection *socket;
408 socket = nc->sockets;
410 if (socket->descriptor == descriptor)
412 socket = socket->next;
416 if (socket->udp_socket) {
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;
425 debug_printf("UDP ECHO bind done.\n");
426 } else if (socket->tcp_socket) {
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;
436 debug_printf("TCP ECHO bind done.\n");
441 static errval_t net_listen(struct net_sockets_binding *binding, uint32_t descriptor, uint8_t backlog, errval_t *error)
443 struct network_connection *nc;
444 struct socket_connection *socket;
447 socket = nc->sockets;
449 if (socket->descriptor == descriptor)
451 socket = socket->next;
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);
466 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
468 struct socket_connection *socket = arg;
469 struct network_connection *nc = socket->connection;
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));
477 static errval_t net_connect(struct net_sockets_binding *binding, uint32_t descriptor, uint32_t ip_address, uint16_t port, errval_t *error)
479 struct network_connection *nc;
480 struct socket_connection *socket;
483 socket = nc->sockets;
485 if (socket->descriptor == descriptor)
487 socket = socket->next;
491 if (socket->udp_socket) {
495 addr.addr = ip_address;
496 e = udp_connect(socket->udp_socket, &addr, port);
499 } else if (socket->tcp_socket) {
503 addr.addr = ip_address;
504 e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
512 static errval_t net_delete_socket(struct net_sockets_binding *binding, uint32_t descriptor, errval_t *error)
514 struct network_connection *nc;
515 struct socket_connection *socket, *last;
518 socket = nc->sockets;
521 if (socket->descriptor == descriptor)
524 socket = socket->next;
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);
534 // debug_printf("%s(%d): tcp_close %p\n", __func__, descriptor, socket->tcp_socket);
535 e = tcp_close(socket->tcp_socket);
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]);
542 last->next = socket->next;
544 nc->sockets = socket->next;
551 static errval_t q_create(struct descq* q, bool notifications, uint8_t role,
554 struct network_connection *nc;
555 static uint64_t qid = 1;
557 nc = malloc(sizeof(struct network_connection));
559 nc->next = network_connections;
560 network_connections = nc;
566 nc->queue_id = *queue_id;
567 memset(nc->buffers, 0, sizeof(nc->buffers));
573 static errval_t q_destroy(struct descq* q)
579 static errval_t q_notify(struct descq* q)
581 struct devq* queue = (struct devq *)q;
582 errval_t err = SYS_ERR_OK;
583 //errval_t err2 = SYS_ERR_OK;
587 genoffset_t valid_data;
588 genoffset_t valid_length;
590 struct network_connection *nc;
593 // debug_printf("%s: \n", __func__);
594 nc = devq_get_state(queue);
596 err = devq_dequeue(queue, &rid, &offset, &length,
597 &valid_data, &valid_length, &flags);
598 if (err_is_fail(err)) {
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;
610 buffer = offset + nc->buffer_start;
611 struct net_buffer *nb = buffer;
612 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
614 // debug_printf("%s: %p\n", __func__, buffer);
616 socket = nc->sockets;
618 if (socket->descriptor == nb->descriptor)
620 socket = socket->next;
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;
629 p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
631 memcpy(p->payload, shb_data, nb->size);
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));
641 // debug_printf("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
642 if (port && addr.addr) {
645 e = udp_sendto(pcb, p, &addr, port);
647 debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
652 e = udp_send(pcb, p);
654 debug_printf("%s(%d): err:%d\n", __func__, socket->descriptor, e);
658 } else if (socket->tcp_socket) {
660 // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
662 if (socket->send_frames[0].length == 0) {
665 assert(socket->send_frames[1].length == 0);
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);
670 debug_printf("%s: e=%d\n", __func__, e);
672 e = tcp_output(socket->tcp_socket);
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);
679 socket->send_frames[1].offset = offset;
680 socket->send_frames[1].length = length - sizeof(struct net_buffer);
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));
692 // debug_printf("notify>\n");
693 err = devq_notify(queue);
694 // debug_printf("notify<\n");
695 assert(err_is_ok(err));
701 static errval_t q_reg(struct descq* q, struct capref cap,
704 struct frame_identity pa;
705 struct network_connection *nc;
707 nc = devq_get_state((struct devq *)q);
709 errval_t err = frame_identify(cap, &pa);
710 assert(err_is_ok(err));
711 nc->buffer_cap = cap;
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));
722 static errval_t q_dereg(struct descq* q, regionid_t rid)
728 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
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,
745 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
747 binding->rpc_rx_vtbl = rpc_rx_vtbl;
752 static void export_cb(void *st, errval_t err, iref_t iref)
754 assert(err_is_ok(err));
755 err = nameservice_register("net_sockets", iref);
756 assert(err_is_ok(err));
759 int main(int argc, char *argv[])
763 debug_printf("Net socket server started for e1000 %s.\n", argv[2]);
765 char servicename[64];
766 snprintf(servicename, sizeof(servicename), "e1000:%s", argv[2]);
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));
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");
779 struct descq *exp_queue;
780 struct descq_func_pointer f;
784 f.destroy = q_destroy;
787 f.control = q_control;
789 err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
790 true, true, 0, NULL, &f);
791 assert(err_is_ok(err));
794 err = net_sockets_export(NULL, export_cb, connect_cb, get_default_waitset(),
795 IDC_EXPORT_FLAGS_DEFAULT);
796 assert(err_is_ok(err));
799 event_dispatch(get_default_waitset());
801 // networking_poll();
804 debug_printf("UDP ECHO termiated.\n");