summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/fs/fifo.c1
-rw-r--r--kernel/lib/stack.h6
-rw-r--r--kernel/network/tcp.c166
-rw-r--r--kernel/network/tcp.h7
-rw-r--r--kernel/network/udp.c42
-rw-r--r--kernel/socket.c270
-rw-r--r--kernel/socket.h51
-rwxr-xr-xmeta/kernel.sh2
8 files changed, 299 insertions, 246 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;
diff --git a/meta/kernel.sh b/meta/kernel.sh
index dd74999..f37ec9b 100755
--- a/meta/kernel.sh
+++ b/meta/kernel.sh
@@ -2,4 +2,4 @@
scriptdir="$(dirname "$0")"
cd "$scriptdir"
export PATH="$PATH:$(pwd)/../toolchain/bin/bin"
-make -C ../kernel
+make -j`nproc` -C ../kernel