Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/See/tcp_session.c')
-rw-r--r--src/See/tcp_session.c296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/See/tcp_session.c b/src/See/tcp_session.c
new file mode 100644
index 00000000..cce97465
--- /dev/null
+++ b/src/See/tcp_session.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2001 - 2003
+ * NetGroup, Politecnico di Torino (Italy)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <GlobalConst.h>
+
+#ifdef WIN32
+#include "tme.h"
+#include "tcp_session.h"
+#endif
+
+#ifdef __FreeBSD
+
+#ifdef _KERNEL
+#include <net/tme/tme.h>
+#include <net/tme/tcp_session.h>
+#else
+#include <tme/tme.h>
+#include <tme/tcp_session.h>
+#endif
+
+#endif
+
+uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data)
+
+{
+
+ uint32 next_status;
+ uint32 direction=ULONG_AT(mem_data,12);
+ uint8 flags=mem_ex->buffer[25];
+ tcp_data *session=(tcp_data*)(block+data->key_len*4);
+
+ session->last_timestamp=session->timestamp_block;
+ session->timestamp_block.tv_sec=0x7fffffff;
+
+ if (direction==session->direction)
+ {
+ session->pkts_cln_to_srv++;
+ session->bytes_cln_to_srv+=pkt_size;
+ }
+ else
+ {
+ session->pkts_srv_to_cln++;
+ session->bytes_srv_to_cln+=pkt_size;
+ }
+ /* we use only thes four flags, we don't need PSH or URG */
+ flags&=(ACK|FIN|SYN|RST);
+
+ switch (session->status)
+ {
+ case ERROR_TCP:
+ next_status=ERROR_TCP;
+ break;
+
+ case UNKNOWN:
+ if (flags==SYN)
+ {
+ if (SW_ULONG_AT(mem_ex->buffer,20)!=0)
+ {
+
+ next_status=ERROR_TCP;
+ break;
+ }
+ next_status=SYN_RCV;
+ session->syn_timestamp=session->last_timestamp;
+
+ session->direction=direction;
+ session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16);
+ }
+ else
+ next_status=UNKNOWN;
+ break;
+
+ case SYN_RCV:
+ if ((flags&RST)&&(direction!=session->direction))
+ {
+ next_status=CLOSED_RST;
+ break;
+ }
+ if ((flags==SYN)&&(direction==session->direction))
+ { /* two syns... */
+ next_status=SYN_RCV;
+ session->seq_n_0_cln=SW_ULONG_AT(mem_ex->buffer,16);
+ break;
+ }
+
+ if ((flags==(SYN|ACK))&&(direction!=session->direction))
+ {
+ if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_cln+1)
+ {
+ next_status=ERROR_TCP;
+ break;
+ }
+ next_status=SYN_ACK_RCV;
+
+ session->syn_ack_timestamp=session->last_timestamp;
+
+ session->seq_n_0_srv=SW_ULONG_AT(mem_ex->buffer,16);
+ session->ack_cln=session->seq_n_0_cln+1;
+ }
+ else
+ {
+ next_status=ERROR_TCP;
+ }
+ break;
+
+ case SYN_ACK_RCV:
+ if ((flags&ACK)&&(flags&RST)&&(direction==session->direction))
+ {
+ next_status=CLOSED_RST;
+ session->ack_srv=SW_ULONG_AT(mem_ex->buffer,20);
+ break;
+ }
+
+ if ((flags==ACK)&&(!(flags&(SYN|FIN|RST)))&&(direction==session->direction))
+ {
+ if (SW_ULONG_AT(mem_ex->buffer,20)!=session->seq_n_0_srv+1)
+ {
+ next_status=ERROR_TCP;
+ break;
+ }
+ next_status=ESTABLISHED;
+ session->ack_srv=session->seq_n_0_srv+1;
+ break;
+ }
+ if ((flags&ACK)&&(flags&SYN)&&(direction!=session->direction))
+ {
+ next_status=SYN_ACK_RCV;
+ break;
+ }
+
+ next_status=ERROR_TCP;
+ break;
+
+ case ESTABLISHED:
+ if (flags&SYN)
+ {
+ if ((flags&ACK)&&
+ (direction!=session->direction)&&
+ ((session->ack_cln-SW_ULONG_AT(mem_ex->buffer,20))<MAX_WINDOW)
+ )
+ { /* SYN_ACK duplicato */
+ next_status=ESTABLISHED;
+ break;
+ }
+
+ if ((!(flags&ACK))&&
+ (direction==session->direction)&&
+ (SW_ULONG_AT(mem_ex->buffer,16)==session->seq_n_0_cln)&&
+ (ULONG_AT(mem_ex->buffer,20)==0)
+ )
+ { /* syn duplicato */
+ next_status=ESTABLISHED;
+ break;
+ }
+
+ next_status=ERROR_TCP;
+ break;
+ }
+ if (flags&ACK)
+ if (direction==session->direction)
+ {
+ uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
+ if (new_ack-session->ack_srv<MAX_WINDOW)
+ session->ack_srv=new_ack;
+ }
+ else
+ {
+ uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
+ if (new_ack-session->ack_cln<MAX_WINDOW)
+ session->ack_cln=new_ack;
+ }
+ if (flags&RST)
+ {
+ next_status=CLOSED_RST;
+ break;
+ }
+ if (flags&FIN)
+ if (direction==session->direction)
+ { /* an hack to make all things work */
+ session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16);
+ next_status=FIN_CLN_RCV;
+ break;
+ }
+ else
+ {
+ session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16);
+ next_status=FIN_SRV_RCV;
+ break;
+ }
+ next_status=ESTABLISHED;
+ break;
+
+ case CLOSED_RST:
+ next_status=CLOSED_RST;
+ break;
+
+ case FIN_SRV_RCV:
+ if (flags&SYN)
+ {
+ next_status=ERROR_TCP;
+ break;
+ }
+
+ next_status=FIN_SRV_RCV;
+
+ if (flags&ACK)
+ {
+ uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
+ if (direction!=session->direction)
+ if ((new_ack-session->ack_cln)<MAX_WINDOW)
+ session->ack_cln=new_ack;
+ }
+
+ if (flags&RST)
+ next_status=CLOSED_RST;
+ else
+ if ((flags&FIN)&&(direction==session->direction))
+ {
+ session->ack_cln=SW_ULONG_AT(mem_ex->buffer,16);
+ next_status=CLOSED_FIN;
+ }
+
+ break;
+
+ case FIN_CLN_RCV:
+ if (flags&SYN)
+ {
+ next_status=ERROR_TCP;
+ break;
+ }
+
+ next_status=FIN_CLN_RCV;
+
+ if (flags&ACK)
+ {
+ uint32 new_ack=SW_ULONG_AT(mem_ex->buffer,20);
+ if (direction==session->direction)
+ if (new_ack-session->ack_srv<MAX_WINDOW)
+ session->ack_srv=new_ack;
+ }
+
+ if (flags&RST)
+ next_status=CLOSED_RST;
+ else
+ if ((flags&FIN)&&(direction!=session->direction))
+ {
+ session->ack_srv=SW_ULONG_AT(mem_ex->buffer,16);
+ next_status=CLOSED_FIN;
+ }
+
+ break;
+
+ case CLOSED_FIN:
+ next_status=CLOSED_FIN;
+ break;
+ default:
+ next_status=ERROR_TCP;
+
+ }
+
+ session->status=next_status;
+
+ if ((next_status==CLOSED_FIN)||(next_status==UNKNOWN)||(next_status==CLOSED_RST)||(next_status==ERROR_TCP))
+ session->timestamp_block=session->last_timestamp;
+
+ return TME_SUCCESS;
+}