diff options
-rw-r--r-- | include/sys/socket.h | 11 | ||||
-rw-r--r-- | kernel/lib/relist.c | 7 | ||||
-rw-r--r-- | kernel/lib/relist.h | 1 | ||||
-rw-r--r-- | kernel/network/ethernet.c | 2 | ||||
-rw-r--r-- | kernel/network/ipv4.c | 8 | ||||
-rw-r--r-- | kernel/network/tcp.c | 269 | ||||
-rw-r--r-- | kernel/network/tcp.h | 7 | ||||
-rw-r--r-- | kernel/network/udp.c | 3 | ||||
-rw-r--r-- | kernel/network/udp.h | 2 | ||||
-rw-r--r-- | kernel/socket.c | 37 | ||||
-rw-r--r-- | kernel/socket.h | 6 |
11 files changed, 264 insertions, 89 deletions
diff --git a/include/sys/socket.h b/include/sys/socket.h index eab62eb..f67b6a0 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -38,6 +38,17 @@ typedef uint16_t in_port_t; typedef unsigned int sa_family_t; typedef int socklen_t; +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; +}; + struct sockaddr { sa_family_t sa_family; /* Address family */ char *sa_data; /* Socket address */ diff --git a/kernel/lib/relist.c b/kernel/lib/relist.c index 01af884..2e45429 100644 --- a/kernel/lib/relist.c +++ b/kernel/lib/relist.c @@ -5,6 +5,7 @@ #include <string.h> void relist_init(struct relist *list) { + list->num_entries = 0; list->bitmap_capacity = 1; list->bitmap = kcalloc(sizeof(u64), list->bitmap_capacity); if (!list->bitmap) { @@ -28,6 +29,7 @@ relist_init_error: } void relist_reset(struct relist *list) { + list->num_entries = 0; memset(list->bitmap, 0, list->bitmap_capacity * sizeof(u64)); } @@ -43,12 +45,14 @@ int relist_clone(struct relist *in, struct relist *out) { kfree(out->bitmap); goto relist_clone_error; } + out->num_entries = in->num_entries; memcpy(out->bitmap, in->bitmap, sizeof(u64) * out->bitmap_capacity); memcpy(out->entries, in->entries, sizeof(void *) * sizeof(u64) * 8 * out->bitmap_capacity); return 1; relist_clone_error: + out->num_entries = 0; out->bitmap_capacity = 0; out->entries = NULL; out->bitmap = NULL; @@ -100,6 +104,7 @@ int relist_add(struct relist *list, void *value, u32 *index) { if (index) { *index = entry; } + list->num_entries++; list->bitmap[entry / 64] |= ((u64)1 << (entry % 64)); return 1; } @@ -114,6 +119,7 @@ int relist_remove(struct relist *list, u32 index) { assert(0); return 0; } + list->num_entries--; list->bitmap[index / 64] &= ~((u64)1 << (index % 64)); return 1; } @@ -148,6 +154,7 @@ int relist_get(const struct relist *list, u32 index, void **out, int *end) { } void relist_free(struct relist *list) { + list->num_entries = 0; list->bitmap_capacity = 0; kfree(list->entries); kfree(list->bitmap); diff --git a/kernel/lib/relist.h b/kernel/lib/relist.h index 734e5dc..409032d 100644 --- a/kernel/lib/relist.h +++ b/kernel/lib/relist.h @@ -5,6 +5,7 @@ struct relist { void **entries; u32 bitmap_capacity; + u32 num_entries; u64 *bitmap; }; diff --git a/kernel/network/ethernet.c b/kernel/network/ethernet.c index cf2e047..1bda07f 100644 --- a/kernel/network/ethernet.c +++ b/kernel/network/ethernet.c @@ -62,7 +62,7 @@ void handle_ethernet(const u8 *packet, u64 packet_length) { handle_ipv4(payload, packet_length - sizeof(struct ETHERNET_HEADER) - 4); break; default: - kprintf("Can't handle ethernet type\n"); + kprintf("Can't handle ethernet type 0x%x\n", type); break; } } diff --git a/kernel/network/ipv4.c b/kernel/network/ipv4.c index 4fe3799..cceee8e 100644 --- a/kernel/network/ipv4.c +++ b/kernel/network/ipv4.c @@ -84,15 +84,17 @@ void handle_ipv4(const u8 *payload, u32 packet_length) { assert(ipv4_total_length <= packet_length); ipv4_t src_ip; - memcpy(&src_ip, payload + 12, sizeof(u8[4])); + memcpy(&src_ip.d, payload + 12, sizeof(u8[4])); + ipv4_t dst_ip; + memcpy(&dst_ip.d, payload + 16, sizeof(u8[4])); u8 protocol = *(payload + 9); switch (protocol) { case 0x6: - handle_tcp(src_ip, payload + 20, ipv4_total_length - 20); + handle_tcp(src_ip, dst_ip, payload + 20, ipv4_total_length - 20); break; case 0x11: - handle_udp(src_ip, payload + 20, ipv4_total_length - 20); + handle_udp(src_ip, dst_ip, payload + 20, ipv4_total_length - 20); break; default: kprintf("Protocol given in IPv4 header not handeld: %x\n", protocol); diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c index aeabbf2..fc8d97c 100644 --- a/kernel/network/tcp.c +++ b/kernel/network/tcp.c @@ -1,10 +1,13 @@ #include <assert.h> #include <cpu/arch_inst.h> #include <drivers/pit.h> +#include <fs/vfs.h> +#include <math.h> #include <network/arp.h> #include <network/bytes.h> #include <network/ipv4.h> #include <network/udp.h> +#include <random.h> #define CWR (1 << 7) #define ECE (1 << 6) @@ -15,6 +18,8 @@ #define SYN (1 << 1) #define FIN (1 << 0) +#define MSS 536 + // FIXME: This should be dynamic #define WINDOW_SIZE 4096 @@ -73,28 +78,82 @@ u16 tcp_checksum(u16 *buffer, int size) { return (u16)(~cksum); } -void tcp_calculate_checksum(ipv4_t src_ip, u32 dst_ip, const u8 *payload, - u16 payload_length, struct TCP_HEADER *header) { - struct PSEUDO_TCP_HEADER ps; - memset(&ps, 0, sizeof(ps)); - memcpy(&ps.src_addr, &src_ip.d, sizeof(u32)); - memcpy(&ps.dst_addr, &dst_ip, sizeof(u32)); - ps.protocol = 6; - ps.tcp_length = htons(20 + payload_length); - ps.src_port = header->src_port; - ps.dst_port = header->dst_port; - ps.seq_num = header->seq_num; - ps.ack_num = header->ack_num; - ps.data_offset = header->data_offset; - ps.reserved = header->reserved; - ps.flags = header->flags; - ps.window_size = header->window_size; - ps.urgent_pointer = header->urgent_pointer; - int buffer_length = sizeof(ps) + payload_length; +u16 tcp_calculate_checksum(ipv4_t src_ip, u32 dst_ip, const u8 *payload, + u16 payload_length, const struct TCP_HEADER *header, + int total) { + if (total < header->data_offset + payload_length) { + return 0; + } + + int pseudo = sizeof(u32) * 2 + sizeof(u16) + sizeof(u8) * 2; + + int buffer_length = + pseudo + header->data_offset * sizeof(u32) + payload_length; u8 buffer[buffer_length]; - memcpy(buffer, &ps, sizeof(ps)); - memcpy(buffer + sizeof(ps), payload, payload_length); - header->checksum = tcp_checksum((u16 *)buffer, buffer_length); + u8 *ptr = buffer; + memcpy(ptr, &src_ip.d, sizeof(u32)); + ptr += sizeof(u32); + memcpy(ptr, &dst_ip, sizeof(u32)); + ptr += sizeof(u32); + *ptr = 0; + ptr += sizeof(u8); + *ptr = 6; + ptr += sizeof(u8); + *(u16 *)ptr = htons(header->data_offset * sizeof(u32) + payload_length); + ptr += sizeof(u16); + memcpy(ptr, header, header->data_offset * sizeof(u32)); + memset(ptr + 16, 0, sizeof(u16)); // set checksum to zero + ptr += header->data_offset * sizeof(u32); + memcpy(ptr, payload, payload_length); + + return tcp_checksum((u16 *)buffer, buffer_length); +} + +struct TcpPacket { + u32 time; + u32 seq_num; + u16 payload_length; + u8 *buffer; + u16 length; +}; + +static void tcp_send(struct TcpConnection *con, u8 *buffer, u16 length, + u32 seq_num, u32 payload_length) { + if (payload_length > 0) { + struct TcpPacket *packet = kmalloc(sizeof(struct TcpPacket)); + assert(packet); + packet->time = pit_num_ms(); + packet->seq_num = seq_num; + packet->buffer = buffer; + packet->length = length; + packet->payload_length = payload_length; + + assert(relist_add(&con->inflight, packet, NULL)); + } + send_ipv4_packet((ipv4_t){.d = con->outgoing_ip}, 6, buffer, length); +} + +void tcp_resend_packets(struct TcpConnection *con) { + if (con->inflight.num_entries > 0) { + for (u32 i = 0;; i++) { + struct TcpPacket *packet; + int end; + if (!relist_get(&con->inflight, i, (void *)&packet, &end)) { + if (end) { + break; + } + continue; + } + if (packet->time + 200 > pit_num_ms()) { + continue; + } + // resend the packet + relist_remove(&con->inflight, i); + tcp_send(con, packet->buffer, packet->length, packet->seq_num, + packet->payload_length); + kfree(packet); + } + } } void tcp_send_empty_payload(struct TcpConnection *con, u8 flags) { @@ -111,14 +170,15 @@ void tcp_send_empty_payload(struct TcpConnection *con, u8 flags) { u8 payload[0]; u16 payload_length = 0; - tcp_calculate_checksum(ip_address, con->outgoing_ip, (const u8 *)payload, - payload_length, &header); + header.checksum = tcp_calculate_checksum( + ip_address, con->outgoing_ip, (const u8 *)payload, payload_length, + &header, sizeof(struct TCP_HEADER) + payload_length); int send_len = sizeof(header) + payload_length; - u8 send_buffer[send_len]; + u8 *send_buffer = kmalloc(send_len); memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); - send_ipv4_packet((ipv4_t){.d = con->outgoing_ip}, 6, send_buffer, send_len); + tcp_send(con, send_buffer, send_len, con->seq, 0); } void tcp_close_connection(struct TcpConnection *con) { @@ -134,12 +194,30 @@ void tcp_send_syn(struct TcpConnection *con) { con->seq++; } -void send_tcp_packet(struct TcpConnection *con, const u8 *payload, - u16 payload_length) { - if (payload_length > 1500 - 20 - sizeof(struct TCP_HEADER)) { - send_tcp_packet(con, payload, 1500 - 20 - sizeof(struct TCP_HEADER)); - payload_length -= 1500 - 20 - sizeof(struct TCP_HEADER); - payload += 1500 - 20 - sizeof(struct TCP_HEADER); +int tcp_can_send(struct TcpConnection *con, u16 payload_length) { + if (con->inflight.num_entries > 2) { + tcp_resend_packets(con); + return 0; + } + if (con->seq - con->seq_ack + payload_length > con->current_window_size) { + tcp_resend_packets(con); + return 0; + } + return 1; +} + +int send_tcp_packet(struct TcpConnection *con, const u8 *payload, + u16 payload_length) { + if (!tcp_can_send(con, payload_length)) { + return 0; + } + + if (payload_length > MSS) { + if (0 == send_tcp_packet(con, payload, MSS)) { + return 0; + } + payload_length -= MSS; + payload += MSS; return send_tcp_packet(con, payload, payload_length); } struct TCP_HEADER header = {0}; @@ -152,24 +230,37 @@ void send_tcp_packet(struct TcpConnection *con, const u8 *payload, header.flags = PSH | ACK; header.window_size = htons(WINDOW_SIZE); header.urgent_pointer = 0; - tcp_calculate_checksum(ip_address, con->outgoing_ip, (const u8 *)payload, - payload_length, &header); + header.checksum = tcp_calculate_checksum( + ip_address, con->outgoing_ip, (const u8 *)payload, payload_length, + &header, sizeof(struct TCP_HEADER) + payload_length); int send_len = sizeof(header) + payload_length; - u8 send_buffer[send_len]; + u8 *send_buffer = kmalloc(send_len); + assert(send_buffer); memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); - send_ipv4_packet((ipv4_t){.d = con->outgoing_ip}, 6, send_buffer, send_len); + + tcp_send(con, send_buffer, send_len, con->seq, payload_length); con->seq += payload_length; + return 1; } -void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length) { +void handle_tcp(ipv4_t src_ip, ipv4_t dst_ip, const u8 *payload, + u32 payload_length) { const struct TCP_HEADER *header = (const struct TCP_HEADER *)payload; - (void)header; + u16 tcp_payload_length = payload_length - header->data_offset * sizeof(u32); + const u8 *tcp_payload = payload + header->data_offset * sizeof(u32); + u16 checksum = + tcp_calculate_checksum(src_ip, dst_ip.d, tcp_payload, tcp_payload_length, + header, payload_length); + if (header->checksum != checksum) { + return; + } u16 n_src_port = header->src_port; u16 n_dst_port = header->dst_port; u32 n_seq_num = header->seq_num; u32 n_ack_num = header->ack_num; + u32 n_window_size = header->window_size; u8 flags = header->flags; @@ -177,14 +268,18 @@ void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length) { u16 dst_port = htons(n_dst_port); u32 seq_num = htonl(n_seq_num); u32 ack_num = htonl(n_ack_num); + u16 window_size = htons(n_window_size); + (void)ack_num; if (SYN == flags) { struct TcpConnection *con = internal_tcp_incoming(src_ip.d, src_port, 0, dst_port); - if(!con) { + if (!con) { return; } + con->window_size = window_size; + con->current_window_size = MSS; con->ack = seq_num + 1; tcp_send_empty_payload(con, SYN | ACK); con->seq++; @@ -195,49 +290,75 @@ void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length) { tcp_find_connection(src_ip, src_port, dst_port); if (!incoming_connection) { kprintf("unable to find open port for incoming connection\n"); + return; + } + incoming_connection->window_size = window_size; + incoming_connection->unhandled_packet = 1; + if (0 != (flags & RST)) { + klog("Requested port is closed", LOG_NOTE); + incoming_connection->dead = 1; + return; } - if (incoming_connection) { - incoming_connection->unhandled_packet = 1; - if (0 != (flags & RST)) { - klog("Requested port is closed", LOG_NOTE); - incoming_connection->dead = 1; + if (ACK == flags) { + if (0 == incoming_connection->handshake_state) { + // Then it is probably a response to the SYN|ACK we sent. + incoming_connection->handshake_state = 1; return; } - if (ACK == flags) { - if (0 == incoming_connection->handshake_state) { - // Then it is probably a response to the SYN|ACK we sent. - incoming_connection->handshake_state = 1; - return; + } + if ((SYN | ACK) == flags) { + assert(0 == incoming_connection->handshake_state); + incoming_connection->handshake_state = 1; + incoming_connection->ack = seq_num + 1; + tcp_send_ack(incoming_connection); + return; + } + if (ACK & flags) { + incoming_connection->seq_ack = ack_num; + if (incoming_connection->inflight.num_entries > 0) { + for (u32 i = 0;; i++) { + struct TcpPacket *packet; + int end; + if (!relist_get(&incoming_connection->inflight, i, (void *)&packet, + &end)) { + if (end) { + break; + } + continue; + } + if (packet->seq_num + packet->payload_length != ack_num) { + continue; + } + relist_remove(&incoming_connection->inflight, i); + kfree(packet->buffer); + kfree(packet); + break; } } - if ((SYN | ACK) == flags) { - assert(0 == incoming_connection->handshake_state); - incoming_connection->handshake_state = 1; - - incoming_connection->ack = seq_num + 1; - - tcp_send_ack(incoming_connection); - } - u16 tcp_payload_length = payload_length - header->data_offset * sizeof(u32); - if (tcp_payload_length > 0) { - const u8 *tcp_payload = payload + header->data_offset * sizeof(u32); - u32 len = ringbuffer_write(&incoming_connection->incoming_buffer, - tcp_payload, tcp_payload_length); - assert(len == tcp_payload_length); - incoming_connection->ack += len; - tcp_send_ack(incoming_connection); + tcp_resend_packets(incoming_connection); + if (0 == incoming_connection->inflight.num_entries) { + u32 rest = incoming_connection->window_size - + incoming_connection->current_window_size; + if (rest > 0) { + incoming_connection->current_window_size += min(rest, MSS); + } } - if (0 != (flags & FIN)) { - incoming_connection->ack++; + } + if (tcp_payload_length > 0) { + u32 len = ringbuffer_write(&incoming_connection->incoming_buffer, + tcp_payload, tcp_payload_length); + assert(len == tcp_payload_length); + incoming_connection->ack += len; + tcp_send_ack(incoming_connection); + } + if (0 != (flags & FIN)) { + incoming_connection->ack++; - tcp_send_empty_payload(incoming_connection, FIN | ACK); - incoming_connection->seq++; + tcp_send_empty_payload(incoming_connection, FIN | ACK); + incoming_connection->seq++; - incoming_connection->dead = 1; // FIXME: It should wait for a ACK - // of the FIN before the connection - // is closed. - } - } else { - return; + incoming_connection->dead = 1; // FIXME: It should wait for a ACK + // of the FIN before the connection + // is closed. } } diff --git a/kernel/network/tcp.h b/kernel/network/tcp.h index 1e292b3..836a148 100644 --- a/kernel/network/tcp.h +++ b/kernel/network/tcp.h @@ -2,7 +2,8 @@ #include <typedefs.h> void tcp_send_syn(struct TcpConnection *con); void tcp_wait_reply(struct TcpConnection *con); -void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length); -void send_tcp_packet(struct TcpConnection *con, const u8 *payload, - u16 payload_length); +void handle_tcp(ipv4_t src_ip, ipv4_t dst_ip, const u8 *payload, u32 payload_length); +int send_tcp_packet(struct TcpConnection *con, const u8 *payload, + u16 payload_length); void tcp_close_connection(struct TcpConnection *con); +int tcp_can_send(struct TcpConnection *con, u16 payload_length); diff --git a/kernel/network/udp.c b/kernel/network/udp.c index 724c97a..0c8d6e9 100644 --- a/kernel/network/udp.c +++ b/kernel/network/udp.c @@ -24,7 +24,8 @@ void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, kfree(packet); } -void handle_udp(ipv4_t src_ip, const u8 *payload, u32 packet_length) { +void handle_udp(ipv4_t src_ip, ipv4_t dst_ip, const u8 *payload, u32 packet_length) { + (void)dst_ip; if (packet_length < sizeof(u16[4])) { return; } diff --git a/kernel/network/udp.h b/kernel/network/udp.h index bcf31bc..af532ec 100644 --- a/kernel/network/udp.h +++ b/kernel/network/udp.h @@ -1,6 +1,6 @@ #include <socket.h> #include <typedefs.h> -void handle_udp(ipv4_t src_ip, const u8 *payload, u32 packet_length); +void handle_udp(ipv4_t src_ip, ipv4_t dst_ip, const u8 *payload, u32 packet_length); void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, const u8 *payload, u16 payload_length); diff --git a/kernel/socket.c b/kernel/socket.c index fa37efd..8b6e12d 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -89,6 +89,7 @@ struct TcpConnection *internal_tcp_incoming(u32 src_ip, u16 src_port, int connection_id; list_add(&open_tcp_connections, con, &connection_id); + con->current_window_size = 536; con->outgoing_ip = src_ip; con->outgoing_port = src_port; con->incoming_ip = dst_ip; @@ -97,6 +98,7 @@ struct TcpConnection *internal_tcp_incoming(u32 src_ip, u16 src_port, ringbuffer_init(&con->incoming_buffer, 8192); ringbuffer_init(&con->outgoing_buffer, 8192); + relist_init(&con->inflight); stack_push(&listen->incoming_connections, con); return con; } @@ -105,7 +107,7 @@ int tcp_sync_buffer(vfs_fd_t *fd) { struct TcpConnection *con = fd->inode->internal_object; assert(con); if (con->dead) { - return -EBADF; // TODO: Check if this is correct. + return 0; } struct ringbuffer *rb = &con->outgoing_buffer; @@ -113,11 +115,16 @@ int tcp_sync_buffer(vfs_fd_t *fd) { if (0 == send_buffer_len) { return 0; } + + if (!tcp_can_send(con, send_buffer_len)) { + return 0; + } + char *send_buffer = kmalloc(send_buffer_len); assert(ringbuffer_read(rb, send_buffer, send_buffer_len) == send_buffer_len); send_tcp_packet(con, send_buffer, send_buffer_len); kfree(send_buffer); - return 0; + return 1; } void tcp_close(vfs_fd_t *fd) { @@ -151,14 +158,20 @@ int tcp_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) { } if (con->no_delay) { - send_tcp_packet(con, buffer, len); + if (!send_tcp_packet(con, buffer, len)) { + return -EWOULDBLOCK; + } return len; } struct ringbuffer *rb = &con->outgoing_buffer; if (ringbuffer_unused(rb) < len) { - tcp_sync_buffer(fd); - send_tcp_packet(con, buffer, len); + if (!tcp_sync_buffer(fd)) { + return -EWOULDBLOCK; + } + if (!send_tcp_packet(con, buffer, len)) { + return -EWOULDBLOCK; + } len = 0; } else { assert(ringbuffer_write(rb, buffer, len) == len); @@ -171,6 +184,15 @@ int tcp_has_data(vfs_inode_t *inode) { return !(ringbuffer_isempty(&con->incoming_buffer)); } +int tcp_can_write(vfs_inode_t *inode) { + struct TcpConnection *con = inode->internal_object; + if (con->no_delay) { + return tcp_can_send(con, 256); + } + return (ringbuffer_unused(&con->outgoing_buffer) > 0) || + (tcp_can_send(con, 250)); +} + int udp_recvfrom(vfs_fd_t *fd, void *buffer, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { struct UdpConnection *con = fd->inode->internal_object; @@ -289,10 +311,12 @@ int tcp_connect(vfs_fd_t *fd, const struct sockaddr *addr, socklen_t addrlen) { con->incoming_port = 1337; // TODO con->outgoing_ip = in_addr->sin_addr.s_addr; con->outgoing_port = ntohs(in_addr->sin_port); + con->current_window_size = 536; ringbuffer_init(&con->incoming_buffer, 8192); ringbuffer_init(&con->outgoing_buffer, 8192); list_add(&open_tcp_connections, con, NULL); + relist_init(&con->inflight); tcp_send_syn(con); @@ -307,6 +331,7 @@ int tcp_connect(vfs_fd_t *fd, const struct sockaddr *addr, socklen_t addrlen) { } fd->inode->_has_data = tcp_has_data; + fd->inode->_can_write = tcp_can_write; fd->inode->write = tcp_write; fd->inode->read = tcp_read; fd->inode->close = tcp_close; @@ -426,7 +451,7 @@ int accept(int socket, struct sockaddr *address, socklen_t *address_len) { stack_pop(&tcp_listen->incoming_connections); assert(connection); vfs_inode_t *inode = vfs_create_inode( - 0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, tcp_has_data, always_can_write, 1, + 0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, tcp_has_data, tcp_can_write, 1, connection, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, tcp_read, tcp_write, tcp_close /*close*/, NULL /*create_directory*/, NULL /*get_vm_object*/, NULL /*truncate*/, NULL /*stat*/, diff --git a/kernel/socket.h b/kernel/socket.h index ef5863d..f41e9a1 100644 --- a/kernel/socket.h +++ b/kernel/socket.h @@ -5,6 +5,7 @@ typedef int socklen_t; #include <fs/fifo.h> #include <fs/vfs.h> #include <lib/buffered_write.h> +#include <lib/relist.h> #include <lib/ringbuffer.h> #include <lib/stack.h> #include <stddef.h> @@ -51,9 +52,14 @@ struct TcpConnection { struct ringbuffer incoming_buffer; struct ringbuffer outgoing_buffer; + struct relist inflight; + int no_delay; + u32 current_window_size; + u32 window_size; u32 seq; + u32 seq_ack; u32 ack; int handshake_state; |