Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315515
b: refs/heads/master
c: cf60af0
h: refs/heads/master
i:
  315513: 5676688
  315511: 59c688a
v: v3
  • Loading branch information
Yuchung Cheng authored and David S. Miller committed Jul 19, 2012
1 parent 9c48a94 commit 04ce92d
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8e4178c1c7b52f7c99f5fd22ef7af6b2bff409e3
refs/heads/master: cf60af03ca4e71134206809ea892e49b92a88896
11 changes: 11 additions & 0 deletions trunk/Documentation/networking/ip-sysctl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,17 @@ tcp_syncookies - BOOLEAN
SYN flood warnings in logs not being really flooded, your server
is seriously misconfigured.

tcp_fastopen - INTEGER
Enable TCP Fast Open feature (draft-ietf-tcpm-fastopen) to send data
in the opening SYN packet. To use this feature, the client application
must not use connect(). Instead, it should use sendmsg() or sendto()
with MSG_FASTOPEN flag which performs a TCP handshake automatically.

The values (bitmap) are:
1: Enables sending data in the opening SYN on the client

Default: 0

tcp_syn_retries - INTEGER
Number of times initial SYNs for an active TCP connection attempt
will be retransmitted. Should not be higher than 255. Default value
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ struct ucred {
#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
#define MSG_EOF MSG_FIN

#define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */
#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exit for file
descriptor received through
SCM_RIGHTS */
Expand Down
6 changes: 4 additions & 2 deletions trunk/include/net/inet_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ struct sockaddr;
struct socket;

extern int inet_release(struct socket *sock);
extern int inet_stream_connect(struct socket *sock, struct sockaddr * uaddr,
extern int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags);
extern int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
extern int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags);
extern int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags);
extern int inet_accept(struct socket *sock, struct socket *newsock, int flags);
extern int inet_sendmsg(struct kiocb *iocb, struct socket *sock,
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
/* TCP initial congestion window as per draft-hkchu-tcpm-initcwnd-01 */
#define TCP_INIT_CWND 10

/* Bit Flags for sysctl_tcp_fastopen */
#define TFO_CLIENT_ENABLE 1

extern struct inet_timewait_death_row tcp_death_row;

/* sysctl variables for tcp */
Expand Down
19 changes: 14 additions & 5 deletions trunk/net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,8 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias)
* Connect to a remote host. There is regrettably still a little
* TCP 'magic' in here.
*/
int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
struct sock *sk = sock->sk;
int err;
Expand All @@ -595,8 +595,6 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
if (addr_len < sizeof(uaddr->sa_family))
return -EINVAL;

lock_sock(sk);

if (uaddr->sa_family == AF_UNSPEC) {
err = sk->sk_prot->disconnect(sk, flags);
sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
Expand Down Expand Up @@ -663,7 +661,6 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
sock->state = SS_CONNECTED;
err = 0;
out:
release_sock(sk);
return err;

sock_error:
Expand All @@ -673,6 +670,18 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
sock->state = SS_DISCONNECTING;
goto out;
}
EXPORT_SYMBOL(__inet_stream_connect);

int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
int err;

lock_sock(sock->sk);
err = __inet_stream_connect(sock, uaddr, addr_len, flags);
release_sock(sock->sk);
return err;
}
EXPORT_SYMBOL(inet_stream_connect);

/*
Expand Down
61 changes: 56 additions & 5 deletions trunk/net/ipv4/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@
#include <linux/slab.h>

#include <net/icmp.h>
#include <net/inet_common.h>
#include <net/tcp.h>
#include <net/xfrm.h>
#include <net/ip.h>
Expand Down Expand Up @@ -982,26 +983,67 @@ static inline int select_size(const struct sock *sk, bool sg)
return tmp;
}

void tcp_free_fastopen_req(struct tcp_sock *tp)
{
if (tp->fastopen_req != NULL) {
kfree(tp->fastopen_req);
tp->fastopen_req = NULL;
}
}

static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *size)
{
struct tcp_sock *tp = tcp_sk(sk);
int err, flags;

if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE))
return -EOPNOTSUPP;
if (tp->fastopen_req != NULL)
return -EALREADY; /* Another Fast Open is in progress */

tp->fastopen_req = kzalloc(sizeof(struct tcp_fastopen_request),
sk->sk_allocation);
if (unlikely(tp->fastopen_req == NULL))
return -ENOBUFS;
tp->fastopen_req->data = msg;

flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
err = __inet_stream_connect(sk->sk_socket, msg->msg_name,
msg->msg_namelen, flags);
*size = tp->fastopen_req->copied;
tcp_free_fastopen_req(tp);
return err;
}

int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t size)
{
struct iovec *iov;
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
int iovlen, flags, err, copied;
int mss_now = 0, size_goal;
int iovlen, flags, err, copied = 0;
int mss_now = 0, size_goal, copied_syn = 0, offset = 0;
bool sg;
long timeo;

lock_sock(sk);

flags = msg->msg_flags;
if (flags & MSG_FASTOPEN) {
err = tcp_sendmsg_fastopen(sk, msg, &copied_syn);
if (err == -EINPROGRESS && copied_syn > 0)
goto out;
else if (err)
goto out_err;
offset = copied_syn;
}

timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);

/* 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;
goto do_error;

if (unlikely(tp->repair)) {
if (tp->repair_queue == TCP_RECV_QUEUE) {
Expand Down Expand Up @@ -1037,6 +1079,15 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
unsigned char __user *from = iov->iov_base;

iov++;
if (unlikely(offset > 0)) { /* Skip bytes copied in SYN */
if (offset >= seglen) {
offset -= seglen;
continue;
}
seglen -= offset;
from += offset;
offset = 0;
}

while (seglen > 0) {
int copy = 0;
Expand Down Expand Up @@ -1199,7 +1250,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (copied && likely(!tp->repair))
tcp_push(sk, flags, mss_now, tp->nonagle);
release_sock(sk);
return copied;
return copied + copied_syn;

do_fault:
if (!skb->len) {
Expand All @@ -1212,7 +1263,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
}

do_error:
if (copied)
if (copied + copied_syn)
goto out;
out_err:
err = sk_stream_error(sk, flags, err);
Expand Down
3 changes: 3 additions & 0 deletions trunk/net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,9 @@ void tcp_v4_destroy_sock(struct sock *sk)
tp->cookie_values = NULL;
}

/* If socket is aborted during connect operation */
tcp_free_fastopen_req(tp);

sk_sockets_allocated_dec(sk);
sock_release_memcg(sk);
}
Expand Down

0 comments on commit 04ce92d

Please sign in to comment.