Send error code in tcp

Source: Internet
Author: User

Send error code in tcp
Int tcp_sendmsg (struct kiocb * iocb, struct socket * sock, struct msghdr * msg, size_t size)
{
Struct sock * sk = sock-> sk;
Struct iovec * iov;
Struct tcp_sock * tp = tcp_sk (sk );
Struct sk_buff * skb;
Int iovlen, flags;
Int mss_now, size_goal;
Int err, copied;
Long timeo;


Lock_sock (sk );
TCP_CHECK_TIMER (sk );


Flags = msg-> msg_flags;
Timeo = sock_sndtimeo (sk, flags & MSG_DONTWAIT); // the value of non-blocking is 0.


/* Wait for a connection to finish .*/
If (1 <sk-> sk_state )&~ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT ))
If (err = sk_stream_wait_connect (sk, & timeo ))! = 0)
Goto out_err;


/* This shoshould be in poll */
Clear_bit (SOCK_ASYNC_NOSPACE, & sk-> sk_socket-> flags );


Mss_now = tcp_send_mss (sk, & size_goal, flags );


/* OK commence sending .*/
Iovlen = msg-> msg_iovlen;
Iov = msg-> msg_iov;
Copied = 0;


Err =-EPIPE;
If (sk-> sk_err | (sk-> sk_shutdown & SEND_SHUTDOWN ))
Goto out_err;


While (-- iovlen> = 0)
{
Int seglen = iov-> iov_len;
Unsigned char _ user * from = iov-> iov_base;


Iov ++;


While (seglen> 0)
{
Int copy = 0;
Int max = size_goal;


Skb = tcp_write_queue_tail (sk );
If (tcp_send_head (sk )){
If (skb-> ip_summed = CHECKSUM_NONE)
Max = mss_now;
Copy = max-skb-> len;
}


If (copy <= 0)
{
New_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 ),
Sk-> sk_allocation );
If (! Skb)
Goto wait_for_memory;


/*
* Check whether we can use HW checksum.
*/
If (sk-> sk_route_caps & NETIF_F_ALL_CSUM)
Skb-> ip_summed = CHECKSUM_PARTIAL;


Skb_entail (sk, skb );
Copy = size_goal;
Max = size_goal;
}


/* Try to append data to the end of skb .*/
If (copy> seglen)
Copy = seglen;


/* Where to copy? */
If (skb_tailroom (skb)> 0 ){
/* We have some space in skb head. Superb! */
If (copy> skb_tailroom (skb ))
Copy = skb_tailroom (skb );
If (err = skb_add_data (skb, from, copy ))! = 0)
Goto do_fault;
} Else {
Int merge = 0;
Int I = skb_shinfo (skb)-> nr_frags;
Struct page * page = TCP_PAGE (sk );
Int off = TCP_OFF (sk );


If (skb_can_coalesce (skb, I, page, off )&&
Off! = PAGE_SIZE ){
/* We can extend the last page
* Fragment .*/
Merge = 1;
} Else if (I = MAX_SKB_FRAGS |
(! I &&
! (Sk-> sk_route_caps & NETIF_F_SG ))){
/* Need to add new fragment and cannot
* Do this because interface is non-SG,
* Or because all the page slots are
* Busy .*/
Tcp_mark_push (tp, skb );
Goto new_segment;
} Else if (page ){
If (off = PAGE_SIZE ){
Put_page (page );
TCP_PAGE (sk) = page = NULL;
Off = 0;
}
} Else
Off = 0;


If (copy> PAGE_SIZE-off)
Copy = PAGE_SIZE-off;


If (! Sk_wmem_schedule (sk, copy ))
Goto wait_for_memory;


If (! Page ){
/* Allocate new cache page .*/
If (! (Page = sk_stream_alloc_page (sk )))
Goto wait_for_memory;
}


/* Time to copy data. We are close
* The end! */
Err = skb_copy_to_page (sk, from, skb, page,
Off, copy );
If (err ){
/* If this page was new, give it to
* Socket so it does not get leaked.
*/
If (! TCP_PAGE (sk )){
TCP_PAGE (sk) = page;
TCP_OFF (sk) = 0;
}
Goto do_error;
}


/* Update the skb .*/
If (merge ){
Skb_shinfo (skb)-> frags [I-1]. size + =
Copy;
} Else {
Skb_fill_page_desc (skb, I, page, off, copy );
If (TCP_PAGE (sk )){
Get_page (page );
} Else if (off + copy <PAGE_SIZE ){
Get_page (page );
TCP_PAGE (sk) = page;
}
}


TCP_OFF (sk) = off + copy;
}


