Program: 5608
Project: 5608
Buggy source:
synchronized void receive(TCPPacket tcpPacket){
  int plen=tcpPacket.payload == null ? 0 : tcpPacket.payload.length;
  if (tcpPacket.isAck()) {
    if (sentUnack < tcpPacket.ackNo && sendNext >= tcpPacket.ackNo) {
      int noAcked=tcpPacket.ackNo - sentUnack;
      sentUnack=tcpPacket.ackNo;
      bufPos+=noAcked;
      if (bufPos >= outgoingBuffer.length)       bufPos=0;
      System.out.println("String_Node_Str" + noAcked + "String_Node_Str"+ bufPos+ "String_Node_Str"+ bufNextEmpty+ "String_Node_Str"+ Integer.toString(sentUnack & 0xffff,16)+ "String_Node_Str"+ Integer.toString(sendNext & 0xffff,16));
      notify();
    }
 else {
      System.out.println("String_Node_Str" + Integer.toString(tcpPacket.ackNo & 0xffff,16) + "String_Node_Str"+ Integer.toString(sendNext & 0xffff,16)+ "String_Node_Str"+ Integer.toString(sentUnack & 0xffff,16));
      if (tcpPacket.ackNo == sentUnack) {
        resend();
      }
    }
  }
  if (receiveNext == tcpPacket.seqNo) {
  }
 else {
    System.out.println("String_Node_Str" + Integer.toString(receiveNext & 0xffff,16) + "String_Node_Str"+ Integer.toString(tcpPacket.seqNo & 0xffff,16));
  }
  receiveNext=tcpPacket.seqNo + plen;
  if (tcpPacket.isFin()) {
    if (tcpListener != null && plen > 0) {
      tcpListener.connectionClosed(this);
    }
  }
  if (plen > 0) {
    TCPPacket tcpReply=TCPHandler.createAck(tcpPacket,0);
    tcpReply.ackNo=tcpPacket.seqNo + plen;
    tcpReply.seqNo=sendNext;
    send(tcpReply);
    if (tcpListener != null) {
      tcpListener.tcpDataReceived(this,tcpPacket);
    }
  }
}

Fixed version (ground truth):
synchronized void receive(TCPPacket tcpPacket){
  int plen=tcpPacket.payload == null ? 0 : tcpPacket.payload.length;
  if (tcpPacket.isAck()) {
    if (sentUnack < tcpPacket.ackNo && sendNext >= tcpPacket.ackNo) {
      int noAcked=tcpPacket.ackNo - sentUnack;
      sentUnack=tcpPacket.ackNo;
      bufPos+=noAcked;
      if (bufPos >= outgoingBuffer.length)       bufPos-=outgoingBuffer.length;
      System.out.println("String_Node_Str" + noAcked + "String_Node_Str"+ bufPos+ "String_Node_Str"+ bufNextEmpty+ "String_Node_Str"+ Integer.toString(sentUnack & 0xffff,16)+ "String_Node_Str"+ Integer.toString(sendNext & 0xffff,16)+ "String_Node_Str"+ outSize()+ "String_Node_Str"+ (sendNext - sentUnack));
      notify();
    }
 else {
      System.out.println("String_Node_Str" + Integer.toString(tcpPacket.ackNo & 0xffff,16) + "String_Node_Str"+ Integer.toString(sendNext & 0xffff,16)+ "String_Node_Str"+ Integer.toString(sentUnack & 0xffff,16));
      if (tcpPacket.ackNo == sentUnack) {
        resend();
      }
    }
  }
  if (receiveNext == tcpPacket.seqNo) {
  }
 else {
    System.out.println("String_Node_Str" + Integer.toString(receiveNext & 0xffff,16) + "String_Node_Str"+ Integer.toString(tcpPacket.seqNo & 0xffff,16));
  }
  receiveNext=tcpPacket.seqNo + plen;
  if (tcpPacket.isFin()) {
    if (tcpListener != null && plen > 0) {
      tcpListener.connectionClosed(this);
    }
  }
  if (plen > 0) {
    TCPPacket tcpReply=TCPHandler.createAck(tcpPacket,0);
    tcpReply.ackNo=tcpPacket.seqNo + plen;
    tcpReply.seqNo=sendNext;
    send(tcpReply);
    if (tcpListener != null) {
      tcpListener.tcpDataReceived(this,tcpPacket);
    }
  }
}