Update block transfer protocol to v2.

This commit is contained in:
Jiaqiang Xu 2013-10-03 17:58:52 +08:00
parent 5b0df118d3
commit 9e8a214403
4 changed files with 96 additions and 19 deletions

View File

@ -148,7 +148,10 @@ handle_frame_content (struct evbuffer *buf, FrameParser *parser)
if (evbuffer_get_length (input) < parser->enc_frame_len)
return 0;
blocktx_decrypt_init (&ctx, parser->key, parser->iv);
if (parser->version == 1)
blocktx_decrypt_init (&ctx, parser->key, parser->iv);
else if (parser->version == 2)
blocktx_decrypt_init (&ctx, parser->key_v2, parser->iv_v2);
frame = g_malloc (parser->enc_frame_len);
out = g_malloc (parser->enc_frame_len + ENC_BLOCK_SIZE);
@ -277,7 +280,10 @@ handle_frame_fragments (struct evbuffer *buf, FrameParser *parser)
parser->enc_frame_len = ntohl (frame_len);
parser->remain = parser->enc_frame_len;
blocktx_decrypt_init (&parser->ctx, parser->key, parser->iv);
if (parser->version == 1)
blocktx_decrypt_init (&parser->ctx, parser->key, parser->iv);
else if (parser->version == 2)
blocktx_decrypt_init (&parser->ctx, parser->key_v2, parser->iv_v2);
parser->enc_init = TRUE;
if (evbuffer_get_length (input) > 0)

View File

