cregit-Linux how code gets into the kernel

Release 4.8 net/ipv4/af_inet.c

Directory: net/ipv4
/*
 * INET         An implementation of the TCP/IP protocol suite for the LINUX
 *              operating system.  INET is implemented using the  BSD Socket
 *              interface as the means of communication with the user level.
 *
 *              PF_INET protocol family socket handler.
 *
 * Authors:     Ross Biro
 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *              Florian La Roche, <flla@stud.uni-sb.de>
 *              Alan Cox, <A.Cox@swansea.ac.uk>
 *
 * Changes (see also sock.c)
 *
 *              piggy,
 *              Karl Knutson    :       Socket protocol table
 *              A.N.Kuznetsov   :       Socket death error in accept().
 *              John Richardson :       Fix non blocking error in connect()
 *                                      so sockets that fail to connect
 *                                      don't return -EINPROGRESS.
 *              Alan Cox        :       Asynchronous I/O support
 *              Alan Cox        :       Keep correct socket pointer on sock
 *                                      structures
 *                                      when accept() ed
 *              Alan Cox        :       Semantics of SO_LINGER aren't state
 *                                      moved to close when you look carefully.
 *                                      With this fixed and the accept bug fixed
 *                                      some RPC stuff seems happier.
 *              Niibe Yutaka    :       4.4BSD style write async I/O
 *              Alan Cox,
 *              Tony Gale       :       Fixed reuse semantics.
 *              Alan Cox        :       bind() shouldn't abort existing but dead
 *                                      sockets. Stops FTP netin:.. I hope.
 *              Alan Cox        :       bind() works correctly for RAW sockets.
 *                                      Note that FreeBSD at least was broken
 *                                      in this respect so be careful with
 *                                      compatibility tests...
 *              Alan Cox        :       routing cache support
 *              Alan Cox        :       memzero the socket structure for
 *                                      compactness.
 *              Matt Day        :       nonblock connect error handler
 *              Alan Cox        :       Allow large numbers of pending sockets
 *                                      (eg for big web sites), but only if
 *                                      specifically application requested.
 *              Alan Cox        :       New buffering throughout IP. Used
 *                                      dumbly.
 *              Alan Cox        :       New buffering now used smartly.
 *              Alan Cox        :       BSD rather than common sense
 *                                      interpretation of listen.
 *              Germano Caronni :       Assorted small races.
 *              Alan Cox        :       sendmsg/recvmsg basic support.
 *              Alan Cox        :       Only sendmsg/recvmsg now supported.
 *              Alan Cox        :       Locked down bind (see security list).
 *              Alan Cox        :       Loosened bind a little.
 *              Mike McLagan    :       ADD/DEL DLCI Ioctls
 *      Willy Konynenberg       :       Transparent proxying support.
 *              David S. Miller :       New socket lookup architecture.
 *                                      Some other random speedups.
 *              Cyrus Durgin    :       Cleaned up file for kmod hacks.
 *              Andi Kleen      :       Fix inet_stream_connect TCP race.
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 */


#define pr_fmt(fmt) "IPv4: " fmt

#include <linux/err.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/capability.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/netfilter_ipv4.h>
#include <linux/random.h>
#include <linux/slab.h>

#include <asm/uaccess.h>

#include <linux/inet.h>
#include <linux/igmp.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <net/checksum.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/arp.h>
#include <net/route.h>
#include <net/ip_fib.h>
#include <net/inet_connection_sock.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/udplite.h>
#include <net/ping.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/raw.h>
#include <net/icmp.h>
#include <net/inet_common.h>
#include <net/ip_tunnels.h>
#include <net/xfrm.h>
#include <net/net_namespace.h>
#include <net/secure_seq.h>
#ifdef CONFIG_IP_MROUTE
#include <linux/mroute.h>
#endif
#include <net/l3mdev.h>


/* The inetsw table contains everything that inet_create needs to
 * build a new socket.
 */

static struct list_head inetsw[SOCK_MAX];
static DEFINE_SPINLOCK(inetsw_lock);

/* New destruction routine */


