void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len){ /* * Standard slow path. */ if (!tcp_validate_incoming(sk, skb, th, 1)) return;step5: if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) goto discard; tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ tcp_urg(sk, skb, th); /* step 7: process the segment text */ tcp_data_queue(sk, skb); tcp_data_snd_check(sk); tcp_ack_snd_check(sk); return;}/* This routine deals with incoming acks, but not outgoing ones. */static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag){ /* See if we can take anything off of the retransmit queue. */ acked = tp->packets_out; flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, sack_rtt); acked -= tp->packets_out;}/* Remove acknowledged frames from the retransmission queue. If our packet * is before the ack sequence we can discard it as it's confirmed to have * arrived at the other end. */static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,        u32 prior_snd_una, s32 sack_rtt){ while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) {    struct tcp_skb_cb *scb = TCP_SKB_CB(skb);     if (after(scb->end_seq, tp->snd_una)) {          fully_acked = false;     }     if (!fully_acked)          break;     tcp_unlink_write_queue(skb, sk);     sk_wmem_free_skb(sk, skb);     if (skb == tp->retransmit_skb_hint)          tp->retransmit_skb_hint = NULL;     if (skb == tp->lost_skb_hint)          tp->lost_skb_hint = NULL; }}---------------------------------------------------------------------------------------int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t size){ while (seglen > 0) {     skb = tcp_write_queue_tail(sk);     if (copynew_segment:     /* Allocate new segment. If the interface is SG,     * allocate skb fitting to single page.     */         if (!sk_stream_memory_free(sk))             goto wait_for_sndbuf;          skb = sk_stream_alloc_skb(sk,                   select_size(sk, sg),                   sk->sk_allocation);         if (!skb)          goto wait_for_memory;         skb_entail(sk, skb); }}---------------------------------------------------------------------------------------debug kernel 3.13.1丢出的信息:[   56.403621] sendto() len = 560[   56.403628] tcp_sendmsg() 1210 skb->len = 560  tmp = 0![   56.403635] ip_finish_output2() skb->len = 612[   56.403724] sendto() len = 4095[   56.403748] tcp_sendmsg() 1210 skb->len = 4095  tmp = 560![   56.403756] ip_finish_output2() skb->len = 2948[   56.403862] sendto() len = 4095[   56.403880] tcp_sendmsg() 1210 skb->len = 5294 tmp = 2896!丢信息的代码如下:1.tcp.ctcp_sendmsg(){ while (seglen > 0) {     struct sk_buff *tmp;     tmp = skb->prev;     printk("tcp_sendmsg() 1210 skb->len = %d tmp = %d!\n",skb->len,tmp->len);}2.ip_output.cstatic inline int ip_finish_output2(struct sk_buff *skb){ if (!IS_ERR(neigh)) { int res = 0; printk("ip_finish_output2() skb->len = %d\n",skb->len); res = dst_neigh_output(dst, neigh, skb); rcu_read_unlock_bh(); return res; }}
10-30 23:00