Skip to content
Snippets Groups Projects
Commit 570c2daf authored by Michael Tüxen's avatar Michael Tüxen
Browse files

Allow the TS ecr value to be absolute.

This is based on a patch from Jason Eggleston with minor modifications
from me.
parent 5b33bd42
No related branches found
No related tags found
No related merge requests found
...@@ -108,9 +108,10 @@ struct packet { ...@@ -108,9 +108,10 @@ struct packet {
u32 flags; /* various meta-flags */ u32 flags; /* various meta-flags */
#define FLAG_WIN_NOCHECK 0x1 /* don't check TCP receive window */ #define FLAG_WIN_NOCHECK 0x1 /* don't check TCP receive window */
#define FLAG_OPTIONS_NOCHECK 0x2 /* don't check TCP options */ #define FLAG_OPTIONS_NOCHECK 0x2 /* don't check TCP options */
#define FLAGS_SCTP_BAD_CRC32C 0x4 /* compute bad CRC32C for SCTP packets */ #define FLAG_ABSOLUTE_TS_ECR 0x4 /* don't adjust TCP TS ecr */
#define FLAGS_SCTP_EXPLICIT_TAG 0x8 /* verification tag specified */ #define FLAGS_SCTP_BAD_CRC32C 0x8 /* compute bad CRC32C for SCTP packets */
#define FLAGS_SCTP_GENERIC_PACKET 0x10 /* set if it is a generic packet */ #define FLAGS_SCTP_EXPLICIT_TAG 0x10 /* verification tag specified */
#define FLAGS_SCTP_GENERIC_PACKET 0x20 /* set if it is a generic packet */
enum ip_ecn_t ecn; /* IPv4/IPv6 ECN treatment for packet */ enum ip_ecn_t ecn; /* IPv4/IPv6 ECN treatment for packet */
......
...@@ -152,6 +152,12 @@ static struct script *out_script = NULL; ...@@ -152,6 +152,12 @@ static struct script *out_script = NULL;
/* The test invocation to pass back to parse_and_finalize_config(). */ /* The test invocation to pass back to parse_and_finalize_config(). */
struct invocation *invocation; struct invocation *invocation;
/* Temporary variables to allow passing absolute timestamp flags to
* the tcp_options struct from the timestamp options. Adding fields
* to struct tcp_option, which might be cleaner, affects the on-wire format.
*/
bool absolute_ts_ecr = false;
/* Copy the script contents into our single linear buffer. */ /* Copy the script contents into our single linear buffer. */
void copy_script(const char *script_buffer, struct script *script) void copy_script(const char *script_buffer, struct script *script)
{ {
...@@ -439,6 +445,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -439,6 +445,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
*/ */
%union { %union {
s64 integer; s64 integer;
struct abs_integer abs_integer;
double floating; double floating;
char *string; char *string;
char *reserved; char *reserved;
...@@ -586,6 +593,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -586,6 +593,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <floating> FLOAT %token <floating> FLOAT
%token <integer> INTEGER HEX_INTEGER %token <integer> INTEGER HEX_INTEGER
%token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
%type <abs_integer> abs_integer
%type <direction> direction %type <direction> direction
%type <ip_ecn> opt_ip_info %type <ip_ecn> opt_ip_info
%type <ip_ecn> ip_ecn %type <ip_ecn> ip_ecn
...@@ -2366,7 +2374,10 @@ tcp_packet_spec ...@@ -2366,7 +2374,10 @@ tcp_packet_spec
inner = new_tcp_packet(in_config->wire_protocol, inner = new_tcp_packet(in_config->wire_protocol,
direction, $2, $3, direction, $2, $3,
$4.start_sequence, $4.payload_bytes, $4.start_sequence, $4.payload_bytes,
$5, $6, $7, &error); $5, $6, $7,
absolute_ts_ecr,
&error);
absolute_ts_ecr = false;
free($3); free($3);
free($7); free($7);
if (inner == NULL) { if (inner == NULL) {
...@@ -2694,17 +2705,18 @@ tcp_option ...@@ -2694,17 +2705,18 @@ tcp_option
| SACK sack_block_list { | SACK sack_block_list {
$$ = $2; $$ = $2;
} }
| TIMESTAMP VAL INTEGER ECR INTEGER { | TIMESTAMP VAL INTEGER ECR abs_integer {
u32 val, ecr; u32 val, ecr;
absolute_ts_ecr = $5.absolute;
$$ = tcp_option_new(TCPOPT_TIMESTAMP, TCPOLEN_TIMESTAMP); $$ = tcp_option_new(TCPOPT_TIMESTAMP, TCPOLEN_TIMESTAMP);
if (!is_valid_u32($3)) { val = $3;
ecr = $5.integer;
if (!is_valid_u32(val)) {
semantic_error("ts val out of range"); semantic_error("ts val out of range");
} }
if (!is_valid_u32($5)) { if (!is_valid_u32(ecr)) {
semantic_error("ecr val out of range"); semantic_error("ecr val out of range");
} }
val = $3;
ecr = $5;
$$->data.time_stamp.val = htonl(val); $$->data.time_stamp.val = htonl(val);
$$->data.time_stamp.ecr = htonl(ecr); $$->data.time_stamp.ecr = htonl(ecr);
} }
...@@ -2720,6 +2732,11 @@ tcp_option ...@@ -2720,6 +2732,11 @@ tcp_option
} }
; ;
abs_integer
: INTEGER { $$.integer = $1; $$.absolute = false; }
| INTEGER '!' { $$.integer = $1; $$.absolute = true; }
;
sack_block_list sack_block_list
: sack_block { $$ = $1; } : sack_block { $$ = $1; }
| sack_block_list sack_block { | sack_block_list sack_block {
......
...@@ -936,6 +936,10 @@ static int map_inbound_packet( ...@@ -936,6 +936,10 @@ static int map_inbound_packet(
if (find_tcp_timestamp(live_packet, error)) if (find_tcp_timestamp(live_packet, error))
return STATUS_ERR; return STATUS_ERR;
/* If we are using absolute ecr values, do not adjust the ecr. */
if (live_packet->flags & FLAG_ABSOLUTE_TS_ECR) {
return STATUS_OK;
}
/* Remap TCP timestamp echo reply from script value to a live /* Remap TCP timestamp echo reply from script value to a live
* value. We say "a" rather than "the" live value because * value. We say "a" rather than "the" live value because
* there could be multiple live values corresponding to the * there could be multiple live values corresponding to the
...@@ -3389,7 +3393,7 @@ int reset_connection(struct state *state, struct socket *socket) ...@@ -3389,7 +3393,7 @@ int reset_connection(struct state *state, struct socket *socket)
packet = new_tcp_packet(socket->address_family, packet = new_tcp_packet(socket->address_family,
DIRECTION_INBOUND, ECN_NONE, DIRECTION_INBOUND, ECN_NONE,
"R.", seq, 0, ack_seq, window, NULL, &error); "R.", seq, 0, ack_seq, window, NULL, false, &error);
if (packet == NULL) if (packet == NULL)
die("%s", error); die("%s", error);
......
...@@ -59,6 +59,7 @@ struct packet *new_tcp_packet(int address_family, ...@@ -59,6 +59,7 @@ struct packet *new_tcp_packet(int address_family,
u32 ack_sequence, u32 ack_sequence,
s32 window, s32 window,
const struct tcp_options *tcp_options, const struct tcp_options *tcp_options,
bool abs_ts_ecr,
char **error) char **error)
{ {
struct packet *packet = NULL; /* the newly-allocated result packet */ struct packet *packet = NULL; /* the newly-allocated result packet */
...@@ -157,6 +158,10 @@ struct packet *new_tcp_packet(int address_family, ...@@ -157,6 +158,10 @@ struct packet *new_tcp_packet(int address_family,
tcp_options->length); tcp_options->length);
} }
if (abs_ts_ecr) {
packet->flags |= FLAG_ABSOLUTE_TS_ECR;
}
packet->ip_bytes = ip_bytes; packet->ip_bytes = ip_bytes;
return packet; return packet;
} }
...@@ -44,5 +44,6 @@ extern struct packet *new_tcp_packet(int address_family, ...@@ -44,5 +44,6 @@ extern struct packet *new_tcp_packet(int address_family,
u32 ack_sequence, u32 ack_sequence,
s32 window, s32 window,
const struct tcp_options *tcp_options, const struct tcp_options *tcp_options,
bool abs_ts_ecr,
char **error); char **error);
#endif /* __TCP_PACKET_H__ */ #endif /* __TCP_PACKET_H__ */
...@@ -133,6 +133,14 @@ enum ip_ecn_t { ...@@ -133,6 +133,14 @@ enum ip_ecn_t {
ECN_NOCHECK, ECN_NOCHECK,
}; };
/* Type to handle <integer>! for specifying absolute vs adjusted values.
* The <integer>! means absolute integer. Just a plain <integer> is relative.
*/
struct abs_integer {
s64 integer;
bool absolute;
};
/* Length of output buffer for inet_ntop, plus prefix length (e.g. "/128"). */ /* Length of output buffer for inet_ntop, plus prefix length (e.g. "/128"). */
#define ADDR_STR_LEN ((INET_ADDRSTRLEN + INET6_ADDRSTRLEN)+5) #define ADDR_STR_LEN ((INET_ADDRSTRLEN + INET6_ADDRSTRLEN)+5)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment