in nanofi/src/sitetosite/CRawSocketProtocol.c [99:263]
int handShake(struct CRawSiteToSiteClient * client) {
if (client->_peer_state != ESTABLISHED) {
return -1;
}
CIDGenerator gen;
gen.implementation_ = CUUID_DEFAULT_IMPL;
generate_uuid(&gen, client->_commsIdentifier);
client->_commsIdentifier[36]='\0';
int ret = writeUTF(client->_commsIdentifier, strlen(client->_commsIdentifier), False, client->_peer->_stream);
if (ret <= 0) {
return -1;
}
uint32_t prop_size;
PropertyValue *current, *tmp, * properties = NULL;
current = (PropertyValue *)malloc(sizeof(PropertyValue));
current->name = HandShakePropertyStr[GZIP];
strncpy(current->value, "false", sizeof(current->value));
current->value[sizeof(current->value) - 1] = '\0';
HASH_ADD_KEYPTR(hh, properties, current->name, strlen(current->name), current);
current = (PropertyValue *)malloc(sizeof(PropertyValue));
current->name = HandShakePropertyStr[PORT_IDENTIFIER];
strncpy(current->value, client->_port_id_str, sizeof(current->value));
current->value[sizeof(current->value) - 1] = '\0';
HASH_ADD_KEYPTR(hh, properties, current->name, strlen(current->name), current);
current = (PropertyValue *)malloc(sizeof(PropertyValue));
current->name = HandShakePropertyStr[REQUEST_EXPIRATION_MILLIS];
sprintf(current->value, "%"PRIu64, client->_timeout);
HASH_ADD_KEYPTR(hh, properties, current->name, strlen(current->name), current);
prop_size = 3;
if (client->_currentVersion >= 5) {
if (client->_batch_count > 0) {
current = (PropertyValue *)malloc(sizeof(PropertyValue));
current->name = HandShakePropertyStr[BATCH_COUNT];
sprintf(current->value, "%"PRIu64, client->_batch_count);
HASH_ADD_KEYPTR(hh, properties, current->name, strlen(current->name), current);
prop_size++;
}
if (client->_batch_size > 0) {
current = (PropertyValue *)malloc(sizeof(PropertyValue));
current->name = HandShakePropertyStr[BATCH_SIZE];
sprintf(current->value, "%"PRIu64, client->_batch_size);
HASH_ADD_KEYPTR(hh, properties, current->name, strlen(current->name), current);
prop_size++;
}
if (client->_batch_duration > 0) {
current = (PropertyValue *)malloc(sizeof(PropertyValue));
current->name = HandShakePropertyStr[BATCH_DURATION];
sprintf(current->value, "%"PRIu64, client->_batch_duration);
HASH_ADD_KEYPTR(hh, properties, current->name, strlen(current->name), current);
prop_size++;
}
}
int ret_val = 0;
if (client->_currentVersion >= 3) {
const char * urlstr = getURL(client->_peer);
ret = writeUTF(urlstr, strlen(urlstr), False, client->_peer->_stream);
if (ret <= 0) {
ret_val = -1;
}
}
if (ret_val == 0) {
ret = write_uint32_t(prop_size, client->_peer->_stream);
}
if (ret <= 0) {
ret_val = -1;
}
HASH_ITER(hh, properties, current, tmp) {
if (ret_val == 0 && writeUTF(current->name, strlen(current->name), False, client->_peer->_stream) <= 0) {
ret_val = -1;
}
if (ret_val == 0 && writeUTF(current->value, strlen(current->value), False, client->_peer->_stream) <= 0) {
ret_val = -1;
}
logc(debug, "Site2Site Protocol Send handshake properties %s %s", current->name, current->value);
HASH_DEL(properties, current);
free(current);
}
if (ret_val < 0) {
logc(err, "%s", "Failed to transfer handshake properties");
return -1;
}
RespondCode code;
ret = readResponse(client, &code);
if (ret <= 0) {
logc(err, "failed to receive response code from server");
return -1;
}
RespondCodeContext *resCode = getRespondCodeContext(code);
if (resCode == NULL) {
logc(err, "Received invalid respond code: %d", code);
return -1;
}
if (resCode->hasDescription) {
uint32_t utflen;
ret = readUTFLen(&utflen, client->_peer->_stream);
if (ret <= 0)
return -1;
memset(client->_description_buffer, 0, utflen+1);
ret = readUTF(client->_description_buffer, utflen, client->_peer->_stream);
if (ret <= 0)
return -1;
}
const char * error = "";
switch (code) {
case PROPERTIES_OK:
logc(debug, "%s", "Site2Site HandShake Completed");
client->_peer_state = HANDSHAKED;
return 0;
case PORT_NOT_IN_VALID_STATE:
error = "in invalid state";
break;
case UNKNOWN_PORT:
error = "an unknown port";
break;
case PORTS_DESTINATION_FULL:
error = "full";
break;
// Unknown error
default:
logc(err, "HandShake Failed because of unknown respond code %d", code);
return -1;
}
// All known error cases handled here
logc(err, "Site2Site HandShake Failed because destination port, %s, is %s", client->_port_id_str, error);
return -2;
}