summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-02-15 18:20:58 -0800
committerDamjan Marion <dmarion@me.com>2019-02-18 07:03:06 +0000
commit830fe7370af7ac9e28e9be04b5b5712b22ad9c31 (patch)
treed179668d0e6e1e1eaad0a4a84e798a31dd924539 /src/vnet
parent26a101976d6213a01417aa99b35180a79100028b (diff)
tcp: fix handling of retransmitted syns
Change-Id: I88fdeb0ca56d3a5d9c0f36def13c6de8142f59f0 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/tcp/tcp_error.def3
-rw-r--r--src/vnet/tcp/tcp_input.c39
2 files changed, 26 insertions, 16 deletions
diff --git a/src/vnet/tcp/tcp_error.def b/src/vnet/tcp/tcp_error.def
index 0d6c44b5402..7bed10f1840 100644
--- a/src/vnet/tcp/tcp_error.def
+++ b/src/vnet/tcp/tcp_error.def
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2016-2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -26,6 +26,7 @@ tcp_error (PARTIALLY_ENQUEUED, "Packets partially pushed into rx fifo")
tcp_error (SEGMENT_OLD, "Old segment")
tcp_error (SEGMENT_INVALID, "Invalid segments")
tcp_error (SYNS_RCVD, "SYNs received")
+tcp_error (SPURIOUS_SYN, "Spurious SYNs received")
tcp_error (SYN_ACKS_RCVD, "SYN-ACKs received")
tcp_error (MSG_QUEUE_FULL, "Events not sent for lack of msg queue space")
tcp_error (CREATE_SESSION_FAIL, "Sessions couldn't be allocated")
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index da03cababb7..6514dca4b4a 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2016-2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -330,6 +330,26 @@ tcp_segment_validate (tcp_worker_ctx_t * wrk, tcp_connection_t * tc0,
if (!tcp_segment_in_rcv_wnd (tc0, vnet_buffer (b0)->tcp.seq_number,
vnet_buffer (b0)->tcp.seq_end))
{
+ /* SYN/SYN-ACK retransmit */
+ if (tcp_syn (th0)
+ && vnet_buffer (b0)->tcp.seq_number == tc0->rcv_nxt - 1)
+ {
+ tcp_options_parse (th0, &tc0->rcv_opts, 1);
+ if (tc0->state == TCP_STATE_SYN_RCVD)
+ {
+ tcp_send_synack (tc0);
+ TCP_EVT_DBG (TCP_EVT_SYN_RCVD, tc0, 0);
+ *error0 = TCP_ERROR_SYNS_RCVD;
+ }
+ else
+ {
+ tcp_program_ack (wrk, tc0);
+ TCP_EVT_DBG (TCP_EVT_SYNACK_RCVD, tc0);
+ *error0 = TCP_ERROR_SYN_ACKS_RCVD;
+ }
+ goto error;
+ }
+
*error0 = TCP_ERROR_RCV_WND;
/* If our window is 0 and the packet is in sequence, let it pass
* through for ack processing. It should be dropped later. */
@@ -356,22 +376,11 @@ tcp_segment_validate (tcp_worker_ctx_t * wrk, tcp_connection_t * tc0,
/* 3rd: check security and precedence (skip) */
- /* 4th: check the SYN bit */
+ /* 4th: check the SYN bit (in window) */
if (PREDICT_FALSE (tcp_syn (th0)))
{
- *error0 = tcp_ack (th0) ? TCP_ERROR_SYN_ACKS_RCVD : TCP_ERROR_SYNS_RCVD;
- /* TODO implement RFC 5961 */
- if (tc0->state == TCP_STATE_SYN_RCVD)
- {
- tcp_options_parse (th0, &tc0->rcv_opts, 1);
- tcp_send_synack (tc0);
- TCP_EVT_DBG (TCP_EVT_SYN_RCVD, tc0, 0);
- }
- else
- {
- tcp_program_ack (wrk, tc0);
- TCP_EVT_DBG (TCP_EVT_SYNACK_RCVD, tc0);
- }
+ *error0 = TCP_ERROR_SPURIOUS_SYN;
+ tcp_send_reset (tc0);
goto error;
}
nd-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 *------------------------------------------------------------------
 * Copyright (c) 2018 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

#ifndef SRC_VLIBMEMORY_MEMORY_API_H_
#define SRC_VLIBMEMORY_MEMORY_API_H_

#include <svm/svm.h>
#include <svm/ssvm.h>
#include <svm/queue.h>
#include <vlib/vlib.h>
#include <vlibapi/api.h>
#include <vlibmemory/memory_shared.h>

svm_queue_t *vl_api_client_index_to_input_queue (u32 index);
int vl_mem_api_init (const char *region_name);
void vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm,
				  f64 now);
int vl_mem_api_handle_msg_main (vlib_main_t * vm, vlib_node_runtime_t * node);
int vl_mem_api_handle_msg_private (vlib_main_t * vm,
				   vlib_node_runtime_t * node, u32 reg_index);
int vl_mem_api_handle_rpc (vlib_main_t * vm, vlib_node_runtime_t * node);

vl_api_registration_t *vl_mem_api_client_index_to_registration (u32 handle);
void vl_mem_api_enable_disable (vlib_main_t * vm, int yesno);
u32 vl_api_memclnt_create_internal (char *, svm_queue_t *);

static inline u32
vl_msg_api_handle_get_epoch (u32 index)
{
  return (index & VL_API_EPOCH_MASK);
}

static inline u32
vl_msg_api_handle_get_index (u32 index)
{
  return (index >> VL_API_EPOCH_SHIFT);
}

static inline u32
vl_msg_api_handle_from_index_and_epoch (u32 index, u32 epoch)
{
  u32 handle;
  ASSERT (index < 0x00FFFFFF);

  handle = (index << VL_API_EPOCH_SHIFT) | (epoch & VL_API_EPOCH_MASK);
  return handle;
}

static inline u8
vl_msg_api_handle_is_valid (u32 handle, u32 restarts)
{
  u32 epoch = vl_msg_api_handle_get_epoch (handle);
  return ((restarts & VL_API_EPOCH_MASK) == epoch);
}

#define VL_MEM_API_LOG_Q_LEN(fmt,qlen)			\
if (TRACE_VLIB_MEMORY_QUEUE)				\
  do {							\
      ELOG_TYPE_DECLARE (e) = {				\
        .format = fmt,					\
        .format_args = "i4",				\
      };							\
      struct { u32 len; } *ed;				\
      ed = ELOG_DATA (&vm->elog_main, e);		\
      ed->len = qlen;					\
  } while (0)

#endif /* SRC_VLIBMEMORY_MEMORY_API_H_ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */