static int32_t proxy_negotiation_check(proxy_link_negotiate_t *neg)
{
- proxy_log(LOG_INFO, 0, "Features enabled: %08x", neg->v1.enabled);
+ proxy_log(LOG_INFO, 0, "Features enabled: %08x, protocol: %u",
+ neg->v1.enabled, neg->v2.protocol);
return 0;
}
}
proxy_link_negotiate_init(&global_cmount.neg, 0, PROXY_FEAT_ALL,
- 0, 0);
+ 0, 0, PROXY_LINK_PROTOCOL_VERSION);
err = proxy_link_handshake_client(&global_cmount.link, err,
&global_cmount.neg,
sd = err;
proxy_link_negotiate_init(&ceph_mount->neg, 0, PROXY_FEAT_ALL, 0,
- PROXY_FEAT_ASYNC_IO);
+ PROXY_FEAT_ASYNC_IO,
+ PROXY_LINK_PROTOCOL_VERSION);
err = proxy_link_handshake_client(&ceph_mount->link, sd,
&ceph_mount->neg,
static int32_t server_negotiation_check(proxy_link_negotiate_t *neg)
{
- proxy_log(LOG_INFO, 0, "Features enabled: %08x", neg->v1.enabled);
+ proxy_log(LOG_INFO, 0, "Features enabled: %08x, protocol: %u",
+ neg->v1.enabled, neg->v2.protocol);
return 0;
}
client = container_of(worker, proxy_client_t, worker);
- proxy_link_negotiate_init(&client->neg, 0, PROXY_FEAT_ALL, 0, 0);
+ proxy_link_negotiate_init(&client->neg, 0, PROXY_FEAT_ALL, 0, 0,
+ PROXY_LINK_PROTOCOL_VERSION);
err = proxy_link_handshake_server(client->link, client->sd,
&client->neg,
#define DEFINE_VERSION(_num) [_num] = NEG_VERSION_SIZE(_num)
static uint32_t negotiation_sizes[PROXY_LINK_NEGOTIATE_VERSION + 1] = {
- DEFINE_VERSION(1)
+ DEFINE_VERSION(1),
+ DEFINE_VERSION(2)
/* NEG_VERSION: Add newly defined versions above this comment. */
};
"features");
}
+ /* NEG_VERSION: Check if there's any incompatibility with new
+ * extensions that are not supported by an old
+ * peer. */
+
/* The peer is running the old version, but it is compatible
* with us, so everything is fine and the connection can be
* completed successfully with all features disabled. */
local->v1.enabled = 0;
+ local->v2.protocol = 0;
+
+ /* NEG_VERSION: Initialize default values for new extensions. */
proxy_log(LOG_INFO, 0,
"Connected to legacy peer. No features enabled");
enabled = (local->v1.enabled | remote->v1.enabled) & supported;
local->v1.enabled = enabled;
+ if (local->v2.protocol > remote->v2.protocol) {
+ local->v2.protocol = remote->v2.protocol;
+ }
+
/* NEG_VERSION: Implement handling of negotiate extensions. */
validate:
return err;
}
+ if (remote.v0.version == 1) {
+ return 0;
+ }
+
+ /* For version 2 and higher, send the agreed protocol. */
+ err = proxy_link_write(link, sd, &neg->v2.protocol,
+ sizeof(neg->v2.protocol));
+ if (err < 0) {
+ return err;
+ }
+
+ /* NEG_VERSION: Send any extension related information to the server.
+ * Make the changes above this line. */
+
return 0;
}
}
}
+ if (remote.v0.version > 1) {
+ /* Read the agreed protocol version. */
+ err = proxy_link_read(link, sd, &neg->v2.protocol,
+ sizeof(neg->v2.protocol));
+ if (err < 0) {
+ return err;
+ }
+
+ if (neg->v2.protocol > PROXY_LINK_PROTOCOL_VERSION) {
+ return proxy_log(LOG_ERR, EINVAL,
+ "The client tried to use an "
+ "unsupported protocol");
+ }
+ }
+
/* NEG_VERSION: Implement any required handling for new negotiate
* extensions. */
* starting with "NEG_VERSION" and do the appropriate changes in each place. */
/* NEG_VERSION: Update this value to the latest implemented version. */
-#define PROXY_LINK_NEGOTIATE_VERSION 1
+#define PROXY_LINK_NEGOTIATE_VERSION 2
+
+/* Known versions for communication protocol. */
+#define PROXY_PROTOCOL_V0 0
+
+/* The maximum supported protocol version. */
+#define PROXY_LINK_PROTOCOL_VERSION PROXY_PROTOCOL_V0
/* Version 0 structure will be used to handle legacy clients that don't support
* negotiation. */
uint32_t enabled;
} proxy_link_negotiate_v1_t;
+typedef struct _proxy_link_negotiate_v2 {
+ uint32_t protocol;
+} proxy_link_negotiate_v2_t;
+
/* NEG_VERSION: Add typedefs for new negotiate extensions above this comment. */
struct _proxy_link_negotiate {
proxy_link_negotiate_v0_t v0;
proxy_link_negotiate_v1_t v1;
+ proxy_link_negotiate_v2_t v2;
/* NEG_VERSION: Add newly defined typedefs above this comment. */
};
uint32_t min_version,
uint32_t supported,
uint32_t required,
- uint32_t enabled)
+ uint32_t enabled,
+ uint32_t protocol)
{
proxy_link_negotiate_init_v0(neg, PROXY_LINK_NEGOTIATE_VERSION,
min_version);
+
neg->v1.supported = supported;
neg->v1.required = required;
neg->v1.enabled = enabled;
+
+ neg->v2.protocol = protocol;
}
static inline bool proxy_link_is_connected(proxy_link_t *link)