@ -11,7 +11,7 @@
#define ENC_KEY_SIZE 32
#define ENC_BLOCK_SIZE 16
#define BLOCK_PROTOCOL_VERSION 1
#define BLOCK_PROTOCOL_VERSION 2
enum {
STATUS_OK = 0,
@ -109,11 +109,16 @@ typedef int (*FrameFragmentCB) (char *, int, int, void *);
typedef struct _FrameParser {
int enc_frame_len;
unsigned char key[ENC_KEY_SIZE];
unsigned char key[ENC_BLOCK_SIZE];
unsigned char iv[ENC_BLOCK_SIZE];
gboolean enc_init;
EVP_CIPHER_CTX ctx;
unsigned char key_v2[ENC_KEY_SIZE];
unsigned char iv_v2[ENC_BLOCK_SIZE];
int version;
/* Used when parsing fragments */
int remain;

View File

@ -65,12 +65,17 @@ struct _BlockTxClient {
/* Used by get block */
BlockHandle *block;
unsigned char key[ENC_KEY_SIZE];
unsigned char key[ENC_BLOCK_SIZE];
unsigned char iv[ENC_BLOCK_SIZE];
unsigned char key_v2[ENC_KEY_SIZE];
unsigned char iv_v2[ENC_BLOCK_SIZE];
FrameParser parser;
gboolean break_loop;
int version;
};
typedef struct _BlockTxClient BlockTxClient;
@ -203,9 +208,15 @@ init_frame_parser (BlockTxClient *client)
{
FrameParser *parser = &client->parser;
memcpy (parser->key, client->key, ENC_KEY_SIZE);
memcpy (parser->iv, client->iv, ENC_BLOCK_SIZE);
if (client->version == 1) {
memcpy (parser->key, client->key, ENC_BLOCK_SIZE);
memcpy (parser->iv, client->iv, ENC_BLOCK_SIZE);
} else if (client->version == 2) {
memcpy (parser->key_v2, client->key_v2, ENC_KEY_SIZE);
memcpy (parser->iv_v2, client->iv_v2, ENC_BLOCK_SIZE);
}
parser->version = client->version;
parser->cbarg = client;
}
@ -230,8 +241,21 @@ handle_handshake_response (BlockTxClient *client)
if (rsp.status == STATUS_OK) {
seaf_debug ("Handshake OK.\n");
blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key),
client->key, client->iv);
client->version = MIN (rsp.version, BLOCK_PROTOCOL_VERSION);
if (client->version == 1)
blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key),
client->key, client->iv);
else if (client->version == 2)
blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key),
client->key_v2, client->iv_v2);
else {
seaf_warning ("Bad block protocol version %d.\n", rsp.version);
info->result = BLOCK_CLIENT_FAILED;
return -1;
}
seaf_debug ("Block protocol version %d.\n", client->version);
init_frame_parser (client);
@ -311,7 +335,10 @@ send_authentication (BlockTxClient *client)
EVP_CIPHER_CTX ctx;
int ret = 0;
blocktx_encrypt_init (&ctx, client->key, client->iv);
if (client->version == 1)
blocktx_encrypt_init (&ctx, client->key, client->iv);
else if (client->version == 2)
blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2);
seaf_debug ("session token length is %d.\n", strlen(task->session_token));
@ -362,7 +389,10 @@ send_block_header (BlockTxClient *client, int command)
header.command = htonl (command);
memcpy (header.block_id, client->curr_block_id, 40);
blocktx_encrypt_init (&ctx, client->key, client->iv);
if (client->version == 1)
blocktx_encrypt_init (&ctx, client->key, client->iv);
else if (client->version == 2)
blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2);
if (send_encrypted_data_frame_begin (client->data_fd, sizeof(header)) < 0) {
seaf_warning ("Send block header %s: failed to begin.\n",
@ -494,7 +524,10 @@ send_encrypted_block (BlockTxClient *client,
size = md->size;
g_free (md);
blocktx_encrypt_init (&ctx, client->key, client->iv);
if (client->version == 1)
blocktx_encrypt_init (&ctx, client->key, client->iv);
else if (client->version == 2)
blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2);
if (send_encrypted_data_frame_begin (client->data_fd, size) < 0) {
seaf_warning ("Send block %s: failed to begin.\n", block_id);

View File

@ -35,12 +35,17 @@ struct _BlockTxServer {
/* Used by put block */
BlockHandle *block;
unsigned char key[ENC_KEY_SIZE];
unsigned char key[ENC_BLOCK_SIZE];
unsigned char iv[ENC_BLOCK_SIZE];
unsigned char key_v2[ENC_KEY_SIZE];
unsigned char iv_v2[ENC_BLOCK_SIZE];
FrameParser parser;
gboolean break_loop;
int version;
};
typedef struct _BlockTxServer BlockTxServer;
@ -69,9 +74,15 @@ init_frame_parser (BlockTxServer *server)
{
FrameParser *parser = &server->parser;
memcpy (parser->key, server->key, ENC_KEY_SIZE);
memcpy (parser->iv, server->iv, ENC_BLOCK_SIZE);
if (server->version == 1) {
memcpy (parser->key, server->key, ENC_BLOCK_SIZE);
memcpy (parser->iv, server->iv, ENC_BLOCK_SIZE);
} else if (server->version == 2) {
memcpy (parser->key_v2, server->key_v2, ENC_KEY_SIZE);
memcpy (parser->iv_v2, server->iv_v2, ENC_BLOCK_SIZE);
}
parser->version = server->version;
parser->cbarg = server;
}
@ -106,7 +117,10 @@ process_session_key (BlockTxServer *server, unsigned char *enc_session_key)
session_key = g_base64_decode (key_b64, &len);
blocktx_generate_encrypt_key (session_key, len, server->key, server->iv);
if (server->version == 1)
blocktx_generate_encrypt_key (session_key, len, server->key, server->iv);
else if (server->version == 2)
blocktx_generate_encrypt_key (session_key, len, server->key_v2, server->iv_v2);
init_frame_parser (server);
@ -137,6 +151,16 @@ handle_handshake_request (BlockTxServer *server)
evbuffer_remove (input, &req, sizeof(req));
req.version = ntohl (req.version);
server->version = MIN (req.version, BLOCK_PROTOCOL_VERSION);
if (server->version != 1 && server->version != 2) {
seaf_warning ("Bad block protocol version %d.\n", server->version);
send_handshake_response (server, STATUS_VERSION_MISMATCH);
return -1;
}
seaf_debug ("Block protocol version %d.\n", server->version);
server->session_key_len = ntohl (req.key_len);
if (server->session_key_len > MAX_SESSION_KEY_SIZE) {
seaf_warning ("Encrypted session key is too long: %d.\n",
@ -181,7 +205,10 @@ send_auth_response (BlockTxServer *server, int status)
rsp.status = htonl (status);
blocktx_encrypt_init (&ctx, server->key, server->iv);
if (server->version == 1)
blocktx_encrypt_init (&ctx, server->key, server->iv);
else if (server->version == 2)
blocktx_encrypt_init (&ctx, server->key_v2, server->iv_v2);
if (send_encrypted_data_frame_begin (server->data_fd, sizeof(rsp)) < 0) {
seaf_warning ("Send auth response: failed to begin.\n");
@ -270,7 +297,10 @@ send_block_response_header (BlockTxServer *server, int status)
header.status = htonl (status);
blocktx_encrypt_init (&ctx, server->key, server->iv);
if (server->version == 1)
blocktx_encrypt_init (&ctx, server->key, server->iv);
else if (server->version == 2)
blocktx_encrypt_init (&ctx, server->key_v2, server->iv_v2);
if (send_encrypted_data_frame_begin (server->data_fd, sizeof(header)) < 0) {
seaf_warning ("Send block response header %s: failed to begin.\n",
@ -398,7 +428,10 @@ send_encrypted_block (BlockTxServer *server,
EVP_CIPHER_CTX ctx;
char send_buf[SEND_BUFFER_SIZE];
blocktx_encrypt_init (&ctx, server->key, server->iv);
if (server->version == 1)
blocktx_encrypt_init (&ctx, server->key, server->iv);
else if (server->version == 2)
blocktx_encrypt_init (&ctx, server->key_v2, server->iv_v2);
if (send_encrypted_data_frame_begin (server->data_fd, size) < 0) {
seaf_warning ("Send block %s: failed to begin.\n", block_id);