aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2020-11-24 12:15:01 +0100
committerMarvin Borner2020-11-24 12:15:01 +0100
commit39f3538f7ee56dab414d62201235f8427b4a9592 (patch)
treef58a946b8db1e753bfa9d1123d39ba52f06b0770 /kernel
parent8babf8b26e23ffdd8094c810295061effde153dd (diff)
Added userspace-based network timeout
The network in my whole city is down right now, so I've done some error catching using timeouts etc without the kernel blocking everything. Not having internet is exhausting though :(
Diffstat (limited to 'kernel')
-rw-r--r--kernel/features/net.c28
-rw-r--r--kernel/features/syscall.c13
-rw-r--r--kernel/inc/net.h1
3 files changed, 10 insertions, 32 deletions
diff --git a/kernel/features/net.c b/kernel/features/net.c
index d2fa4b9..3fa28c9 100644
--- a/kernel/features/net.c
+++ b/kernel/features/net.c
@@ -504,6 +504,8 @@ static void tcp_handle_packet(struct tcp_packet *packet, u32 dst, int len)
tcp->ack_no = recv_seq;
tcp->seq_no = recv_ack;
+ proc_from_pid(socket->pid)->state = PROC_RUNNING;
+
socket->state = S_CONNECTED;
tcp->state++;
return;
@@ -523,7 +525,6 @@ static void tcp_handle_packet(struct tcp_packet *packet, u32 dst, int len)
// TODO: How many segments are going to be sent?!
if ((flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_PSH)) {
- proc_from_pid(socket->pid)->state = PROC_RUNNING;
tcp_send_packet(socket, TCP_FLAG_ACK, NULL, 0);
tcp_send_packet(socket, TCP_FLAG_FIN | TCP_FLAG_ACK, NULL, 0);
tcp->state++;
@@ -764,22 +765,8 @@ int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port)
socket->prot.tcp.ack_no = 0;
socket->prot.tcp.state = 0;
socket->state = S_CONNECTING;
- // TODO: Don't block kernel
tcp_send_packet(socket, TCP_FLAG_SYN, NULL, 0);
- scheduler_disable();
- sti();
- u32 time = timer_get();
- while ((socket->state != S_CONNECTED && timer_get() - time < 1000)) {
- if (socket->state == S_FAILED)
- break;
- }
- cli();
- scheduler_enable();
- if (socket->state != S_CONNECTED) {
- socket->state = S_FAILED;
- return 0;
- }
- return 1;
+ return 0;
} else if (socket->type == S_UDP) {
socket->state = S_CONNECTED;
return 1;
@@ -804,15 +791,6 @@ void net_send(struct socket *socket, void *data, u32 len)
}
}
-int net_data_available(struct socket *socket)
-{
- if (net_installed() && socket && socket->packets && socket->packets->head &&
- ((struct socket_data *)socket->packets->head->data)->length > 0)
- return 1;
- else
- return 0;
-}
-
int net_receive(struct socket *socket, void *buf, u32 len)
{
if (!net_installed() || !socket || !socket->packets)
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index 3d70dbb..01720c5 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -111,7 +111,13 @@ void syscall_handler(struct regs *r)
break;
}
case SYS_NET_CONNECT: {
- r->eax = net_connect((void *)r->ebx, r->ecx, r->edx);
+ struct socket *s = (void *)r->ebx;
+ if (s->state == S_CONNECTED)
+ r->eax = 1;
+ else if (s->state == S_FAILED || s->state == S_CLOSED)
+ r->eax = 0;
+ else if (s->state == S_OPEN)
+ r->eax = net_connect(s, r->ecx, r->edx);
break;
}
case SYS_NET_SEND: {
@@ -119,11 +125,6 @@ void syscall_handler(struct regs *r)
break;
}
case SYS_NET_RECEIVE: {
- if (!net_data_available((void *)r->ebx)) {
- proc_current()->state = PROC_SLEEPING;
- proc_yield(r);
- return;
- }
r->eax = net_receive((void *)r->ebx, (void *)r->ecx, r->edx);
break;
}
diff --git a/kernel/inc/net.h b/kernel/inc/net.h
index 2ad3d65..2852328 100644
--- a/kernel/inc/net.h
+++ b/kernel/inc/net.h
@@ -161,7 +161,6 @@ int net_close(struct socket *socket);
int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port);
void net_send(struct socket *socket, void *data, u32 len);
int net_receive(struct socket *socket, void *buf, u32 len);
-int net_data_available(struct socket *socket);
int net_installed(void);
void net_install(void);