static void tcplib_send_rst(struct ip6_hdr *iph, struct tcp_hdr *tcph) {
struct split_ip_msg *msg = get_ipmsg(0);
+ struct tcp_hdr *tcp_rep;
- if (msg != NULL) {
- struct tcp_hdr *tcp_rep = (struct tcp_hdr *)(msg + 1);
-
- memcpy(&msg->hdr.ip6_dst, &iph->ip6_src, 16);
-
- tcp_rep->flags = TCP_FLAG_RST | TCP_FLAG_ACK;
+ if (msg == NULL) {
+ return;
+ }
+
+ tcp_rep = (struct tcp_hdr *)(msg + 1);
- tcp_rep->ackno = htonl(ntohl(tcph->seqno) + 1);
- tcp_rep->seqno = tcph->ackno;;
+ tcp_rep->flags = TCP_FLAG_RST | TCP_FLAG_ACK;
- tcp_rep->srcport = tcph->dstport;
- tcp_rep->dstport = tcph->srcport;
- tcp_rep->offset = sizeof(struct tcp_hdr) * 4;
- tcp_rep->window = 0;
- tcp_rep->chksum = 0;
- tcp_rep->urgent = 0;
+ tcp_rep->ackno = htonl(ntohl(tcph->seqno) + 1);
+ tcp_rep->seqno = tcph->ackno;;
- tcplib_send_out(msg, tcp_rep);
+ tcp_rep->srcport = tcph->dstport;
+ tcp_rep->dstport = tcph->srcport;
+ tcp_rep->offset = sizeof(struct tcp_hdr) * 4;
+ tcp_rep->window = 0;
+ tcp_rep->chksum = 0;
+ tcp_rep->urgent = 0;
- ip_free(msg);
-
- }
+ memcpy(&msg->hdr.ip6_dst, &iph->ip6_src, 16);
+
+ tcplib_send_out(msg, tcp_rep);
+ ip_free(msg);
}
/* send all the data in the tx buffer, starting at sseqno */
// TODO : this should be after we detect out-of-sequence ACK
// numbers!
this_conn->r_wind = ntohs(tcph->window);
+ printf("State: %i\n", this_conn->state);
switch (this_conn->state) {
case TCP_LAST_ACK:
break;
}
case TCP_FIN_WAIT_1:
+ printf("IN FIN_WAIT_1, %i\n", (tcph->flags & TCP_FLAG_FIN));
if (tcph->flags & TCP_FLAG_ACK &&
hdr_ackno == this_conn->seqno + 1) {
if (tcph->flags & TCP_FLAG_FIN) {
// resources while we're in it...
this_conn->timer.retx = TCPLIB_TIMEWAIT_LEN;
} else {
+ this_conn->timer.retx = TCPLIB_2MSL;
this_conn->state = TCP_FIN_WAIT_2;
}
- // this generate the ACK we need here
- goto ESTABLISHED;
}
+ // this generate the ACK we need here
+ goto ESTABLISHED;
case TCP_FIN_WAIT_2:
-
+ if (tcph->flags & TCP_FLAG_FIN) {
+ this_conn->seqno++;
+ this_conn->state = TCP_TIME_WAIT;
+
+ this_conn->timer.retx = TCPLIB_TIMEWAIT_LEN;
+ tcplib_send_ack(this_conn, 0, TCP_FLAG_ACK);
+ }
break;
case TCP_SYN_SENT:
this_conn->flags |= TCP_ACKSENT;
}
} else { // (hdr_seqno == this_conn->ackno) {
+ printf("receive data\n");
receive_data(this_conn, tcph, len - sizeof(struct ip6_hdr));
if (this_conn->flags & TCP_ACKSENT) {
case TCP_TIME_WAIT:
if ((payload_len > 0 && (this_conn->flags & TCP_ACKPENDING) >= 1)
|| tcph->flags & TCP_FLAG_FIN) {
- tcplib_send_ack(this_conn, (payload_len == 0 && tcph->flags & TCP_FLAG_FIN), TCP_FLAG_ACK);
+ tcplib_send_ack(this_conn, (payload_len == 0 && (tcph->flags & TCP_FLAG_FIN)), TCP_FLAG_ACK);
/* only close the connection if we've gotten all the data */
if (this_conn->state == TCP_ESTABLISHED
- && tcph->flags & TCP_FLAG_FIN
+ && (tcph->flags & TCP_FLAG_FIN)
&& hdr_seqno == this_conn->ackno) {
this_conn->state = TCP_CLOSE_WAIT;
tcplib_extern_closed(this_conn);
case TCP_LAST_ACK:
case TCP_FIN_WAIT_1:
tcplib_send_ack(sock, 1, TCP_FLAG_ACK | TCP_FLAG_FIN);
- sock->timer.retx = 6;
+ sock->timer.retx = TCPLIB_2MSL;
break;
+ case TCP_FIN_WAIT_2:
case TCP_TIME_WAIT:
sock->state = TCP_CLOSED;
// exit TIME_WAIT
case TCP_ESTABLISHED:
// kick off the close
tcplib_send_ack(sock, 0, TCP_FLAG_ACK | TCP_FLAG_FIN);
- sock->timer.retx = 6;
+ sock->timer.retx = TCPLIB_2MSL;
sock->state = TCP_FIN_WAIT_1;
break;
case TCP_SYN_SENT: