* whenever the wire protocol changes. try to keep this string length
* constant.
*/
-#define CEPH_BANNER "ceph v025"
+#define CEPH_BANNER "ceph v026"
#define CEPH_BANNER_MAX_LEN 30
#define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */
#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */
#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
+#define CEPH_MSGR_TAG_FEATURES 12 /* insufficient features */
/*
* connection negotiation
*/
struct ceph_msg_connect {
+ __le64 features; /* supported feature bits */
__le32 host_type; /* CEPH_ENTITY_TYPE_* */
__le32 global_seq; /* count connections initiated by this host */
__le32 connect_seq; /* count connections initiated in this session */
struct ceph_msg_connect_reply {
__u8 tag;
+ __le64 features; /* feature bits for this session */
__le32 global_seq;
__le32 connect_seq;
__le32 protocol_version;
bufferptr bp;
bufferlist authorizer, authorizer_reply;
bool authorizer_valid;
+ __u64 feat_missing;
// this should roughly mirror pseudocode at
// http://ceph.newdream.net/wiki/Messaging_protocol
rank->lock.Unlock();
goto reply;
}
+
+ feat_missing = CEPH_FEATURE_REQUIRED & ~(__u64)connect.features;
+ if (feat_missing) {
+ dout(1) << "peer missing required features " << std::hex << feat_missing << std::dec << dendl;
+ reply.tag = CEPH_MSGR_TAG_FEATURES;
+ rank->lock.Unlock();
+ goto reply;
+ }
if (rank->verify_authorizer(connection_state, peer_type,
connect.authorizer_protocol, authorizer, authorizer_reply, authorizer_valid) &&
assert(0);
reply:
+ reply.features = ((__u64)connect.features & CEPH_FEATURE_SUPPORTED) | CEPH_FEATURE_REQUIRED;
reply.authorizer_len = authorizer_reply.length();
rc = tcp_write(sd, (char*)&reply, sizeof(reply));
if (rc < 0)
bufferlist authorizer_reply;
ceph_msg_connect connect;
+ connect.features = CEPH_FEATURE_SUPPORTED;
connect.host_type = rank->my_type;
connect.global_seq = gseq;
connect.connect_seq = cseq;
goto stop_locked;
}
+ if (reply.tag == CEPH_MSGR_TAG_FEATURES) {
+ dout(0) << "connect protocol feature mismatch, my " << std::hex
+ << connect.features << " < peer " << reply.features
+ << " missing " << (reply.features & ~CEPH_FEATURE_SUPPORTED)
+ << std::dec << dendl;
+ goto fail_locked;
+ }
+
if (reply.tag == CEPH_MSGR_TAG_BADPROTOVER) {
dout(0) << "connect protocol version mismatch, my " << connect.protocol_version
<< " != " << reply.protocol_version << dendl;
}
if (reply.tag == CEPH_MSGR_TAG_READY) {
+ __u64 feat_missing = CEPH_FEATURE_REQUIRED & ~(__u64)reply.features;
+ if (feat_missing) {
+ dout(1) << "missing required features " << std::hex << feat_missing << std::dec << dendl;
+ goto fail_locked;
+ }
+
// hooray!
peer_global_seq = reply.global_seq;
policy.lossy = reply.flags & CEPH_MSG_CONNECT_LOSSY;