void inet_sock_destruct(struct sock *sk) { struct inet_sock *inet = inet_sk(sk); __skb_queue_purge(&sk->sk_receive_queue); __skb_queue_purge(&sk->sk_error_queue); sk_mem_reclaim(sk); if (sk->sk_type == SOCK_STREAM && sk->sk_state != TCP_CLOSE) { pr_err("Attempt to release TCP socket in state %d %p\n", sk->sk_state, sk); return; } if (!sock_flag(sk, SOCK_DEAD)) { pr_err("Attempt to release alive inet socket %p\n", sk); return; } WARN_ON(atomic_read(&sk->sk_rmem_alloc)); WARN_ON(atomic_read(&sk->sk_wmem_alloc)); WARN_ON(sk->sk_wmem_queued); WARN_ON(sk->sk_forward_alloc); kfree(rcu_dereference_protected(inet->inet_opt, 1)); dst_release(rcu_dereference_check(sk->sk_dst_cache, 1)); dst_release(sk->sk_rx_dst); sk_refcnt_debug_dec(sk); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git10565.22%840.00%
david s. millerdavid s. miller1710.56%210.00%
arnaldo carvalho de meloarnaldo carvalho de melo159.32%420.00%
eric dumazeteric dumazet138.07%315.00%
hideo aokihideo aoki53.11%15.00%
ilpo jarvinenilpo jarvinen42.48%15.00%
james morrisjames morris21.24%15.00%
Total161100.00%20100.00%

EXPORT_SYMBOL(inet_sock_destruct); /* * The routines beyond this point handle the behaviour of an AF_INET * socket object. Mostly it punts to the subprotocols of IP to do * the work. */ /* * Automatically bind an unbound socket. */
static int inet_autobind(struct sock *sk) { struct inet_sock *inet; /* We may need to bind the socket. */ lock_sock(sk); inet = inet_sk(sk); if (!inet->inet_num) { if (sk->sk_prot->get_port(sk, 0)) { release_sock(sk); return -EAGAIN; } inet->inet_sport = htons(inet->inet_num); } release_sock(sk); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git6175.31%861.54%
arnaldo carvalho de meloarnaldo carvalho de melo911.11%323.08%
david s. millerdavid s. miller89.88%17.69%
eric dumazeteric dumazet33.70%17.69%
Total81100.00%13100.00%

/* * Move a socket into listening state. */
int inet_listen(struct socket *sock, int backlog) { struct sock *sk = sock->sk; unsigned char old_state; int err; lock_sock(sk); err = -EINVAL; if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM) goto out; old_state = sk->sk_state; if (!((1 << old_state) & (TCPF_CLOSE | TCPF_LISTEN))) goto out; /* Really, if the socket is already in listen state * we can only allow the backlog to be adjusted. */ if (old_state != TCP_LISTEN) { /* Check special setups for testing purpose to enable TFO w/o * requiring TCP_FASTOPEN sockopt. * Note that only TCP sockets (SOCK_STREAM) will reach here. * Also fastopenq may already been allocated because this * socket was in TCP_LISTEN state previously but was * shutdown() (rather than close()). */ if ((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) != 0 && !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) { if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) != 0) fastopen_queue_tune(sk, backlog); else if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT2) != 0) fastopen_queue_tune(sk, ((uint)sysctl_tcp_fastopen) >> 16); tcp_fastopen_init_key_once(true); } err = inet_csk_listen_start(sk, backlog); if (err) goto out; } sk->sk_max_ack_backlog = backlog; err = 0; out: release_sock(sk); return err; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git12261.31%646.15%
jerry chujerry chu6231.16%17.69%
eric dumazeteric dumazet52.51%215.38%
christoph paaschchristoph paasch52.51%17.69%
arnaldo carvalho de meloarnaldo carvalho de melo42.01%215.38%
ian morrisian morris10.50%17.69%
Total199100.00%13100.00%

