linux/net/dccp/output.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  net/dccp/output.c
 *
 *  An implementation of the DCCP protocol
 *  Arnaldo Carvalho de Melo <[email protected]>
 */

#include <linux/dccp.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/sched/signal.h>

#include <net/inet_sock.h>
#include <net/sock.h>

#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"

static inline void dccp_event_ack_sent(struct sock *sk)
{}

/* enqueue @skb on sk_send_head for retransmission, return clone to send now */
static struct sk_buff *dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
{}

/*
 * All SKB's seen here are completely headerless. It is our
 * job to build the DCCP header, and pass the packet down to
 * IP so it can do the same plus pass the packet off to the
 * device.
 */
static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
{}

/**
 * dccp_determine_ccmps  -  Find out about CCID-specific packet-size limits
 * @dp: socket to find packet size limits of
 *
 * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
 * since the RX CCID is restricted to feedback packets (Acks), which are small
 * in comparison with the data traffic. A value of 0 means "no current CCMPS".
 */
static u32 dccp_determine_ccmps(const struct dccp_sock *dp)
{}

unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
{}

EXPORT_SYMBOL_GPL();

void dccp_write_space(struct sock *sk)
{}

/**
 * dccp_wait_for_ccid  -  Await CCID send permission
 * @sk:    socket to wait for
 * @delay: timeout in jiffies
 *
 * This is used by CCIDs which need to delay the send time in process context.
 */
static int dccp_wait_for_ccid(struct sock *sk, unsigned long delay)
{}

/**
 * dccp_xmit_packet  -  Send data packet under control of CCID
 * @sk: socket to send data packet on
 *
 * Transmits next-queued payload and informs CCID to account for the packet.
 */
static void dccp_xmit_packet(struct sock *sk)
{}

/**
 * dccp_flush_write_queue  -  Drain queue at end of connection
 * @sk: socket to be drained
 * @time_budget: time allowed to drain the queue
 *
 * Since dccp_sendmsg queues packets without waiting for them to be sent, it may
 * happen that the TX queue is not empty at the end of a connection. We give the
 * HC-sender CCID a grace period of up to @time_budget jiffies. If this function
 * returns with a non-empty write queue, it will be purged later.
 */
void dccp_flush_write_queue(struct sock *sk, long *time_budget)
{}

void dccp_write_xmit(struct sock *sk)
{}

/**
 * dccp_retransmit_skb  -  Retransmit Request, Close, or CloseReq packets
 * @sk: socket to perform retransmit on
 *
 * There are only four retransmittable packet types in DCCP:
 * - Request  in client-REQUEST  state (sec. 8.1.1),
 * - CloseReq in server-CLOSEREQ state (sec. 8.3),
 * - Close    in   node-CLOSING  state (sec. 8.3),
 * - Acks in client-PARTOPEN state (sec. 8.1.5, handled by dccp_delack_timer()).
 * This function expects sk->sk_send_head to contain the original skb.
 */
int dccp_retransmit_skb(struct sock *sk)
{}

struct sk_buff *dccp_make_response(const struct sock *sk, struct dst_entry *dst,
				   struct request_sock *req)
{}

EXPORT_SYMBOL_GPL();

/* answer offending packet in @rcv_skb with Reset from control socket @ctl */
struct sk_buff *dccp_ctl_make_reset(struct sock *sk, struct sk_buff *rcv_skb)
{}

EXPORT_SYMBOL_GPL();

/* send Reset on established socket, to close or abort the connection */
int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
{}

/*
 * Do all connect socket setups that can be done AF independent.
 */
int dccp_connect(struct sock *sk)
{}

EXPORT_SYMBOL_GPL();

void dccp_send_ack(struct sock *sk)
{}

EXPORT_SYMBOL_GPL();

#if 0
/* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */
void dccp_send_delayed_ack(struct sock *sk)
{
	struct inet_connection_sock *icsk = inet_csk(sk);
	/*
	 * FIXME: tune this timer. elapsed time fixes the skew, so no problem
	 * with using 2s, and active senders also piggyback the ACK into a
	 * DATAACK packet, so this is really for quiescent senders.
	 */
	unsigned long timeout = jiffies + 2 * HZ;

	/* Use new timeout only if there wasn't a older one earlier. */
	if (icsk->icsk_ack.pending & ICSK_ACK_TIMER) {
		/* If delack timer was blocked or is about to expire,
		 * send ACK now.
		 *
		 * FIXME: check the "about to expire" part
		 */
		if (icsk->icsk_ack.blocked) {
			dccp_send_ack(sk);
			return;
		}

		if (!time_before(timeout, icsk->icsk_ack.timeout))
			timeout = icsk->icsk_ack.timeout;
	}
	icsk->icsk_ack.pending |= ICSK_ACK_SCHED | ICSK_ACK_TIMER;
	icsk->icsk_ack.timeout = timeout;
	sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
}
#endif

void dccp_send_sync(struct sock *sk, const u64 ackno,
		    const enum dccp_pkt_type pkt_type)
{}

EXPORT_SYMBOL_GPL();

/*
 * Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This
 * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under
 * any circumstances.
 */
void dccp_send_close(struct sock *sk, const int active)
{}