size_t seq_len;
size_t app_win;
size_t max_rcv_win;
+ int rc;
/* If retransmission timer is already running, do nothing */
if ( timer_running ( &tcp->timer ) )
/* Allocate I/O buffer */
iobuf = alloc_iob ( len + MAX_HDR_LEN );
if ( ! iobuf ) {
- DBGC ( tcp, "TCP %p could not allocate data buffer\n", tcp );
+ DBGC ( tcp, "TCP %p could not allocate iobuf for %08x..%08x "
+ "%08x\n", tcp, tcp->snd_seq, ( tcp->snd_seq + seq_len ),
+ tcp->rcv_ack );
return -ENOMEM;
}
iob_reserve ( iobuf, MAX_HDR_LEN );
DBGC2 ( tcp, "\n" );
/* Transmit packet */
- return tcpip_tx ( iobuf, &tcp_protocol, NULL, &tcp->peer, NULL,
- &tcphdr->csum );
+ if ( ( rc = tcpip_tx ( iobuf, &tcp_protocol, NULL, &tcp->peer, NULL,
+ &tcphdr->csum ) ) != 0 ) {
+ DBGC ( tcp, "TCP %p could not transmit %08x..%08x %08x: %s\n",
+ tcp, tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ),
+ tcp->rcv_ack, strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
}
/**
container_of ( timer, struct tcp_connection, timer );
int graceful_close = TCP_CLOSED_GRACEFULLY ( tcp->tcp_state );
- DBGC ( tcp, "TCP %p timer %s in %s for [%08x,%08x)\n", tcp,
+ DBGC ( tcp, "TCP %p timer %s in %s for %08x..%08x %08x\n", tcp,
( over ? "expired" : "fired" ), tcp_state ( tcp->tcp_state ),
- tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ) );
+ tcp->snd_seq, ( tcp->snd_seq + tcp->snd_sent ), tcp->rcv_ack );
assert ( ( tcp->tcp_state == TCP_SYN_SENT ) ||
( tcp->tcp_state == TCP_SYN_RCVD ) ||
struct tcp_header *in_tcphdr ) {
struct io_buffer *iobuf;
struct tcp_header *tcphdr;
+ int rc;
/* Allocate space for dataless TX buffer */
iobuf = alloc_iob ( MAX_HDR_LEN );
if ( ! iobuf ) {
- DBGC ( tcp, "TCP %p could not allocate data buffer\n", tcp );
+ DBGC ( tcp, "TCP %p could not allocate iobuf for RST "
+ "%08x..%08x %08x\n", tcp, ntohl ( in_tcphdr->ack ),
+ ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ) );
return -ENOMEM;
}
iob_reserve ( iobuf, MAX_HDR_LEN );
DBGC2 ( tcp, "\n" );
/* Transmit packet */
- return tcpip_tx ( iobuf, &tcp_protocol, NULL, st_dest,
- NULL, &tcphdr->csum );
+ if ( ( rc = tcpip_tx ( iobuf, &tcp_protocol, NULL, st_dest,
+ NULL, &tcphdr->csum ) ) != 0 ) {
+ DBGC ( tcp, "TCP %p could not transmit RST %08x..%08x %08x: "
+ "%s\n", tcp, ntohl ( in_tcphdr->ack ),
+ ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ),
+ strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
}
/***************************************************************************
* timer running, as for the ack_len==0 case, to
* handle old duplicate ACKs.
*/
- DBGC ( tcp, "TCP %p received ACK for [%08x,%08zx), "
- "sent only [%08x,%08x)\n", tcp, tcp->snd_seq,
+ DBGC ( tcp, "TCP %p received ACK for %08x..%08zx, "
+ "sent only %08x..%08x\n", tcp, tcp->snd_seq,
( tcp->snd_seq + ack_len ), tcp->snd_seq,
( tcp->snd_seq + tcp->snd_sent ) );
/* Send RST if an out-of-range ACK is received on a
len -= already_rcvd;
/* Deliver data to application */
- if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 )
+ if ( ( rc = xfer_deliver_iob ( &tcp->xfer, iobuf ) ) != 0 ) {
+ DBGC ( tcp, "TCP %p could not deliver %08x..%08x: %s\n",
+ tcp, seq, ( seq + len ), strerror ( rc ) );
return rc;
+ }
/* Acknowledge new data */
tcp_rx_seq ( tcp, len );
tcp_dump_state ( tcp );
tcp_close ( tcp, -ECONNRESET );
+ DBGC ( tcp, "TCP %p connection reset by peer\n", tcp );
return -ECONNRESET;
}