EXPORT_SYMBOL(inet_listen); /* * Create an inet socket. */
static int inet_create(struct net *net, struct socket *sock, int protocol, int kern) { struct sock *sk; struct inet_protosw *answer; struct inet_sock *inet; struct proto *answer_prot; unsigned char answer_flags; int try_loading_module = 0; int err; if (protocol < 0 || protocol >= IPPROTO_MAX) return -EINVAL; sock->state = SS_UNCONNECTED; /* Look for the requested type/protocol pair. */ lookup_protocol: err = -ESOCKTNOSUPPORT; rcu_read_lock(); list_for_each_entry_rcu(answer, &inetsw[sock->type], list) { err = 0; /* Check the non-wild match. */ if (protocol == answer->protocol) { if (protocol != IPPROTO_IP) break; } else { /* Check for the two wild cases. */ if (IPPROTO_IP == protocol) { protocol = answer->protocol; break; } if (IPPROTO_IP == answer->protocol) break; } err = -EPROTONOSUPPORT; } if (unlikely(err)) { if (try_loading_module < 2) { rcu_read_unlock(); /* * Be more specific, e.g. net-pf-2-proto-132-type-1 * (net-pf-PF_INET-proto-IPPROTO_SCTP-type-SOCK_STREAM) */ if (++try_loading_module == 1) request_module("net-pf-%d-proto-%d-type-%d", PF_INET, protocol, sock->type); /* * Fall back to generic, e.g. net-pf-2-proto-132 * (net-pf-PF_INET-proto-IPPROTO_SCTP) */ else request_module("net-pf-%d-proto-%d", PF_INET, protocol); goto lookup_protocol; } else goto out_rcu_unlock; } err = -EPERM; if (sock->type == SOCK_RAW && !kern && !ns_capable(net->user_ns, CAP_NET_RAW)) goto out_rcu_unlock; sock->ops = answer->ops; answer_prot = answer->prot; answer_flags = answer->flags; rcu_read_unlock(); WARN_ON(!answer_prot->slab); err = -ENOBUFS; sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, kern); if (!sk) goto out; err = 0; if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse = SK_CAN_REUSE; inet = inet_sk(sk); inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; inet->nodefrag = 0; if (SOCK_RAW == sock->type) { inet->inet_num = protocol; if (IPPROTO_RAW == protocol) inet->hdrincl = 1; } if (net->ipv4.sysctl_ip_no_pmtu_disc) inet->pmtudisc = IP_PMTUDISC_DONT; else inet->pmtudisc = IP_PMTUDISC_WANT; inet->inet_id = 0; sock_init_data(sock, sk); sk->sk_destruct = inet_sock_destruct; sk->sk_protocol = protocol; sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv; inet->uc_ttl = -1; inet->mc_loop = 1; inet->mc_ttl = 1; inet->mc_all = 1; inet->mc_index = 0; inet->mc_list = NULL; inet->rcv_tos = 0; sk_refcnt_debug_inc(sk); if (inet->inet_num) { /* It assumes that any protocol which allows * the user to assign a number at socket * creation time automatically * shares. */ inet->inet_sport = htons(inet->inet_num); /* Add to protocol hash chains. */ err = sk->sk_prot->hash(sk); if (err) { sk_common_release(sk); goto out; } } if (sk->sk_prot->init) { err = sk->sk_prot->init(sk); if (err) sk_common_release(sk); } out: return err; out_rcu_unlock: rcu_read_unlock(); goto out; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git19033.99%1428.57%
arnaldo carvalho de meloarnaldo carvalho de melo14926.65%816.33%
linus torvaldslinus torvalds7914.13%24.08%
david s. millerdavid s. miller274.83%36.12%
hannes frederic sowahannes frederic sowa183.22%24.08%
craig gallekcraig gallek162.86%12.04%
eric w. biedermaneric w. biederman142.50%36.12%
eric pariseric paris111.97%36.12%
herbert xuherbert xu101.79%12.04%
paul e. mckenneypaul e. mckenney71.25%12.04%
jiri olsajiri olsa61.07%12.04%
nivedita singhvinivedita singhvi61.07%12.04%
jiri bencjiri benc61.07%12.04%
stephen hemmingerstephen hemminger50.89%12.04%
eric dumazeteric dumazet50.89%12.04%
paul moorepaul moore40.72%24.08%
ian morrisian morris20.36%12.04%
denis v. lunevdenis v. lunev20.36%12.04%
pavel emelianovpavel emelianov10.18%12.04%
ilpo jarvinenilpo jarvinen10.18%12.04%
Total559100.00%49100.00%

