RXRPC(7)
๐ NAME ๐
rxrpc โ the Linux RxRPC (AFS) protocol implementation, bestie. Yes, it's a real socket family. Yes, it slays. ๐ฆ
This one lives in the kafs-client manual, section 7, so you already know it's the deep lore. โจ
๐ธ SYNOPSIS ๐ธ
#include <sys/socket.h>
#include <linux/rxrpc.h>
socket = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);
socket = socket(AF_RXRPC, SOCK_DGRAM, PF_INET6);
โจ DESCRIPTION โจ
Okay so Linux can implement the RxRPC transport protocol โ that's the one the AFS network filesystem rides on. And here's the iconic part: both the client end AND the server end are supported, even on the same socket, and authentication works at both ends too. Multi-talented. ๐
You talk to it through the regular BSD socket interface, using sendmsg(2) and recvmsg(2) with control data โ that's how you multiplex a bunch of calls over one socket and how you hand over or pick up call metadata. And request_key(2) is what finds the authentication keys you wanna use, looking in the calling process's keyrings. ๐
Under the hood, the AF_RXRPC driver uses udp(7) sockets for transport โ either IPv4-only or IPv6 (with IPv4 hanging around too). And under certain circumstances, those underlying transport sockets may be shared between client-only sockets. But heads up: they are never shared if a socket is implementing a server. Nope. Not happening. ๐
โโ๏ธ
๐บ๏ธ Address format
struct sockaddr_rxrpc {
sa_family_t srx_family; /* AF_RXRPC */
uint16_t srx_service; /* The service identifier */
uint16_t transport_type; /* The type of transport */
uint16_t transport_len; /* Transport address length */
union {
sa_family_t family; /* Transport address family */
struct sockaddr_in sin; /* IPv4 transport address */
struct sockaddr_in6 sin6; /* IPv6 transport address */
} transport;
};
So like, the rundown:
srx_familyis always set toAF_RXRPC. Always. No debate.srx_serviceis set to the service ID of the service you're after.transport_typeis set to the transport type, which for now is alwaysSOCK_DGRAM.transport_lensays how big the address sitting intransportis.
Inside that transport address part, you set an address that actually makes sense for the underlying socket โ family, port, address, all the usual suspects as appropriate. And lowkey: it may be permissible to use IPv4 addresses on an IPv6 socket. ๐
๐ Socket Options
AF_RXRPC serves up a whole lineup of socket options you can set with setsockopt(2) and read back with getsockopt(2). The socket option level for IPv6 is SOL_RXRPC.
RXRPC_SECURITY_KEYโ the option value is a string naming a key to hand torequest_key(2)so it can go fetch an appropriate authentication key. Those keys are expected to be ofrxrpctype. And if you never set this?AF_RXRPCwill just do an unauthenticated, unencrypted call to the server. No key, no problem, no security either. ๐ญRXRPC_SECURITY_KEYRINGโ the option value is a string naming a keyring to pass torequest_key(2), which is how you tell the server end which keys it should use to authenticate connections. The service keys inside that ring should be of typerxrpc_s, their descriptions should be of the form"<service-id>:<security-index>", and each one should be given an 8-byte secret. ๐๏ธRXRPC_EXCLUSIVE_CONNECTIONโ the option value should be empty. What it does is make every single call on this socket get its own virtual connection, and therefore its own negotiated security context. Very main character, refuses to share. โจRXRPC_MIN_SECURITY_LEVELโ the option value should be a 4-byte unsigned integer, and it can be one of these constants:RXRPC_SECURITY_PLAIN,RXRPC_SECURITY_AUTH, orRXRPC_SECURITY_ENCRYPT.RXRPC_SECURITY_PLAINmeans the packets should be securely checksummed only,RXRPC_SECURITY_AUTHmeans packets should be authenticated, andRXRPC_SECURITY_ENCRYPTmeans full encryption is employed. Pick your fighter. ๐ฅRXRPC_UPGRADEABLE_SERVICEโ the option value should be a 2-slot array of 2-byte unsigned integers. To use this the socket must be a server socket, and it must have been bound to more than one address with differentsrx_servicespecifiers. Slot[0] in the array is the service ID to upgrade from; slot[1] is the service ID to upgrade to. This lets a client find out whether there's a 'better' version of the service available on the same address but under a different service ID. And if the client follows the correct protocol for probing an upgradeable service, the kernel will automatically upgrade the service ID on the connection, and that'll show up in the addressrecvmsg(2)returns. Glow up, but for service IDs. ๐RXRPC_SUPPORTED_CMSGโ the option buffer should have room for a 4-byte integer. The maximum control buffer message type supported by the kernel gets written into that buffer. Why do you care? Because it lets an application find out which control messages it's actually allowed to use, so it can dodge an error instead of trying something unsupported and getting humbled. ๐
๐ฉ Message flags
AF_RXRPC communicates certain information by way of the message flags passed to and received from sendmsg(2) and recvmsg(2).
MSG_MOREโ this is passed tosendmsg()to indicate that there's more data to be transmitted as part of the request phase of a client call, or the reply phase of a service operation.MSG_EORโrecvmsg()sets this to indicate that the call has been terminated (the control messages must be parsed for information as to why), and that the kernel has discarded the user call ID tag. That tag may now be reused. ๐MSG_PEEKโ this is passed torecvmsg()to look at the front of the message queue without removing any messages or changing the state of any outstanding calls.MSG_WAITALLโ this is passed tosendmsg()to instruct it not to return for a signal if it's still loading up the message queue and progress is being made at the other side in emptying it. This works around the problem ofsendmsg()getting interrupted after partially queuing its data, but not then being able to return how much it has consumed. ๐ฎโ๐จMSG_DONTWAITโ this is passed torecvmsg()to indicate that it shouldn't wait if the message queue is empty.
๐ฆ Control messages
AF_RXRPC communicates metadata to the caller through the ancillary data buffer (msg_control) in the messages passed to and fro using sendmsg(2) and recvmsg(2). And when you're building a control message buffer for sendmsg(), you should consult the RXRPC_SUPPORTED_CMSG value to make sure that the control message type you're reaching for is actually supported. Check before you wreck. โจ
RXRPC_USER_CALL_IDโ the data for this is an arbitrary long integer/pointer-sized tag that represents the call to the kernel. It may, for example, hold a pointer to some userspace structure representing the call to the process.[sendmsg]This is passed tosendmsg()when the message proposed will create a client call. It must thereafter be included in all futuresendmsg()calls pertaining to that call.[recvmsg]recvmsg()includes the tag in all messages pertaining to a call until the final termination message is reached โ whichrecvmsg()will mark by settingMSG_EOR.
RXRPC_ABORTโ the data for this is a 32-bit integer that is the abort code.[sendmsg]When passed tosendmsg(), this causes the operation matching the tag to be aborted; this will be followed up byrecvmsg()indicatingMSG_EORand a local error ofECONNABORTED, thereby terminating the tag.[recvmsg]When obtained fromrecvmsg(), this indicates that a remote abort was received from the peer, and the data gives the code for that abort.
RXRPC_ACKโ[recvmsg]this conveys no data. It indicates the final acknowledgement to a service call has been received. ๐RXRPC_NET_ERRORโ[recvmsg]this conveys a 32-bit integer into which the network error that terminated a call will have been placed.RXRPC_BUSYโ[recvmsg]this conveys no data. It indicates that the operation has been rejected because the server is busy. ๐ญRXRPC_LOCAL_ERRORโ[recvmsg]this conveys a 32-bit integer into which the local error that terminated a call will have been placed.RXRPC_NEW_CALLโ[recvmsg]this conveys no data. It indicates that a new service call has arrived at a server socket and is in need of a tag.RXRPC_ACCEPTmust be used for that.RXRPC_ACCEPTโ the data for this is an arbitrary long integer/pointer-sized tag that represents the call to the kernel, with the same semantics as forRXRPC_USER_CALL_ID.[sendmsg]Supply a user call ID tag to a new service call.
RXRPC_EXCLUSIVE_CALLโ[sendmsg]indicate that this particular call should be made on its own connection with an unshared negotiated security context. This requires no additional data. ๐ฆRXRPC_UPGRADE_SERVICEโ[sendmsg]indicate that this call should attempt to probe the service ID on the other side to see if it gets upgraded. The answer can be found in thesrx_servicevalue of the peer addressrecvmsg()returns for this call. This requires no additional data.RXRPC_TX_LENGTHโ the data for this is a signed 64-bit integer.[sendmsg]Specify the exact total transmit size. This allowsAF_RXRPCto work out in advance how big encrypted packets are going to be (under some circumstances, there's a data length encrypted inside the packet).- If this is set, it may allow
AF_RXRPCto be more efficient at filling packets. But listen: if the wrong amount of data is given โ too little or too much โ then the call will be aborted. Get your math right, bestie. ๐
RXRPC_SET_CALL_TIMEOUTโ the data for this is an array of 1-3 32-bit integers.[sendmsg]Specify various call timeouts.- The first timeout is the hard timeout for the call, in seconds: the call will be aborted if it takes longer than this amount of time in total.
- The second timeout is the idle timeout for the call, in milliseconds: the call will be aborted if we don't receive the next
DATApacket within that amount of time during the reception phase. - The third timeout is the normal timeout for the call, in milliseconds: the call will be aborted if we go for that amount of time without receiving any type of packet pertaining to the call.
๐ SEE ALSO ๐
ยฉ๏ธ COPYRIGHT ยฉ๏ธ
Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
Written by David Howells (dhowells@redhat.com) โ thank you king, we owe you everything ๐ซถ
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.
And that's the whole page, no cap. This version is 0.9, dated 2026-08-27, and it came straight from the RXRPC(7) manual. Slay, stay socket-safe, and remember: check RXRPC_SUPPORTED_CMSG before you send. ๐
โจ๐
๐ฆ where this page comes from
- fedora 43: kafs-client 0.9-1.fc43 ยท GPL-2.0-or-later
- fedora 43: kafs-client 0.9-1.fc43 ยท GPL-2.0-or-later
- fedora 44: kafs-client 0.9-1.fc44 ยท GPL-2.0-or-later
- fedora 44: kafs-client 0.9-1.fc44 ยท GPL-2.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms