Feature Negotiation (Offers)
Relevant source files
The following files were used as context for generating this wiki page:
Feature Negotiation, referred to as "Offers" within librelp, is the mechanism used during the RELP session establishment phase to agree upon protocol versions, supported commands, and software metadata. This process ensures that both the client and the server are compatible and aware of each other's capabilities before data transmission begins. Sources: doc/relp.html:158-160, src/offers.c
The negotiation occurs specifically during the processing of the open command. The client sends a set of offers describing its capabilities, and the server responds with a subset of those offers that it also supports. A successful negotiation must at minimum include the relp_version offer. Sources: doc/relp.html:162-175, src/copen.c:118-124
Architecture and Data Structures
The system is built around three primary object types: relpOffers, relpOffer, and relpOfferValue. These are organized in a hierarchical list structure. Sources: src/offers.h:42-64
Data Models
| Structure | Description | Key Fields |
|---|---|---|
relpOfferValue_t | Represents a single parameter value for a feature. | szVal (string), intVal (integer), pNext |
relpOffer_t | Represents a specific feature or capability. | szName (feature name), pValueRoot, pNext |
relpOffers_t | A container for the list of all offers in a session. | pRoot (pointer to first relpOffer_t) |
Sources: src/offers.h:42-64, src/offers.c:30-110
Object Relationship Diagram
The following diagram illustrates how offers and their values are linked within the engine.
Sources: src/offers.h:42-64
The Negotiation Process
Negotiation follows a strict request-response flow initiated by the client during the session startup. Sources: doc/relp.html:200-205
Sequence of Events
- Client Init: The client constructs a
relpOffers_tlist based on its configuration and converts it to a string. - Open Command: The client sends the
opencommand with the offers string as the data portion. - Server Selection: The server parses the frame, selects supported offers, and sets session parameters (e.g., protocol version, enabled commands).
- Server Response: The server sends a
rspcommand containing the accepted offers. - Final Validation: The client checks the server's response to ensure all "required" features were accepted.
Sources: src/relpsess.c:646-680, src/copen.c:50-95, doc/relp.html:162-178
Negotiation Flow Diagram
The following flowchart describes the logic used by the server to select and enable features.
Sources: src/copen.c:50-136
Key Features and Parameters
Several standard offers are defined in the RELP specification and implemented in librelp.
| Feature Name | Description | Mandatory/Optional |
|---|---|---|
relp_version | The protocol version (Current: 1). | Mandatory |
commands | List of supported commands (e.g., syslog). | Optional |
relp_software | Metadata about the software, version, and URL. | Optional |
Sources: doc/relp.html:184-198, src/copen.c:65-83
Command States
Commands have an internal state machine determining how they are negotiated:
- Unset/Forbidden: Command cannot be used.
- Desired: Peer would like to use the feature.
- Required: Peer MUST have the feature; negotiation fails if not supported.
- Enabled: Feature is active for the current session.
Sources: src/librelp.h:103-110, src/copen.c:97-105
Implementation Details
Frame Parsing
The function relpOffersConstructFromFrame parses the raw character stream from a RELP frame. It handles the FEATURENAME=VALUE1,VALUE2 syntax, extracting names and values into the object hierarchy. Sources: src/offers.c:286-330
/* Sources: src/offers.c:303-311 */
while(localRet == RELP_RET_OK) {
/* command name */
iName = 0;
while(iName < RELP_MAX_OFFER_FEATURENAME && c != '=' && localRet == RELP_RET_OK) {
szFeatNam[iName++] = c;
localRet = relpFrameGetNextC(pFrame, &c);
}
szFeatNam[iName] = '\0';
CHKRet(relpOfferAdd(&pOffer, szFeatNam, pOffers));
// ... value processing follows
}
Offer Selection Logic
In copen.c, the server iterates through client offers. If a relp_version is offered that is higher than the server's version, the server downgrades the session to its own maximum supported version. Sources: src/copen.c:67-74
Error Handling
If a required feature is missing during negotiation, the server returns a 500 required command not supported by client error. Similarly, if the client finds the server's offers incompatible (e.g., unsupported version), it flags the session as broken. Sources: src/copen.c:132-136, src/relpsess.c:755-763
Feature Negotiation is critical for protocol evolution, allowing newer librelp versions to remain backward compatible with older implementations while enabling advanced features when both peers support them. Sources: doc/relp.html:195-198