/* * The peer socket should always be NULL (or else). When we call this * function we are destroying the object and from then on nobody * should refer to it. */
int inet_release(struct socket *sock) { struct sock *sk = sock->sk; if (sk) { long timeout; /* Applications forget to leave groups before exiting */ ip_mc_drop_socket(sk); /* If linger is set, we don't return until the close * is complete. Otherwise we return immediately. The * actually closing is done the same either way. * * If the close is due to the process exiting, we never * linger.. */ timeout = 0; if (sock_flag(sk, SOCK_LINGER) && !(current->flags & PF_EXITING)) timeout = sk->sk_lingertime; sock->sk = NULL; sk->sk_prot->close(sk, timeout); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git7691.57%770.00%
arnaldo carvalho de meloarnaldo carvalho de melo56.02%220.00%
james morrisjames morris22.41%110.00%
Total83100.00%10100.00%

EXPORT_SYMBOL(inet_release);
int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct net *net = sock_net(sk); unsigned short snum; int chk_addr_ret; u32 tb_id = RT_TABLE_LOCAL; int err; /* If the socket has its own bind function then use it. (RAW) */ if (sk->sk_prot->bind) { err = sk->sk_prot->bind(sk, uaddr, addr_len); goto out; } err = -EINVAL; if (addr_len < sizeof(struct sockaddr_in)) goto out; if (addr->sin_family != AF_INET) { /* Compatibility games : accept AF_UNSPEC (mapped to AF_INET) * only if s_addr is INADDR_ANY. */ err = -EAFNOSUPPORT; if (addr->sin_family != AF_UNSPEC || addr->sin_addr.s_addr != htonl(INADDR_ANY)) goto out; } tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id; chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id); /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since * allowing applications to make a non-local bind solves * several problems with systems using dynamic addressing. * (ie. your servers still start up even if your ISDN link * is temporarily down) */ err = -EADDRNOTAVAIL; if (!net->ipv4.sysctl_ip_nonlocal_bind && !(inet->freebind || inet->transparent) && addr->sin_addr.s_addr != htonl(INADDR_ANY) && chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) goto out; snum = ntohs(addr->sin_port); err = -EACCES; if (snum && snum < PROT_SOCK && !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) goto out; /* We keep a pair of addresses. rcv_saddr is the one * used by hash lookups, and saddr is used for transmit. * * In the BSD API these are the same except where it * would be illegal to use them (multicast/broadcast) in * which case the sending device address is used. */ lock_sock(sk); /* Check these errors (active socket, double bind). */ err = -EINVAL; if (sk->sk_state != TCP_CLOSE || inet->inet_num) goto out_release_sock; inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->inet_saddr = 0; /* Use device */ /* Make sure we are allowed to bind here. */ if ((snum || !inet->bind_address_no_port) && sk->sk_prot->get_port(sk, snum)) { inet->inet_saddr = inet->inet_rcv_saddr = 0; err = -EADDRINUSE; goto out_release_sock; } if (inet->inet_rcv_saddr) sk->sk_userlocks |= SOCK_BINDADDR_LOCK; if (snum) sk->sk_userlocks |= SOCK_BINDPORT_LOCK; inet->inet_sport = htons(inet->inet_num); inet->inet_daddr = 0; inet->inet_dport = 0; sk_dst_reset(sk); err = 0; out_release_sock: release_sock(sk); out: return err; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git26459.73%1747.22%
arnaldo carvalho de meloarnaldo carvalho de melo4610.41%38.33%
eric dumazeteric dumazet409.05%38.33%
david aherndavid ahern235.20%411.11%
david s. millerdavid s. miller214.75%25.56%
marcus meissnermarcus meissner184.07%25.56%
eric w. biedermaneric w. biederman173.85%25.56%
laszlo attila tothlaszlo attila toth61.36%12.78%
vincent bernatvincent bernat40.90%12.78%
al viroal viro30.68%12.78%
Total442100.00%36100.00%

EXPORT_SYMBOL(inet_bind);
int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { struct sock *sk = sock->sk; if (addr_len < sizeof(uaddr->sa_family)) return -EINVAL; if (uaddr->sa_family == AF_UNSPEC) return sk->sk_prot->disconnect(sk, flags); if (!inet_sk(sk)->inet_num && inet_autobind(sk)) return -EAGAIN; return sk->sk_prot->connect(sk, uaddr, addr_len); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git7677.55%555.56%
changli gaochangli gao1515.31%111.11%
david s. millerdavid s. miller44.08%111.11%
arnaldo carvalho de meloarnaldo carvalho de melo22.04%111.11%
eric dumazeteric dumazet11.02%111.11%
Total98100.00%9100.00%

EXPORT_SYMBOL(inet_dgram_connect);
static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) { DEFINE_WAIT(wait); prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); sk->sk_write_pending += writebias; /* Basic assumption: if someone sets sk->sk_err, he _must_ * change state of the socket from TCP_SYN_*. * Connect() does not allow to get error notifications * without closing the socket. */ while ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); if (signal_pending(current) || !timeo) break; prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); } finish_wait(sk_sleep(sk), &wait); sk->sk_write_pending -= writebias; return timeo; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git8267.77%555.56%
yuchung chengyuchung cheng1512.40%111.11%
andrew mortonandrew morton108.26%111.11%
eric dumazeteric dumazet97.44%111.11%
arnaldo carvalho de meloarnaldo carvalho de melo54.13%111.11%
Total121100.00%9100.00%

