net/sctp/output.c

Source file repositories/reference/linux-study-clean/net/sctp/output.c

File Facts

System
Linux kernel
Corpus path
net/sctp/output.c
Extension
.c
Size
24458 bytes
Lines
866
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!packet->has_cookie_echo) {
			int error = 0;

			error = sctp_packet_transmit(packet, gfp);
			if (error < 0)
				chunk->skb->sk->sk_err = -error;

			/* If we have an empty packet, then we can NOT ever
			 * return PMTU_FULL.
			 */
			if (!one_packet)
				retval = sctp_packet_append_chunk(packet,
								  chunk);
		}
		break;

	case SCTP_XMIT_RWND_FULL:
	case SCTP_XMIT_OK:
	case SCTP_XMIT_DELAY:
		break;
	}

	return retval;
}

/* Try to bundle a pad chunk into a packet with a heartbeat chunk for PLPMTUTD probe */
static enum sctp_xmit sctp_packet_bundle_pad(struct sctp_packet *pkt, struct sctp_chunk *chunk)
{
	struct sctp_transport *t = pkt->transport;
	struct sctp_chunk *pad;
	int overhead = 0;

	if (!chunk->pmtu_probe)
		return SCTP_XMIT_OK;

	/* calculate the Padding Data size for the pad chunk */
	overhead += sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
	overhead += sizeof(struct sctp_sender_hb_info) + sizeof(struct sctp_pad_chunk);
	pad = sctp_make_pad(t->asoc, t->pl.probe_size - overhead);
	if (!pad)
		return SCTP_XMIT_DELAY;

	list_add_tail(&pad->list, &pkt->chunk_list);
	pkt->size += SCTP_PAD4(ntohs(pad->chunk_hdr->length));
	chunk->transport = t;

	return SCTP_XMIT_OK;
}

/* Try to bundle an auth chunk into the packet. */
static enum sctp_xmit sctp_packet_bundle_auth(struct sctp_packet *pkt,
					      struct sctp_chunk *chunk)
{
	struct sctp_association *asoc = pkt->transport->asoc;
	enum sctp_xmit retval = SCTP_XMIT_OK;
	struct sctp_chunk *auth;

	/* if we don't have an association, we can't do authentication */
	if (!asoc)
		return retval;

	/* See if this is an auth chunk we are bundling or if
	 * auth is already bundled.
	 */
	if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth)
		return retval;

	/* if the peer did not request this chunk to be authenticated,
	 * don't do it
	 */
	if (!chunk->auth)
		return retval;

	auth = sctp_make_auth(asoc, chunk->shkey->key_id);
	if (!auth)
		return retval;

	auth->shkey = chunk->shkey;
	sctp_auth_shkey_hold(auth->shkey);

	retval = __sctp_packet_append_chunk(pkt, auth);

	if (retval != SCTP_XMIT_OK)
		sctp_chunk_free(auth);

	return retval;
}

/* Try to bundle a SACK with the packet. */
static enum sctp_xmit sctp_packet_bundle_sack(struct sctp_packet *pkt,

Annotation

Implementation Notes