In this illustration, a black arrow extends diagonally downward from left to right and points to a blue circle labeled "Wait for 0 from below." A blue arrow extends from the top of this circle and arcs rightward to a second blue circle. The arrow has two labels separated by a horizontal line. On top: "rdt_rcv(rcvpkt)&& notcorrupt(rcvpkt) && has_seq0(rcvpkt)." On bottom:

"extract(rcvpkt,data) deliver_data(data) sndpkt=make_pkt(ACK,checksum) udt_send(sndpkt)."

The second blue circle is labeled "Wait for 1 from below." A smaller blue arrow extends from the center right side of the circle and arcs sharply back toward the upper right side of the same circle. This arrow has two labels. On top: "rdt_rcv(rcvpkt) && corrupt(rcvpkt)." On bottom: "sndpkt=make_pkt(NAK,checksum) udt_send(sndpkt)."

A smaller blue arrow also extends from the center right side of the circle and arcs sharply back to the lower right side of the same circle. This arrow has two labels. On top: "rdt_rcv(rcvpkt)&& notcorrupt (rcvpkt)&&has_seq0(rcvpkt)."

On bottom: "sndpkt=make_pkt(ACK,checksum) udt_send(sndpkt)."

A blue arrow extends from the bottom of the second blue circle and arcs leftward to the bottom of the first blue circle. This arrow has two labels. On top: "rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && has_seq1(rcvpkt)."

On bottom: "extract(rcvpkt,data) deliver_data(data) sndpkt=make_pkt(ACK,checksum) udt_send(sndpkt)."

A smaller blue arrow extends from the center left side of the first blue circle and arcs sharply back to the bottom left side of the same circle. This arrow has two labels. On top: "rdt_rcv(rcvpkt)&& notcorrupt (rcvpkt)&&has_seq1(rcvpkt)."

On bottom: "sndpkt=make_pkt(ACK,checksum) udt_send(sndpkt)."

A smaller blue arrow extends from the center left side of the first blue circle and arcs sharply back to the top left side of the same circle. This arrow has two labels. On top: "rdt_rcv(rcvpkt)?&& corrupt(rcvpkt)."

On bottom: "sndpkt=make_pkt(NAK,checksum) udt_send(sndpkt)."