/* * 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) { struct sock *sk = sock->sk; int err; long timeo; if (addr_len < sizeof(uaddr->sa_family)) return -EINVAL; if (uaddr->sa_family == AF_UNSPEC) { err = sk->sk_prot->disconnect(sk, flags); sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; goto out; } switch (sock->state) { default: err = -EINVAL; goto out; case SS_CONNECTED: err = -EISCONN; goto out; case SS_CONNECTING: err = -EALREADY; /* Fall out of switch with err, set for this state */ break; case SS_UNCONNECTED: err = -EISCONN; if (sk->sk_state != TCP_CLOSE) goto out; err = sk->sk_prot->connect(sk, uaddr, addr_len); if (err < 0) goto out; sock->state = SS_CONNECTING; /* Just entered SS_CONNECTING state; the only * difference is that return value in non-blocking * case is EINPROGRESS, rather than EALREADY. */ err = -EINPROGRESS; break; } timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { int writebias = (sk->sk_protocol == IPPROTO_TCP) && tcp_sk(sk)->fastopen_req && tcp_sk(sk)->fastopen_req->data ? 1 : 0; /* Error code is set above */ if (!timeo || !inet_wait_for_connect(sk, timeo, writebias)) goto out; err = sock_intr_errno(timeo); if (signal_pending(current)) goto out; } /* Connection was closed by RST, timeout, ICMP error * or another process disconnected us. */ if (sk->sk_state == TCP_CLOSE) goto sock_error; /* sk->sk_err may be not zero now, if RECVERR was ordered by user * and error was received after socket entered established state. * Hence, it is handled normally after connect() return successfully. */ sock->state = SS_CONNECTED; err = 0; out: return err; sock_error: err = sock_error(sk) ? : -ECONNABORTED; sock->state = SS_UNCONNECTED; if (sk->sk_prot->disconnect(sk, flags)) sock->state = SS_DISCONNECTING; goto out; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git29083.82%1275.00%
yuchung chengyuchung cheng349.83%212.50%
changli gaochangli gao154.34%16.25%
arnaldo carvalho de meloarnaldo carvalho de melo72.02%16.25%
Total346100.00%16100.00%

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; }

Contributors

PersonTokensPropCommitsCommitProp
yuchung chengyuchung cheng54100.00%1100.00%
Total54100.00%1100.00%

EXPORT_SYMBOL(inet_stream_connect); /* * Accept a pending connection. The TCP layer now gives BSD semantics. */
int inet_accept(struct socket *sock, struct socket *newsock, int flags) { struct sock *sk1 = sock->sk; int err = -EINVAL; struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err); if (!sk2) goto do_err; lock_sock(sk2); sock_rps_record_flow(sk2); WARN_ON(!((1 << sk2->sk_state) & (TCPF_ESTABLISHED | TCPF_SYN_RECV | TCPF_CLOSE_WAIT | TCPF_CLOSE))); sock_graft(sk2, newsock); newsock->state = SS_CONNECTED; err = 0; release_sock(sk2); do_err: return err; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git9578.51%861.54%
arnaldo carvalho de meloarnaldo carvalho de melo1512.40%215.38%
eric dumazeteric dumazet54.13%17.69%
ilpo jarvinenilpo jarvinen43.31%17.69%
jerry chujerry chu21.65%17.69%
Total121100.00%13100.00%

