4 #include <barrelfish/barrelfish.h>
5 #include <barrelfish/nameservice_client.h>
6 #include <if/net_sockets_defs.h>
7 #include <net_sockets/net_sockets.h>
9 #include <barrelfish/waitset_chan.h>
10 #include <barrelfish/waitset.h>
12 #include <devif/queue_interface.h>
13 #include <devif/backends/descq.h>
16 static struct net_sockets_binding *binding;
17 static bool bound_done = false;
19 static struct capref buffer_frame;
20 struct descq* descq_queue;
21 static void *buffer_start;
22 static regionid_t regionid;
23 static uint64_t queue_id;
25 #define NO_OF_BUFFERS 128
26 #define BUFFER_SIZE 16384
28 void *buffers[NO_OF_BUFFERS];
29 uint64_t next_free, next_used;
30 struct net_socket *sockets = NULL;
32 /// Dequeue the element from the net_socket queue
33 static void dequeue(struct net_socket **queue,
34 struct net_socket *element)
36 if (element->next == element) {
37 assert(element->prev == element);
38 assert(*queue == element);
41 element->prev->next = element->next;
42 element->next->prev = element->prev;
43 if (*queue == element) {
44 *queue = element->next;
47 element->prev = element->next = NULL;
50 /// Enqueue the element on the net_socket queue
51 static void enqueue(struct net_socket **queue,
52 struct net_socket *element)
56 element->next = element->prev = element;
58 element->next = *queue;
59 element->prev = (*queue)->prev;
60 element->next->prev = element;
61 element->prev->next = element;
65 struct net_socket * net_udp_socket(void)
68 struct net_socket *socket;
71 err = binding->rpc_tx_vtbl.new_udp_socket(binding, &descriptor);
72 assert(err_is_ok(err));
74 socket = malloc(sizeof(struct net_socket));
77 socket->descriptor = descriptor;
78 socket->received = NULL;
79 socket->connected = NULL;
80 socket->accepted = NULL;
81 socket->user_state = NULL;
82 enqueue(&sockets, socket);
86 struct net_socket * net_tcp_socket(void)
89 struct net_socket *socket;
92 err = binding->rpc_tx_vtbl.new_tcp_socket(binding, &descriptor);
93 assert(err_is_ok(err));
95 socket = malloc(sizeof(struct net_socket));
98 socket->descriptor = descriptor;
99 socket->received = NULL;
101 socket->connected = NULL;
102 socket->accepted = NULL;
103 socket->user_state = NULL;
104 enqueue(&sockets, socket);
108 static struct net_socket * get_socket(uint32_t descriptor)
110 struct net_socket *socket = sockets;
113 if (socket->descriptor == descriptor)
115 socket = socket->next;
116 if (socket == sockets)
119 debug_printf("%s: %d %p\n", __func__, descriptor, __builtin_return_address(0));
124 void net_set_user_state(struct net_socket *socket, void *user_state)
126 socket->user_state = user_state;
129 void net_close(struct net_socket *socket)
133 debug_printf("%s(%d):\n", __func__, socket->descriptor);
134 err = binding->rpc_tx_vtbl.delete_socket(binding, socket->descriptor, &error);
135 assert(err_is_ok(err));
136 assert(err_is_ok(error));
137 dequeue(&sockets, socket);
139 debug_printf("%s: %ld:%p %ld:%p\n", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
142 errval_t net_bind(struct net_socket *socket, struct in_addr ip_address, uint16_t port)
146 err = binding->rpc_tx_vtbl.bind(binding, socket->descriptor, ip_address.s_addr, port, &error);
147 assert(err_is_ok(err));
152 errval_t net_listen(struct net_socket *socket, uint8_t backlog)
156 err = binding->rpc_tx_vtbl.listen(binding, socket->descriptor, backlog, &error);
157 assert(err_is_ok(err));
162 void * net_alloc(size_t size)
164 void *buffer = buffers[next_free];
166 buffers[next_free] = NULL;
167 next_free = (next_free + 1) % NO_OF_BUFFERS;
168 // debug_printf("%s: %p:%zd %ld:%p %ld:%p %p\n", __func__, buffer + sizeof(struct net_buffer), size, next_free, buffers[next_free], next_used, buffers[next_used], __builtin_return_address(0));
169 return buffer + sizeof(struct net_buffer);
172 void net_free(void *buffer)
174 assert(!buffers[next_used]);
175 buffers[next_used] = buffer - sizeof(struct net_buffer);
176 next_used = (next_used + 1) % NO_OF_BUFFERS;
177 // debug_printf("%s: %p %ld:%p %ld:%p %p\n", __func__, buffer, next_free, buffers[next_free], next_used, buffers[next_used], __builtin_return_address(0));
180 errval_t net_send(struct net_socket *socket, void *data, size_t size)
184 void *buffer = data - sizeof(struct net_buffer);
185 struct net_buffer *nb = buffer;
186 // debug_printf("%s(%d): %ld -> %p\n", __func__, socket->descriptor, size, buffer);
189 nb->descriptor = socket->descriptor;
190 nb->host_address.s_addr = INADDR_NONE;
192 // debug_printf("%s: enqueue 2 %lx:%ld\n", __func__, buffer - buffer_start, sizeof(struct net_buffer) + size);
193 err = devq_enqueue((struct devq *)descq_queue, regionid, buffer - buffer_start, sizeof(struct net_buffer) + size,
195 assert(err_is_ok(err));
196 err = devq_notify((struct devq *)descq_queue);
197 assert(err_is_ok(err));
203 errval_t net_send_to(struct net_socket *socket, void *data, size_t size, struct in_addr ip_address, uint16_t port)
207 void *buffer = data - sizeof(struct net_buffer);
208 struct net_buffer *nb = buffer;
209 // debug_printf("%s(%d): %ld -> %p\n", __func__, descriptor, size, buffer);
212 nb->descriptor = socket->descriptor;
213 nb->host_address = ip_address;
215 // debug_printf("%s: enqueue 2 %lx:%ld\n", __func__, buffer - buffer_start, sizeof(struct net_buffer) + size);
216 err = devq_enqueue((struct devq *)descq_queue, regionid, buffer - buffer_start, sizeof(struct net_buffer) + size,
218 assert(err_is_ok(err));
219 err = devq_notify((struct devq *)descq_queue);
220 assert(err_is_ok(err));
226 errval_t net_connect(struct net_socket *socket, struct in_addr ip_address, uint16_t port, net_connected_callback_t cb)
230 socket->connected = cb;
231 err = binding->rpc_tx_vtbl.connect(binding, socket->descriptor, ip_address.s_addr, port, &error);
232 assert(err_is_ok(err));
233 assert(err_is_ok(error));
238 static void net_connected(struct net_sockets_binding *b, uint32_t descriptor, errval_t error)
240 struct net_socket *socket = get_socket(descriptor);
241 assert(socket->descriptor == descriptor);
242 assert(err_is_ok(error));
244 assert(socket->connected);
245 socket->connected(socket->user_state, socket);
248 void net_accept(struct net_socket *socket, net_accepted_callback_t cb)
250 socket->accepted = cb;
253 static void net_accepted(uint32_t descriptor, uint32_t accepted_descriptor, struct in_addr host_address, uint16_t port)
255 struct net_socket *socket = get_socket(descriptor);
256 assert(socket->descriptor == descriptor);
258 struct net_socket *accepted_socket = malloc(sizeof(struct net_socket));
259 assert(accepted_socket);
261 accepted_socket->descriptor = accepted_descriptor;
262 accepted_socket->received = NULL;
263 accepted_socket->sent = NULL;
264 accepted_socket->connected = NULL;
265 accepted_socket->accepted = NULL;
266 accepted_socket->user_state = NULL;
267 enqueue(&sockets, accepted_socket);
269 assert(socket->accepted);
270 socket->accepted(socket->user_state, accepted_socket, host_address, port);
274 void net_recv(struct net_socket *socket, net_received_callback_t cb)
276 socket->received = cb;
279 void net_set_sent(struct net_socket *socket, net_sent_callback_t cb)
284 static void bind_cb(void *st, errval_t err, struct net_sockets_binding *b)
287 net_sockets_rpc_client_init(binding);
291 static void alloc_mem(struct capref *frame, void** virt, size_t size)
294 vregion_flags_t flags;
296 r = frame_alloc(frame, size, NULL);
297 assert(err_is_ok(r));
299 flags = VREGION_FLAGS_READ_WRITE;
300 r = vspace_map_one_frame_attr(virt, size, *frame, flags, NULL, NULL);
301 assert(err_is_ok(r));
302 memset(*virt, 0, size);
305 static errval_t q_notify(struct descq* q)
307 assert(descq_queue == q);
308 errval_t err = SYS_ERR_OK;
309 //errval_t err2 = SYS_ERR_OK;
313 genoffset_t valid_data;
314 genoffset_t valid_length;
318 // debug_printf("%s: \n", __func__);
320 err = devq_dequeue((struct devq *)descq_queue, &rid, &offset, &length,
321 &valid_data, &valid_length, &flags);
322 if (err_is_fail(err)) {
325 // debug_printf("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, flags);
326 void *buffer = buffer_start + offset;
327 struct net_buffer *nb = buffer;
328 // debug_printf("%s: dequeue %lx:%ld %ld %p socket:%d asocket:%d\n", __func__, offset, length, flags, nb, nb->descriptor, nb->accepted_descriptor);
329 struct net_socket *socket = get_socket(nb->descriptor);
330 void *shb_data = buffer + sizeof(struct net_buffer);
332 if (flags == 1) { // receiving buffer
333 // debug_printf("%s: enqueue 1> %lx:%d\n", __func__, offset, nb->size);
334 if (nb->accepted_descriptor) { // accept
335 net_accepted(nb->descriptor, nb->accepted_descriptor, nb->host_address, nb->port);
337 err = devq_enqueue((struct devq *)descq_queue, rid, offset, length, 0, 0, 1);
338 assert(err_is_ok(err));
341 if (socket->received) {
342 // debug_printf("net_received(%d): %d\n", nb->descriptor, nb->size);
343 socket->received(socket->user_state, socket, shb_data, nb->size, nb->host_address, nb->port);
344 // debug_printf("%s: enqueue 1< %lx:%d\n", __func__, offset, 2048);
347 err = devq_enqueue((struct devq *)descq_queue, rid, offset, length, 0, 0, 1);
348 assert(err_is_ok(err));
351 } else if (flags == 2) { // transmitting buffer
353 // debug_printf("%s: dequeue %lx:%ld %p\n", __func__, offset, length, shb_data);
354 socket->sent(socket->user_state, socket, shb_data, nb->size);
356 // debug_printf("%s: %ld:%p %ld:%p\n", __func__, next_free, buffers[next_free], next_used, buffers[next_used]);
357 // assert(!buffers[next_used]);
358 // buffers[next_used] = buffer_start + offset;
359 // next_used = (next_used + 1) % NO_OF_BUFFERS;
365 // debug_printf("notify>\n");
366 err = devq_notify((struct devq *)descq_queue);
367 assert(err_is_ok(err));
368 // debug_printf("notify<\n");
374 errval_t net_sockets_init(void)
379 memset(buffers, 0, sizeof(buffers));
383 alloc_mem(&buffer_frame, &buffer_start, 2 * BUFFER_SIZE * NO_OF_BUFFERS);
385 struct descq_func_pointer f;
388 debug_printf("Descriptor queue test started \n");
389 err = descq_create(&descq_queue, DESCQ_DEFAULT_SIZE, "net_sockets_queue",
390 false, true, true, &queue_id, &f);
391 assert(err_is_ok(err));
393 err = nameservice_blocking_lookup("net_sockets", &iref);
394 assert(err_is_ok(err));
395 err = net_sockets_bind(iref, bind_cb, NULL, get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
396 assert(err_is_ok(err));
398 while (!bound_done) {
399 event_dispatch(get_default_waitset());
401 debug_printf("%s: initialized\n", __func__);
402 binding->rx_vtbl.connected = net_connected;
403 // binding->rx_vtbl.accepted = net_accepted;
405 err = binding->rpc_tx_vtbl.register_queue(binding, queue_id);
406 assert(err_is_ok(err));
408 err = devq_register((struct devq *)descq_queue, buffer_frame, ®ionid);
409 assert(err_is_ok(err));
411 for (int i = 0; i < NO_OF_BUFFERS; i++) {
412 err = devq_enqueue((struct devq *)descq_queue, regionid, i * BUFFER_SIZE, BUFFER_SIZE,
415 debug_printf("%s: %d:%d\n", __func__, i, NO_OF_BUFFERS);
416 assert(err_is_ok(err));
417 buffers[i] = i * BUFFER_SIZE + buffer_start + BUFFER_SIZE * NO_OF_BUFFERS;
420 err = devq_notify((struct devq *)descq_queue);
421 assert(err_is_ok(err));