If (! Copied)
TCP_SKB_CB (skb)-> flags & = ~ TCPCB_FLAG_PSH;


Tp-> write_seq + = copy;
TCP_SKB_CB (skb)-> end_seq + = copy;
Skb_shinfo (skb)-> gso_segs = 0;


From + = copy;
Copied + = copy;
If (seglen-= copy) = 0 & iovlen = 0)
Goto out;


If (skb-> len <max | (flags & MSG_OOB ))
Continue;


If (forced_push (tp )){
Tcp_mark_push (tp, skb );
_ Tcp_push_pending_frames (sk, mss_now, TCP_NAGLE_PUSH );
} Else if (skb = tcp_send_head (sk ))
Tcp_push_one (sk, mss_now );
Continue;


Wait_for_sndbuf:
Set_bit (SOCK_NOSPACE, & sk-> sk_socket-> flags );
Wait_for_memory:
If (copied)
Tcp_push (sk, flags &~ MSG_MORE, mss_now, TCP_NAGLE_PUSH );


If (err = sk_stream_wait_memory (sk, & timeo ))! = 0)
Goto do_error;


Mss_now = tcp_send_mss (sk, & size_goal, flags );
}
}


Out:
If (copied)
Tcp_push (sk, flags, mss_now, tp-> nonagle );
TCP_CHECK_TIMER (sk );
Release_sock (sk );
Return copied;


Do_fault:
If (! Skb-> len)
{
Tcp_unlink_write_queue (skb, sk );
/* It is the one place in all of TCP, cannot connect
* Reset, where we can be unlinking the send_head.
*/
Tcp_check_send_head (sk, skb );
Sk_wmem_free_skb (sk, skb );
}


Do_error:
If (copied)
Goto out;
Out_err:
Err = sk_stream_error (sk, flags, err );
TCP_CHECK_TIMER (sk );
Release_sock (sk );
Return err;
}

Int sk_stream_wait_connect (struct sock * sk, long * timeo_p)
{
Struct task_struct * tsk = current;
DEFINE_WAIT (wait );
Int done;


Do {
Int err = sock_error (sk );
If (err)
Return err;
If (1 <sk-> sk_state )&~ (TCPF_SYN_SENT | TCPF_SYN_RECV ))
Return-EPIPE;
If (! * Timeo_p)
Return-EAGAIN;
If (signal_pending (tsk ))
Return sock_intr_errno (* timeo_p );


Prepare_to_wait (sk-> sk_sleep, & wait, TASK_INTERRUPTIBLE );
Sk-> sk_write_pending ++;
Done = sk_wait_event (sk, timeo_p,
! Sk-> sk_err &&
! (1 <sk-> sk_state )&
~ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT )));
Finish_wait (sk-> sk_sleep, & wait );
Sk-> sk_write_pending --;
} While (! Done );
Return 0;
}





1. EBADF --- corresponding file object not found
2. The connection is not established. Wait until you enter TCPF_ESTABLISHED or TCPF_CLOSE_WAIT.
1. ERESTARTSYS --- there is an event on the current socket, and the scheduling time is up
2. EINTR -- an event on the current socket is interrupted.
3. EPIPE -- the connected object is not TCPF_SYN_SENT | TCPF_SYN_RECV, Which is returned directly.
4. EAGAIN -- non-blocking, direct return


3. check whether there are errors in the current shutdown flag and connection.
1. EPIPE
4. Possible sending buffer areas are insufficient.
The number of bytes sent is 0, and you need to resend the message.

5. Insufficient memory
The number of bytes sent is 0, and you need to resend the message.

6. Return the number of bytes sent
Number of bytes sent

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.