diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c
index 549dab7d2244e50c9abc8541ed81b2cc52dfb4d8..9038cedbfb319bd50653be918ae0b2d76ea1fece 100644
--- a/gtests/net/packetdrill/run_packet.c
+++ b/gtests/net/packetdrill/run_packet.c
@@ -3211,6 +3211,7 @@ static int do_outbound_script_packet(
 	/* Save the TCP header so we can reset the connection at the end. */
 	if (live_packet->tcp) {
 		socket->last_outbound_tcp_header = *(live_packet->tcp);
+		socket->last_outbound_tcp_payload_len = packet_payload_len(live_packet);
 		if (live_packet->flags & FLAGS_UDP_ENCAPSULATED) {
 			struct udp *udp = (struct udp *)(live_packet->tcp) - 1;
 
@@ -3508,12 +3509,12 @@ int reset_connection(struct state *state, struct socket *socket)
 {
 	char *error = NULL;
 	u32 seq = 0, ack_seq = 0;
-	u16 window = 0;
 	struct packet *packet = NULL;
 	struct tuple live_inbound;
 	int result = STATUS_OK;
 	u16 udp_src_port;
 	u16 udp_dst_port;
+	bool ack_bit;
 
 	if (socket->last_outbound_udp_encaps_src_port != 0 ||
 	    socket->last_outbound_udp_encaps_dst_port != 0) {
@@ -3524,38 +3525,35 @@ int reset_connection(struct state *state, struct socket *socket)
 		udp_dst_port = socket->last_injected_udp_encaps_dst_port;
 	}
 	/* Pick TCP header fields to be something the kernel will accept. */
-	if (socket->last_injected_tcp_header.ack) {
-		/* If we've already injected something, then use a sequence
-		 * number right after the last one we injected, and ACK
-		 * the last thing we ACKed, and offer the same receive
-		 * window we last offered.
-		 */
-		seq	= (ntohl(socket->last_injected_tcp_header.seq) +
-			   (socket->last_injected_tcp_header.syn ? 1 : 0) +
-			   (socket->last_injected_tcp_header.fin ? 1 : 0) +
-			   socket->last_injected_tcp_payload_len);
-		ack_seq	= ntohl(socket->last_injected_tcp_header.ack_seq);
-		window	= ntohs(socket->last_injected_tcp_header.window);
-	} else if (socket->last_outbound_tcp_header.ack) {
-		/* If the kernel ACKed something, then just make sure
-		 * we use the sequence number it ACKed, which will be
-		 * something it expects.
-		 */
-		seq = ntohl(socket->last_outbound_tcp_header.ack_seq);
-		ack_seq = ntohl(socket->last_outbound_tcp_header.seq);
+	if (socket->last_outbound_tcp_header.doff > 0) {
+		/* The kernel has sent something. */
+		if (socket->last_outbound_tcp_header.ack) {
+			seq = ntohl(socket->last_outbound_tcp_header.ack_seq);
+			ack_seq = 0;
+			ack_bit = false;
+		} else {
+			seq = 0;
+			ack_seq = (ntohl(socket->last_outbound_tcp_header.seq) +
+			           (socket->last_outbound_tcp_header.syn ? 1 : 0) +
+			           (socket->last_outbound_tcp_header.fin ? 1 : 0) +
+			           socket->last_outbound_tcp_payload_len);
+			ack_bit = true;
+		}
+	} else if (socket->last_injected_tcp_header.doff > 0) {
+		/* The kernel hasn't sent anything, but a packet was injected */
+		seq = (ntohl(socket->last_injected_tcp_header.seq) +
+		       (socket->last_injected_tcp_header.syn ? 1 : 0) +
+		       (socket->last_injected_tcp_header.fin ? 1 : 0) +
+		       socket->last_injected_tcp_payload_len);
+		ack_seq = 0;
+		ack_bit = false;
 	} else {
-		/* If the kernel didn't ACK anything, then it probably
-		 * sent only an initial SYN. So we get to send any
-		 * sequence number we want, but should send an ACK
-		 * suggesting we've seen the kernel's SYN.
-		 */
-		seq = 0;
-		ack_seq = ntohl(socket->last_outbound_tcp_header.seq) + 1;
+		return result;
 	}
 
 	packet = new_tcp_packet(socket->address_family,
 				DIRECTION_INBOUND, ECN_NONE,
-				"R.", seq, 0, ack_seq, window, NULL, false, false,
+				ack_bit ? "R." : "R", seq, 0, ack_seq, 0, NULL, false, false,
 				false, false, udp_src_port, udp_dst_port, &error);
 	if (packet == NULL)
 		die("%s", error);
diff --git a/gtests/net/packetdrill/socket.h b/gtests/net/packetdrill/socket.h
index 0012903d35996d507a9e99f723817580394580bd..7cbdfded3bc4b14c84880c580e136d3bb26a644b 100644
--- a/gtests/net/packetdrill/socket.h
+++ b/gtests/net/packetdrill/socket.h
@@ -113,6 +113,7 @@ struct socket {
 	 * order to induce the kernel to free the socket.
 	 */
 	struct tcp last_outbound_tcp_header;
+	u32 last_outbound_tcp_payload_len;
 	struct tcp last_injected_tcp_header;
 	u32 last_injected_tcp_payload_len;