EXPORT_SYMBOL(inet_accept); /* * This does both peername and sockname. */
int inet_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); DECLARE_SOCKADDR(struct sockaddr_in *, sin, uaddr); sin->sin_family = AF_INET; if (peer) { if (!inet->inet_dport || (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) && peer == 1)) return -ENOTCONN; sin->sin_port = inet->inet_dport; sin->sin_addr.s_addr = inet->inet_daddr; } else { __be32 addr = inet->inet_rcv_saddr; if (!addr) addr = inet->inet_saddr; sin->sin_port = inet->inet_sport; sin->sin_addr.s_addr = addr; } memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); *uaddr_len = sizeof(*sin); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git13172.78%642.86%
alexey kuznetsovalexey kuznetsov168.89%17.14%
david s. millerdavid s. miller147.78%17.14%
cyrill gorcunovcyrill gorcunov73.89%17.14%
eric dumazeteric dumazet63.33%17.14%
arnaldo carvalho de meloarnaldo carvalho de melo52.78%321.43%
al viroal viro10.56%17.14%
Total180100.00%14100.00%

EXPORT_SYMBOL(inet_getname);
int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) { struct sock *sk = sock->sk; sock_rps_record_flow(sk); /* We may need to bind the socket. */ if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind && inet_autobind(sk)) return -EAGAIN; return sk->sk_prot->sendmsg(sk, msg, size); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git5473.97%330.00%
changli gaochangli gao79.59%110.00%
david s. millerdavid s. miller56.85%220.00%
tom herberttom herbert45.48%110.00%
stephen hemmingerstephen hemminger11.37%110.00%
arnaldo carvalho de meloarnaldo carvalho de melo11.37%110.00%
eric dumazeteric dumazet11.37%110.00%
Total73100.00%10100.00%

EXPORT_SYMBOL(inet_sendmsg);
ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) { struct sock *sk = sock->sk; sock_rps_record_flow(sk); /* We may need to bind the socket. */ if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind && inet_autobind(sk)) return -EAGAIN; if (sk->sk_prot->sendpage) return sk->sk_prot->sendpage(sk, page, offset, size, flags); return sock_no_sendpage(sock, page, offset, size, flags); }

Contributors

PersonTokensPropCommitsCommitProp
alexey kuznetsovalexey kuznetsov9085.71%116.67%
changli gaochangli gao76.67%116.67%
tom herberttom herbert43.81%116.67%
arnaldo carvalho de meloarnaldo carvalho de melo21.90%116.67%
david s. millerdavid s. miller10.95%116.67%
eric dumazeteric dumazet10.95%116.67%
Total105100.00%6100.00%

EXPORT_SYMBOL(inet_sendpage);
int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags) { struct sock *sk = sock->sk; int addr_len = 0; int err; sock_rps_record_flow(sk); err = sk->sk_prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT, flags & ~MSG_DONTWAIT, &addr_len); if (err >= 0) msg->msg_namelen = addr_len; return err; }

Contributors

PersonTokensPropCommitsCommitProp
tom herberttom herbert8498.82%150.00%
david s. millerdavid s. miller11.18%150.00%
Total85100.00%2100.00%

EXPORT_SYMBOL(inet_recvmsg);
int inet_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; int err = 0; /* This should really check to make sure * the socket is a TCP socket. (WHY AC...) */ how++; /* maps 0->1 has the advantage of making bit 1 rcvs and 1->2 bit 2 snds. 2->3 */ if ((how & ~SHUTDOWN_MASK) || !how) /* MAXINT->0 */ return -EINVAL; lock_sock(sk); if (sock->state == SS_CONNECTING) { if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE)) sock->state = SS_DISCONNECTING; else sock->state = SS_CONNECTED; } switch (sk->sk_state) {