[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH] tcpip: Verbindung schliessen beim close()



+ tcpip: Wenn der Benutzer die Datei zumacht, sollten wir auch die
  TCP-Verbindung schliessen.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/tcpip/include/tcp.h |    2 ++
 src/modules/tcpip/lostio_if.c   |    4 ++--
 src/modules/tcpip/tcp.c         |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/modules/tcpip/include/tcp.h b/src/modules/tcpip/include/tcp.h
index b0b5917..c741ea8 100644
--- a/src/modules/tcpip/include/tcp.h
+++ b/src/modules/tcpip/include/tcp.h
@@ -44,6 +44,7 @@
 #define TCPS_CONNECTED_FIN 4
 #define TCPS_CLOSED 5
 #define TCPS_WAIT_FOR_ACCEPT 6
+#define TCPS_WAIT_FOR_FIN_ACK 7
 
 #define TCPF_FIN    (1 << 0)
 #define TCPF_SYN    (1 << 1)
@@ -116,6 +117,7 @@ struct tcp_server {
 
 void init_tcp(void);
 struct tcp_connection* tcp_open_connection(dword ip, word port);
+void tcp_close_connection(struct tcp_connection* conn);
 void tcp_free_connection(struct tcp_connection* conn);
 void tcp_accept_connection(struct tcp_connection* conn);
 
diff --git a/src/modules/tcpip/lostio_if.c b/src/modules/tcpip/lostio_if.c
index b79ebf8..1f3b428 100644
--- a/src/modules/tcpip/lostio_if.c
+++ b/src/modules/tcpip/lostio_if.c
@@ -337,15 +337,15 @@ int lostio_tcp_close(lostio_filehandle_t* filehandle)
         free(buffer->data);
         free(buffer);
     }
+    v();
 
-    // TODO tcp_connection_close
+    tcp_close_connection(conn);
     /*
      * TODO Reaktivieren, sobald die Verbindungen nicht mehr hartkodiert sind
     if (--(filehandle->node->size) == 0) {
         vfstree_delete_node(filehandle->node->name);
     }
     */
-    v();
 
     return 0;
 }
diff --git a/src/modules/tcpip/tcp.c b/src/modules/tcpip/tcp.c
index b8a7f0f..60fb896 100644
--- a/src/modules/tcpip/tcp.c
+++ b/src/modules/tcpip/tcp.c
@@ -179,6 +179,7 @@ static void tcp_send_reset(struct tcp_connection* conn)
 static void tcp_send_fin(struct tcp_connection* conn, bool ack)
 {
     tcp_send_packet(conn, NULL, 0, TCPF_FIN | (ack ? TCPF_ACK : 0));
+    conn->seq++;
 }
 
 static void do_nothing(void) {}
@@ -265,6 +266,30 @@ void tcp_free_connection(struct tcp_connection* conn)
     free(conn);
 }
 
+void tcp_close_connection(struct tcp_connection* conn)
+{
+    uint64_t timeout;
+
+    DEBUG_MSG("tcp_send_fin_ack");
+    conn->status = TCPS_WAIT_FOR_FIN_ACK;
+    tcp_send_fin(conn, FALSE);
+
+    timeout = get_tick_count() + 9 * 1000000;
+    timer_register(do_nothing, 10 * 1000000);
+    while ((conn->status == TCPS_WAIT_FOR_FIN_ACK)
+        && (get_tick_count() < timeout))
+    {
+        wait_for_rpc();
+    }
+
+    if (conn->status == TCPS_WAIT_FOR_FIN_ACK) {
+        tcp_send_reset(conn);
+        DEBUG_MSG("Timeout beim Schliessen der Verbindung");
+    }
+
+    tcp_free_connection(conn);
+}
+
 void tcp_accept_connection(struct tcp_connection* conn)
 {
     DEBUG_MSG("tcp_send_syn_ack");
@@ -512,6 +537,15 @@ void tcp_receive(dword source_ip, void* data, dword data_size)
             }*/
             break;
 
+        case TCPS_WAIT_FOR_FIN_ACK:
+            if ((header->flags & TCPF_FIN) && (header->flags & TCPF_ACK)) {
+                DEBUG_MSG("FIN ACK erhalten");
+                conn->ack = big_endian_dword(header->seq) + 1;
+                tcp_send_ack(conn);
+                conn->status = TCPS_CLOSED;
+            }
+            break;
+
         case TCPS_WAIT_FOR_LAST_ACK:
             // TODO: Pr�fen, ob f�r das richtige Segment
             DEBUG_MSG("ACK");
-- 
1.6.0.2