diff options
author | Anton Kling <anton@kling.gg> | 2024-02-28 21:47:49 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-02-28 21:47:49 +0100 |
commit | e6c8f7298b40757a410d9df6319824c4f0d70351 (patch) | |
tree | b90ee0eba9a45c7551d9f23b6e66620ff0ea5b66 /kernel | |
parent | 4536dc81b4be9a62328826455664cd6d696df8fb (diff) |
TCP/UDP: Start rewrite of network sockets
Having sockets be file descriptors seems like a bad idea so I trying to
make UDP and TCP sockets be more independent and not be abstracted away
as much.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fs/fifo.c | 1 | ||||
-rw-r--r-- | kernel/lib/stack.h | 6 | ||||
-rw-r--r-- | kernel/network/tcp.c | 166 | ||||
-rw-r--r-- | kernel/network/tcp.h | 7 | ||||
-rw-r--r-- | kernel/network/udp.c | 42 | ||||
-rw-r--r-- | kernel/socket.c | 270 | ||||
-rw-r--r-- | kernel/socket.h | 51 |
7 files changed, 298 insertions, 245 deletions
diff --git a/kernel/fs/fifo.c b/kernel/fs/fifo.c index 9844b9e..5563f76 100644 --- a/kernel/fs/fifo.c +++ b/kernel/fs/fifo.c @@ -57,7 +57,6 @@ FIFO_FILE *create_fifo_object(void) { } int create_fifo(void) { - int fd_n = 0; for (; get_current_task()->file_descriptors[fd_n]; fd_n++) ; diff --git a/kernel/lib/stack.h b/kernel/lib/stack.h index efb9cb1..f47fe66 100644 --- a/kernel/lib/stack.h +++ b/kernel/lib/stack.h @@ -1,8 +1,7 @@ +#ifndef STACK_H +#define STACK_H #include <stdint.h> -// struct entry; -// struct stack; - struct entry { void *ptr; // TODO: Maybe don't use a linkedlist @@ -16,3 +15,4 @@ struct stack { void stack_init(struct stack *s); int stack_push(struct stack *s, void *data); void *stack_pop(struct stack *s); +#endif diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c index f45d1af..717c7db 100644 --- a/kernel/network/tcp.c +++ b/kernel/network/tcp.c @@ -3,7 +3,6 @@ #include <network/bytes.h> #include <network/ipv4.h> #include <network/udp.h> -#include <socket.h> extern u8 ip_address[4]; #define CWR (1 << 7) @@ -49,6 +48,16 @@ struct __attribute__((__packed__)) PSEUDO_TCP_HEADER { u16 urgent_pointer; }; +void tcp_wait_reply(struct TcpConnection *con) { + for (;;) { + if (con->unhandled_packet) { + return; + } + // TODO: Make the scheduler halt the process + switch_task(); + } +} + u16 tcp_checksum(u16 *buffer, int size) { unsigned long cksum = 0; while (size > 1) { @@ -64,11 +73,11 @@ u16 tcp_checksum(u16 *buffer, int size) { return (u16)(~cksum); } -void tcp_calculate_checksum(u8 src_ip[4], u8 dst_ip[4], const u8 *payload, +void tcp_calculate_checksum(u8 src_ip[4], u32 dst_ip, const u8 *payload, u16 payload_length, struct TCP_HEADER *header) { struct PSEUDO_TCP_HEADER ps = {0}; memcpy(&ps.src_addr, src_ip, sizeof(u32)); - memcpy(&ps.dst_addr, dst_ip, 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; @@ -88,80 +97,145 @@ void tcp_calculate_checksum(u8 src_ip[4], u8 dst_ip[4], const u8 *payload, header->checksum = tcp_checksum((u16 *)buffer, buffer_length); } -void tcp_close_connection(struct INCOMING_TCP_CONNECTION *inc) { +void tcp_send_empty_payload(struct TcpConnection *con, u8 flags) { struct TCP_HEADER header = {0}; - header.src_port = htons(inc->dst_port); - header.dst_port = inc->n_port; - header.seq_num = htonl(inc->seq_num); - header.ack_num = htonl(inc->ack_num); + header.src_port = htons(con->incoming_port); + header.dst_port = htons(con->outgoing_port); + header.seq_num = htonl(con->seq); + header.ack_num = htonl(con->ack); header.data_offset = 5; header.reserved = 0; - header.flags = FIN | ACK; + header.flags = flags; header.window_size = htons(WINDOW_SIZE); header.urgent_pointer = 0; - u32 dst_ip; - memcpy(&dst_ip, inc->ip, sizeof(dst_ip)); + u8 payload[0]; u16 payload_length = 0; - tcp_calculate_checksum(ip_address, inc->ip, (const u8 *)payload, + tcp_calculate_checksum(ip_address, con->outgoing_ip, (const u8 *)payload, payload_length, &header); int send_len = sizeof(header) + payload_length; u8 send_buffer[send_len]; memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); - send_ipv4_packet(dst_ip, 6, send_buffer, send_len); + + send_ipv4_packet(con->outgoing_ip, 6, send_buffer, send_len); +} + +void tcp_send_ack(struct TcpConnection *con) { + tcp_send_empty_payload(con, ACK); } -void send_tcp_packet(struct INCOMING_TCP_CONNECTION *inc, u8 *payload, +void tcp_send_syn(struct TcpConnection *con) { + tcp_send_empty_payload(con, SYN); + con->seq++; +} + +// void send_tcp_packet(struct INCOMING_TCP_CONNECTION *inc, const u8 *payload, +// u16 payload_length) { +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(inc, payload, 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); - return send_tcp_packet(inc, payload, payload_length); + return send_tcp_packet(con, payload, payload_length); } struct TCP_HEADER header = {0}; - header.src_port = htons(inc->dst_port); - header.dst_port = inc->n_port; - header.seq_num = htonl(inc->seq_num); - header.ack_num = htonl(inc->ack_num); + header.src_port = htons(con->incoming_port); + header.dst_port = htons(con->outgoing_port); + header.seq_num = htonl(con->seq); + header.ack_num = htonl(con->ack); header.data_offset = 5; header.reserved = 0; header.flags = PSH | ACK; header.window_size = htons(WINDOW_SIZE); header.urgent_pointer = 0; - u32 dst_ip; - memcpy(&dst_ip, inc->ip, sizeof(dst_ip)); - tcp_calculate_checksum(ip_address, inc->ip, (const u8 *)payload, + tcp_calculate_checksum(ip_address, con->outgoing_ip, (const u8 *)payload, payload_length, &header); int send_len = sizeof(header) + payload_length; u8 send_buffer[send_len]; memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); - send_ipv4_packet(dst_ip, 6, send_buffer, send_len); + send_ipv4_packet(con->outgoing_ip, 6, send_buffer, send_len); - inc->seq_num += payload_length; + con->seq += payload_length; } -void send_empty_tcp_message(struct INCOMING_TCP_CONNECTION *inc, u8 flags, - u32 inc_seq_num, u16 n_dst_port, u16 n_src_port) { - struct TCP_HEADER header = {0}; - header.src_port = n_dst_port; - header.dst_port = n_src_port; - header.seq_num = 0; - header.ack_num = htonl(inc_seq_num + 1); - header.data_offset = 5; - header.reserved = 0; - header.flags = flags; - header.window_size = htons(WINDOW_SIZE); - header.urgent_pointer = 0; - char payload[0]; - tcp_calculate_checksum(ip_address, inc->ip, (const u8 *)payload, 0, &header); - u32 dst_ip; - memcpy(&dst_ip, inc->ip, sizeof(dst_ip)); - send_ipv4_packet(dst_ip, 6, (const u8 *)&header, sizeof(header)); -} +void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { + const struct TCP_HEADER *header = (const struct TCP_HEADER *)payload; + (void)header; + u16 n_src_port = *(u16 *)(payload); + u16 n_dst_port = *(u16 *)(payload + 2); + u32 n_seq_num = *(u32 *)(payload + 4); + u32 n_ack_num = *(u32 *)(payload + 8); + + // u8 flags = *(payload + 13); + u8 flags = header->flags; + u16 src_port = htons(n_src_port); + (void)src_port; + u16 dst_port = htons(n_dst_port); + u32 seq_num = htonl(n_seq_num); + u32 ack_num = htonl(n_ack_num); + (void)ack_num; + + if (SYN == flags) { + u32 t; + memcpy(&t, src_ip, sizeof(u8[4])); + struct TcpConnection *con = internal_tcp_incoming(t, src_port, 0, dst_port); + assert(con); + con->ack = seq_num + 1; + tcp_send_empty_payload(con, SYN | ACK); + return; + } + + struct TcpConnection *incoming_connection = tcp_find_connection(dst_port); + if (incoming_connection) { + incoming_connection->unhandled_packet = 1; + if (0 != (flags & RST)) { + klog("Requested port is closed", LOG_NOTE); + incoming_connection->dead = 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); + } + if (0 != (flags & PSH)) { + u16 tcp_payload_length = + payload_length - header->data_offset * sizeof(u32); + int len = fifo_object_write( + (u8 *)(payload + header->data_offset * sizeof(u32)), 0, + tcp_payload_length, incoming_connection->data_file); + assert(len >= 0); + 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->dead = 1; // FIXME: It should wait for a ACK + // of the FIN before the connection + // is closed. + } + } else { + assert(NULL); + } +} +/* void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { const struct TCP_HEADER *inc_header = (const struct TCP_HEADER *)payload; u16 n_src_port = *(u16 *)(payload); @@ -233,11 +307,11 @@ void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { header.flags = ACK; header.window_size = htons(WINDOW_SIZE); header.urgent_pointer = 0; - char payload[0]; - tcp_calculate_checksum(ip_address, src_ip, (const u8 *)payload, 0, &header); u32 dst_ip; memcpy(&dst_ip, src_ip, sizeof(dst_ip)); + char payload[0]; + tcp_calculate_checksum(ip_address, dst_ip, (const u8 *)payload, 0, &header); send_ipv4_packet(dst_ip, 6, (const u8 *)&header, sizeof(header)); return; } -} +}*/ diff --git a/kernel/network/tcp.h b/kernel/network/tcp.h index 2a836a4..0f9e818 100644 --- a/kernel/network/tcp.h +++ b/kernel/network/tcp.h @@ -1,4 +1,7 @@ +#include <socket.h> +void tcp_send_syn(struct TcpConnection *con); +void tcp_wait_reply(struct TcpConnection *con); void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length); -void send_tcp_packet(struct INCOMING_TCP_CONNECTION *inc, u8 *payload, +void send_tcp_packet(struct TcpConnection *con, const u8 *payload, u16 payload_length); -void tcp_close_connection(struct INCOMING_TCP_CONNECTION *s); + void tcp_close_connection(struct INCOMING_TCP_CONNECTION * s); diff --git a/kernel/network/udp.c b/kernel/network/udp.c index 5aae050..4f3848a 100644 --- a/kernel/network/udp.c +++ b/kernel/network/udp.c @@ -20,44 +20,6 @@ void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, } void handle_udp(u8 src_ip[4], const u8 *payload, u32 packet_length) { - assert(packet_length >= 8); - // n_.* means network format(big endian) - // h_.* means host format((probably) little endian) - u16 n_source_port = *(u16 *)payload; - u16 h_source_port = ntohs(n_source_port); - (void)h_source_port; - u16 h_dst_port = ntohs(*(u16 *)(payload + 2)); - u16 h_length = ntohs(*(u16 *)(payload + 4)); - assert(h_length == packet_length); - u16 data_length = h_length - 8; - const u8 *data = payload + 8; - - // Find the open port - OPEN_INET_SOCKET *in_s = find_open_udp_port(htons(h_dst_port)); - assert(in_s); - SOCKET *s = in_s->s; - vfs_fd_t *fifo_file = s->ptr_socket_fd; - - // Write the sockaddr struct such that it can later be - // given to userland if asked. - struct sockaddr_in /*{ - sa_family_t sin_family; - union { - u32 s_addr; - } sin_addr; - u16 sin_port; - }*/ in; - in.sin_family = AF_INET; - memcpy(&in.sin_addr.s_addr, src_ip, sizeof(u32)); - in.sin_port = n_source_port; - socklen_t sock_length = sizeof(struct sockaddr_in); - - raw_vfs_pwrite(fifo_file, &sock_length, sizeof(sock_length), 0); - raw_vfs_pwrite(fifo_file, &in, sizeof(in), 0); - - // Write the UDP payload length(not including header) - raw_vfs_pwrite(fifo_file, &data_length, sizeof(u16), 0); - - // Write the UDP payload - raw_vfs_pwrite(fifo_file, (char *)data, data_length, 0); + // TODO: Reimplement + assert(NULL); } diff --git a/kernel/socket.c b/kernel/socket.c index 0f960f5..9cb8763 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -10,162 +10,172 @@ // FIXME: Make these more dynamic OPEN_UNIX_SOCKET *un_sockets[100] = {0}; -OPEN_INET_SOCKET *inet_sockets[100] = {0}; -struct INCOMING_TCP_CONNECTION tcp_connections[100] = {0}; +struct TcpConnection *tcp_sockets[100]; +struct TcpListen *tcp_listen[100]; -int tcp_socket_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) { - struct INCOMING_TCP_CONNECTION *s = - (struct INCOMING_TCP_CONNECTION *)fd->inode->internal_object; - if (s->connection_closed) { - return -EBADF; - } - - if (buffered_write(&s->buffer, buffer, len)) { - return len; - } - - // Use the current buffered input - if (s->buffer.buffer_usage > 0) { - send_tcp_packet(s, s->buffer.data, s->buffer.buffer_usage); - buffered_clear(&s->buffer); +u32 gen_ipv4(u8 i1, u8 i2, u8 i3, u8 i4) { + return i4 << (32 - 8) | i3 << (32 - 16) | i2 << (32 - 24) | i1 << (32 - 32); +} - // Try to add to the buffer again. If it fails just send the whole - // thing immediatley. - if (buffered_write(&s->buffer, buffer, len)) { - return len; +struct TcpConnection *tcp_find_connection(u16 port) { + for (int i = 0; i < 100; i++) { + if (port == tcp_sockets[i]->incoming_port) { + return tcp_sockets[i]; } } - send_tcp_packet(s, buffer, len); - return len; + return NULL; } +struct TcpConnection *internal_tcp_incoming(u32 src_ip, u16 src_port, + u32 dst_ip, u16 dst_port) { + u32 i = 0; + for (; i < 100; i++) { + if (!tcp_listen[i]) { + continue; + } + if (dst_port == tcp_listen[i]->port) { + break; + } + } + if (!tcp_listen[i] || dst_port != tcp_listen[i]->port) { + return NULL; + } + struct TcpListen *listen = tcp_listen[i]; + u32 listen_id = i; -int tcp_socket_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) { - struct INCOMING_TCP_CONNECTION *s = - (struct INCOMING_TCP_CONNECTION *)fd->inode->internal_object; - if (s->connection_closed) { - return -EBADF; + i = 0; + for (; i < 100; i++) { + if (!tcp_sockets[i]) { + break; + } + } + if (tcp_sockets[i]) { + return NULL; } - return fifo_object_read(buffer, offset, len, s->data_file); + tcp_sockets[i] = kcalloc(1, sizeof(struct TcpConnection)); + struct TcpConnection *con = tcp_sockets[i]; + u32 con_id = i; + con->outgoing_ip = src_ip; + con->outgoing_port = src_port; + // con->incoming_ip = dst_ip; + con->incoming_port = dst_port; // FIXME: Should be different for each + // connection + + con->data_file = create_fifo_object(); + kprintf("pushing the connection\n"); + kprintf("listen_id: %x\n", listen_id); + stack_push(&listen->incoming_connections, (void *)con_id); + kprintf("listen->incoming_connections->head: %x\n", + (&listen->incoming_connections)->head); + kprintf("root: %x\n", &listen->incoming_connections); + return con; } -void tcp_socket_close(vfs_fd_t *fd) { - struct INCOMING_TCP_CONNECTION *s = - (struct INCOMING_TCP_CONNECTION *)fd->inode->internal_object; - - // Flush the remaining buffer - if (s->buffer.buffer_usage > 0) { - send_tcp_packet(s, s->buffer.data, s->buffer.buffer_usage); +u32 tcp_listen_ipv4(u32 ip, u16 port, int *error) { + *error = 0; + u32 i = 0; + for (; i < 100; i++) { + if (!tcp_listen[i]) { + break; + } } - buffered_free(&s->buffer); - - if (s->connection_closed) { - s->is_used = 0; - return; + if (tcp_listen[i]) { + *error = 1; + return 0; } - s->requesting_connection_close = 1; - tcp_close_connection(s); - s->is_used = 0; + + tcp_listen[i] = kcalloc(1, sizeof(struct TcpListen)); + tcp_listen[i]->ip = ip; + tcp_listen[i]->port = port; + stack_init(&tcp_listen[i]->incoming_connections); + return i; } -struct INCOMING_TCP_CONNECTION *get_incoming_tcp_connection(u8 ip[4], - u16 n_port) { - for (int i = 0; i < 100; i++) { - if (0 != memcmp(tcp_connections[i].ip, ip, sizeof(u8[4]))) { - continue; - } - if (n_port != tcp_connections[i].n_port) { - continue; +u32 tcp_accept(u32 listen_socket, int *error) { + *error = 0; + struct TcpListen *l = tcp_listen[listen_socket]; + if (NULL == l) { + *error = 1; + return 0; + } + for (;;) { + // TODO: halt the process + if (NULL != l->incoming_connections.head) { + void *out = stack_pop(&l->incoming_connections); + return (u32)out; // TODO: Should a pointer store a u32? } - return &tcp_connections[i]; } - return NULL; + ASSERT_NOT_REACHED; } -struct INCOMING_TCP_CONNECTION * -handle_incoming_tcp_connection(u8 ip[4], u16 n_port, u16 dst_port) { - OPEN_INET_SOCKET *in = find_open_tcp_port(htons(dst_port)); - if (!in) { - kprintf("TCP SYN to unopened port: %d\n", dst_port); - return NULL; - } - - int i; - for (i = 0; i < 100; i++) { - if (!tcp_connections[i].is_used) { +u32 tcp_connect_ipv4(u32 ip, u16 port, int *error) { + *error = 0; + u32 i = 0; + for (; i < 100; i++) { + if (!tcp_sockets[i]) { break; } } + if (tcp_sockets[i]) { + *error = 1; + return 0; + } - tcp_connections[i].is_used = 1; - memcpy(tcp_connections[i].ip, ip, sizeof(u8[4])); - tcp_connections[i].n_port = n_port; - tcp_connections[i].dst_port = dst_port; - tcp_connections[i].data_file = create_fifo_object(); - - buffered_init(&tcp_connections[i].buffer, 0x2000); + tcp_sockets[i] = kcalloc(1, sizeof(struct TcpConnection)); + struct TcpConnection *con = tcp_sockets[i]; - SOCKET *s = in->s; + con->incoming_port = 1337; // TODO + con->outgoing_ip = ip; + con->outgoing_port = port; - vfs_inode_t *inode = vfs_create_inode( - 0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, 0 /*has_data*/, 1 /*can_write*/, - 1 /*is_open*/, &tcp_connections[i], 0 /*file_size*/, NULL /*open*/, - NULL /*create_file*/, tcp_socket_read, tcp_socket_write, tcp_socket_close, - NULL /*create_directory*/, NULL /*get_vm_object*/, NULL /*truncate*/, - NULL /*stat*/); + con->data_file = create_fifo_object(); - tcp_connections[i].has_data_ptr = &inode->has_data; + tcp_send_syn(con); - vfs_fd_t *fd; - int n = vfs_create_fd(O_RDWR, 0, 0 /*is_tty*/, inode, &fd); + for (;;) { + tcp_wait_reply(con); + if (con->dead) { // Port is probably closed + *error = 1; + return 0; + } + if (0 != con->handshake_state) { + break; + } + } - fd->reference_count++; - s->incoming_fd = fd; + return i; +} - // Shitty way of telling the accepting socket we have a incoming - // connection. - char c = 'i'; - fifo_object_write((u8 *)&c, 1, 0, s->fifo_file); - s->ptr_socket_fd->inode->has_data = 1; +int tcp_write(u32 socket, const u8 *buffer, u64 len, u64 *out) { + struct TcpConnection *con = tcp_sockets[socket]; + if (con->dead) { + *out = 0; + return 0; + } - vfs_close(n); // Closes the file descriptor in the current process. - // But it does not get freed since the reference count - // is still over zero. - fd->reference_count--; - return &tcp_connections[i]; + send_tcp_packet(con, buffer, len); + *out = len; + return 1; } -OPEN_INET_SOCKET *find_open_tcp_port(u16 port) { - for (int i = 0; i < 100; i++) { - if (!inet_sockets[i]) { - continue; - } - if (inet_sockets[i]->port != port) { - continue; - } - if (inet_sockets[i]->s->type != SOCK_STREAM) { - continue; - } - return inet_sockets[i]; +int tcp_read(u32 socket, u8 *buffer, u64 buffer_size, u64 *out) { + struct TcpConnection *con = tcp_sockets[socket]; + if (con->dead) { + *out = 0; + return 0; } - return NULL; -} -OPEN_INET_SOCKET *find_open_udp_port(u16 port) { - for (int i = 0; i < 100; i++) { - if (!inet_sockets[i]) { - continue; - } - if (inet_sockets[i]->port != port) { - continue; - } - if (inet_sockets[i]->s->type != SOCK_DGRAM) { - continue; - } - return inet_sockets[i]; + int rc = 0; + for (; rc <= 0;) { + rc = fifo_object_read(buffer, 0, buffer_size, con->data_file); } - return NULL; + *out = rc; + return 1; +} + +void tcp_close(u32 socket) { + assert(NULL); } int uds_open(const char *path) { @@ -268,24 +278,6 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { devfs_add_file(us->path, NULL, NULL, NULL, 1, 1, FS_TYPE_UNIX_SOCKET); return 0; } - if (AF_INET == s->domain) { - struct sockaddr_in *in = (struct sockaddr_in *)addr; - assert(in->sin_family == AF_INET); // FIXME: Figure out error value - OPEN_INET_SOCKET *inet; - int i = 0; - for (; i < 100; i++) { - if (!inet_sockets[i]) { - break; - } - } - - inet = inet_sockets[i] = kmalloc(sizeof(OPEN_INET_SOCKET)); - inet->address = in->sin_addr.s_addr; - inet->port = in->sin_port; - inet->s = s; - s->child = inet; - return 0; - } return 0; } diff --git a/kernel/socket.h b/kernel/socket.h index f765fb7..174ceb1 100644 --- a/kernel/socket.h +++ b/kernel/socket.h @@ -3,6 +3,7 @@ #include <fs/fifo.h> #include <fs/vfs.h> #include <lib/buffered_write.h> +#include <lib/stack.h> #include <stddef.h> #include <typedefs.h> @@ -17,6 +18,42 @@ #define MSG_WAITALL 1 +u32 gen_ipv4(u8 i1, u8 i2, u8 i3, u8 i4); +u32 tcp_connect_ipv4(u32 ip, u16 port, int *error); + +u32 tcp_listen_ipv4(u32 ip, u16 port, int *error); +u32 tcp_accept(u32 listen_socket, int *error); + +int tcp_write(u32 socket, const u8 *buffer, u64 len, u64 *out); +int tcp_read(u32 socket, u8 *buffer, u64 buffer_size, u64 *out); + +struct TcpListen { + u32 ip; + u16 port; + struct stack incoming_connections; +}; + +struct TcpConnection { + int dead; + u16 incoming_port; + u32 outgoing_ip; + u16 outgoing_port; + + int unhandled_packet; + + FIFO_FILE *data_file; + + u32 seq; + u32 ack; + + int handshake_state; +}; + +struct TcpConnection *internal_tcp_incoming(u32 src_ip, u16 src_port, + u32 dst_ip, u16 dst_port); + +struct TcpConnection *tcp_find_connection(u16 port); + typedef struct { vfs_fd_t *ptr_socket_fd; FIFO_FILE *fifo_file; @@ -42,20 +79,6 @@ typedef struct { SOCKET *s; } OPEN_INET_SOCKET; -struct INCOMING_TCP_CONNECTION { - u8 ip[4]; - u16 n_port; - u16 dst_port; - FIFO_FILE *data_file; - struct buffered buffer; - u8 *has_data_ptr; - u8 is_used; - u32 ack_num; - u32 seq_num; - u8 connection_closed; - u8 requesting_connection_close; -}; - typedef u32 in_addr_t; typedef u16 in_port_t; typedef unsigned int sa_family_t; |