Skip to content
Snippets Groups Projects
socket.c 105 KiB
Newer Older
Per Liden's avatar
Per Liden committed
/*
 * net/tipc/socket.c: TIPC socket API
 * Copyright (c) 2001-2007, 2012-2019, Ericsson AB
 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
 * Copyright (c) 2020-2021, Red Hat Inc
Per Liden's avatar
Per Liden committed
 * All rights reserved.
 *
Per Liden's avatar
Per Liden committed
 * Redistribution and use in source and binary forms, with or without
Per Liden's avatar
Per Liden committed
 * modification, are permitted provided that the following conditions are met:
 *
Per Liden's avatar
Per Liden committed
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
Per Liden's avatar
Per Liden committed
 *
Per Liden's avatar
Per Liden committed
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Per Liden's avatar
Per Liden committed
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/rhashtable.h>
Per Liden's avatar
Per Liden committed
#include "core.h"
#include "node.h"
#include "name_distr.h"
#include "socket.h"
#include "bcast.h"
#include "netlink.h"
#include "group.h"
#include "trace.h"
#define NAGLE_START_INIT	4
#define NAGLE_START_MAX		1024
#define CONN_TIMEOUT_DEFAULT    8000    /* default connect timeout = 8s */
#define CONN_PROBING_INTV	msecs_to_jiffies(3600000)  /* [ms] => 1 h */
#define TIPC_MAX_PORT		0xffffffff
#define TIPC_MIN_PORT		1
#define TIPC_ACK_RATE		4       /* ACK at 1/4 of rcv window size */
enum {
	TIPC_LISTEN = TCP_LISTEN,
	TIPC_ESTABLISHED = TCP_ESTABLISHED,
	TIPC_OPEN = TCP_CLOSE,
	TIPC_DISCONNECTING = TCP_CLOSE_WAIT,
	TIPC_CONNECTING = TCP_SYN_SENT,
struct sockaddr_pair {
	struct sockaddr_tipc sock;
	struct sockaddr_tipc member;
};

/**
 * struct tipc_sock - TIPC socket structure
 * @sk: socket - interacts with 'port' and with user via the socket API
 * @max_pkt: maximum packet size "hint" used when building messages sent by port
 * @maxnagle: maximum size of msg which can be subject to nagle
 * @portid: unique port identity in TIPC socket hash table
 * @phdr: preformatted message header used when sending messages
 * @cong_links: list of congested links
 * @publications: list of publications for port
 * @blocking_link: address of the congested link we are currently sleeping on
 * @pub_count: total # of publications port has made during its lifetime
 * @conn_timeout: the time we can wait for an unresponded setup request
 * @probe_unacked: probe has not received ack yet
 * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
 * @cong_link_cnt: number of congested links
 * @snt_unacked: # messages sent by socket, and not yet acked by peer
 * @snd_win: send window size
 * @peer_caps: peer capabilities mask
 * @rcv_unacked: # messages read by user, but not yet acked back to peer
 * @rcv_win: receive window size
 * @peer: 'connected' peer for dgram/rdm
 * @node: hash table node
 * @mc_method: cookie for use between socket and broadcast layer
 * @rcu: rcu struct for tipc_sock
 * @group: TIPC communications group
 * @oneway: message count in one direction (FIXME)
 * @nagle_start: current nagle value
 * @snd_backlog: send backlog count
 * @msg_acc: messages accepted; used in managing backlog and nagle
 * @pkt_cnt: TIPC socket packet count
 * @expect_ack: whether this TIPC socket is expecting an ack
 * @nodelay: setsockopt() TIPC_NODELAY setting
 * @group_is_open: TIPC socket group is fully open (FIXME)
 * @published: true if port has one or more associated names
 * @conn_addrtype: address type used when establishing connection
 */
struct tipc_sock {
	struct sock sk;
	u32 max_pkt;
	u32 maxnagle;
	struct tipc_msg phdr;
	struct list_head cong_links;
	struct list_head publications;
	u32 pub_count;
	atomic_t dupl_rcvcnt;
	u16 snt_unacked;
	u16 snd_win;
	u16 rcv_unacked;
	u16 rcv_win;
	struct rhash_head node;
	struct tipc_mc_method mc_method;
	struct tipc_group *group;
	u32 oneway;
	u16 snd_backlog;
	u16 msg_acc;
	u16 pkt_cnt;
	bool expect_ack;
	bool nodelay;
	bool group_is_open;
Per Liden's avatar
Per Liden committed

static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb);
static void tipc_data_ready(struct sock *sk);
static void tipc_write_space(struct sock *sk);
static void tipc_sock_destruct(struct sock *sk);
static int tipc_release(struct socket *sock);
static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags,
		       bool kern);
static void tipc_sk_timeout(struct timer_list *t);
static int tipc_sk_publish(struct tipc_sock *tsk, struct tipc_uaddr *ua);
static int tipc_sk_withdraw(struct tipc_sock *tsk, struct tipc_uaddr *ua);
static int tipc_sk_leave(struct tipc_sock *tsk);
static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid);
static int tipc_sk_insert(struct tipc_sock *tsk);
static void tipc_sk_remove(struct tipc_sock *tsk);
static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dsz);
static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz);
static void tipc_sk_push_backlog(struct tipc_sock *tsk, bool nagle_ack);
static int tipc_wait_for_connect(struct socket *sock, long *timeo_p);
Per Liden's avatar
Per Liden committed

static const struct proto_ops packet_ops;
static const struct proto_ops stream_ops;
static const struct proto_ops msg_ops;
Per Liden's avatar
Per Liden committed
static struct proto tipc_proto;
static const struct rhashtable_params tsk_rht_params;

static u32 tsk_own_node(struct tipc_sock *tsk)
{
	return msg_prevnode(&tsk->phdr);
}

static u32 tsk_peer_node(struct tipc_sock *tsk)
	return msg_destnode(&tsk->phdr);
static u32 tsk_peer_port(struct tipc_sock *tsk)
	return msg_destport(&tsk->phdr);
static  bool tsk_unreliable(struct tipc_sock *tsk)
	return msg_src_droppable(&tsk->phdr) != 0;
static void tsk_set_unreliable(struct tipc_sock *tsk, bool unreliable)
	msg_set_src_droppable(&tsk->phdr, unreliable ? 1 : 0);
static bool tsk_unreturnable(struct tipc_sock *tsk)
	return msg_dest_droppable(&tsk->phdr) != 0;
static void tsk_set_unreturnable(struct tipc_sock *tsk, bool unreturnable)
Loading
Loading full blame...