- /*
- * Header prediction: check for the two common cases
- * of a uni-directional data xfer. If the packet has
- * no control flags, is in-sequence, the window didn't
- * change and we're not retransmitting, it's a
- * candidate. If the length is zero and the ack moved
- * forward, we're the sender side of the xfer. Just
- * free the data acked & wake any higher level process
- * that was blocked waiting for space. If the length
- * is non-zero and the ack didn't move, we're the
- * receiver side. If we're getting packets in-order
- * (the reassembly queue is empty), add the data to
+ if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) {
+ if (to.to_flags & TOF_SCALE) {
+ tp->t_flags |= TF_RCVD_SCALE;
+ tp->requested_s_scale = to.to_requested_s_scale;
+ tp->snd_wnd = th->th_win << tp->snd_scale;
+ tiwin = tp->snd_wnd;
+ }
+ if (to.to_flags & TOF_TS) {
+ tp->t_flags |= TF_RCVD_TSTMP;
+ tp->ts_recent = to.to_tsval;
+ tp->ts_recent_age = tcp_now;
+ }
+ if (to.to_flags & TOF_MSS)
+ tcp_mss(tp, to.to_mss, ifscope);
+ if (tp->sack_enable) {
+ if (!(to.to_flags & TOF_SACK))
+ tp->sack_enable = 0;
+ else
+ tp->t_flags |= TF_SACK_PERMIT;
+ }
+ }
+
+#if TRAFFIC_MGT
+ /* Compute inter-packet arrival jitter. According to RFC 3550, inter-packet
+ * arrival jitter is defined as the difference in packet spacing at the
+ * receiver compared to the sender for a pair of packets. When two packets
+ * of maximum segment size come one after the other with consecutive
+ * sequence numbers, we consider them as packets sent together at the
+ * sender and use them as a pair to compute inter-packet arrival jitter.
+ * This metric indicates the delay induced by the network components due
+ * to queuing in edge/access routers.
+ */
+ if (tp->t_state == TCPS_ESTABLISHED &&
+ (thflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK|TH_ECE|TH_PUSH)) == TH_ACK &&
+ ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) &&
+ ((to.to_flags & TOF_TS) == 0 ||
+ TSTMP_GEQ(to.to_tsval, tp->ts_recent)) &&
+ th->th_seq == tp->rcv_nxt &&
+ LIST_EMPTY(&tp->t_segq)) {
+ if (tp->iaj_pktcnt <= IAJ_IGNORE_PKTCNT) {
+ tp->iaj_pktcnt++;
+ }
+
+ if ( tp->iaj_size == 0 || tlen > tp->iaj_size ||
+ (tlen == tp->iaj_size && tp->iaj_rcv_ts == 0)) {
+ /* State related to inter-arrival jitter is uninitialized
+ * or we are trying to find a good first packet to start
+ * computing the metric
+ */
+ update_iaj_state(tp, tlen, 0);
+ } else {
+ if (tlen == tp->iaj_size) {
+ /* Compute inter-arrival jitter taking this packet
+ * as the second packet
+ */
+ compute_iaj(tp);
+ }
+ if (tlen < tp->iaj_size) {
+ /* There is a smaller packet in the stream.
+ * Some times the maximum size supported on a path can
+ * change if there is a new link with smaller MTU.
+ * The receiver will not know about this change.
+ * If there are too many packets smaller than iaj_size,
+ * we try to learn the iaj_size again.
+ */
+ tp->iaj_small_pkt++;
+ if (tp->iaj_small_pkt > RESET_IAJ_SIZE_THRESH) {
+ update_iaj_state(tp, tlen, 1);
+ } else {
+ clear_iaj_state(tp);
+ }
+ } else {
+ update_iaj_state(tp, tlen, 0);
+ }
+ }
+ } else {
+ clear_iaj_state(tp);
+ }
+#endif /* TRAFFIC_MGT */
+
+ /*
+ * Header prediction: check for the two common cases
+ * of a uni-directional data xfer. If the packet has
+ * no control flags, is in-sequence, the window didn't
+ * change and we're not retransmitting, it's a
+ * candidate. If the length is zero and the ack moved
+ * forward, we're the sender side of the xfer. Just
+ * free the data acked & wake any higher level process
+ * that was blocked waiting for space. If the length
+ * is non-zero and the ack didn't move, we're the
+ * receiver side. If we're getting packets in-order
+ * (the reassembly queue is empty), add the data to