diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp index fa89eee..51dbc94 100644 --- a/src/session/session_manager.cpp +++ b/src/session/session_manager.cpp @@ -290,6 +290,8 @@ static void tcp_update(struct session_manager *mgr, struct session *sess, enum f { half->isn = tcp_hdr_get_seq(hdr); } + half->inject_inc_ack_offset = 0; + half->inject_inc_seq_offset = 0; half->flags = flags; half->history |= flags; half->seq = tcp_hdr_get_seq(hdr); diff --git a/src/session/session_priv.h b/src/session/session_priv.h index 46fdbd2..2890f79 100644 --- a/src/session/session_priv.h +++ b/src/session/session_priv.h @@ -27,6 +27,9 @@ struct tcp_half struct tcp_segment in_order; // current packet in order segment uint32_t in_order_ref; // reference count of current packet in order segment + uint32_t inject_inc_seq_offset; // inject packet base on current packet increase seq offset + uint32_t inject_inc_ack_offset; // inject packet base on current packet increase ack offset + uint32_t seq; // current packet sequence number uint32_t ack; // current packet ack number uint16_t len; // current packet payload length diff --git a/src/stellar/inject.cpp b/src/stellar/inject.cpp index 400d3c1..ad1b5d6 100644 --- a/src/stellar/inject.cpp +++ b/src/stellar/inject.cpp @@ -164,7 +164,7 @@ static void update_ip6_hdr(struct ip6_hdr *ip6hdr, int trim) ipv6_hdr_set_payload_len(ip6hdr, len - trim); } -static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direction inject_dir, uint32_t *seq, uint32_t *ack) +static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direction inject_dir, uint32_t *seq, uint32_t *ack, uint16_t len) { /* * +--------+ current packet +---------+ C2S RST +--------+ @@ -188,16 +188,20 @@ static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direct */ enum flow_direction curr_dir = session_get_current_flow_direction(sess); - const struct tcp_half *tcp_curr_half = &sess->tcp_halfs[curr_dir]; + struct tcp_half *tcp_curr_half = (struct tcp_half *)&sess->tcp_halfs[curr_dir]; if (inject_dir == curr_dir) { - *seq = tcp_curr_half->seq; - *ack = tcp_curr_half->ack; + *seq = uint32_add(tcp_curr_half->seq, tcp_curr_half->inject_inc_seq_offset); + *ack = uint32_add(tcp_curr_half->ack, tcp_curr_half->inject_inc_ack_offset); + + tcp_curr_half->inject_inc_seq_offset += len; } else { - *seq = tcp_curr_half->ack; - *ack = tcp_curr_half->seq + tcp_curr_half->len + (tcp_curr_half->flags & TH_SYN ? 1 : 0); + *seq = uint32_add(tcp_curr_half->ack, tcp_curr_half->inject_inc_ack_offset); + *ack = uint32_add(tcp_curr_half->seq, tcp_curr_half->inject_inc_seq_offset + tcp_curr_half->len + (tcp_curr_half->flags & TH_SYN ? 1 : 0)); + + tcp_curr_half->inject_inc_ack_offset += len; } } @@ -406,7 +410,7 @@ int inject_tcp_packet(const struct session *sess, enum flow_direction inject_dir uint32_t tcp_seq = 0; uint32_t tcp_ack = 0; char buff[4096] = {0}; - calc_tcp_seq_ack(sess, inject_dir, &tcp_seq, &tcp_ack); + calc_tcp_seq_ack(sess, inject_dir, &tcp_seq, &tcp_ack, len); calc_tcp_fingerprint(&finger); int pkt_len = build_tcp_packet(pkt, finger.ipid, finger.ttl, tcp_seq, tcp_ack, tcp_flags, finger.win, payload, len, buff, sizeof(buff));