@@ -2310,6 +2310,7 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
int *cmsg_flags)
{
struct tcp_sock *tp = tcp_sk(sk);
+ size_t peek_offset;
int copied = 0;
u32 peek_seq;
u32 *seq;
@@ -2353,6 +2354,20 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
if (flags & MSG_PEEK) {
peek_seq = tp->copied_seq;
seq = &peek_seq;
+ if (!msg->msg_iter.__iov[0].iov_base) {
+ peek_offset = msg->msg_iter.__iov[0].iov_len;
+ msg->msg_iter.__iov = &msg->msg_iter.__iov[1];
+ if (msg->msg_iter.nr_segs <= 1)
+ goto out;
+ msg->msg_iter.nr_segs -= 1;
+ if (msg->msg_iter.count <= peek_offset)
+ goto out;
+ msg->msg_iter.count -= peek_offset;
+ if (len <= peek_offset)
+ goto out;
+ len -= peek_offset;
+ *seq += peek_offset;
+ }
}
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);