From 794d69ca97738736844ee6a6da37f1ef686578cb Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 1 Oct 2011 08:48:50 -0600 Subject: [PATCH] server: ensure payload larger than max is broken into pieces For debug purposes, set the max payload size to 64 to catch any further issues while developing this. Signed-off-by: Jens Axboe --- client.c | 12 +--------- server.c | 70 +++++++++++++++++++++++++++++++++++++------------------- server.h | 12 ++++++---- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/client.c b/client.c index b47624b5..1074da44 100644 --- a/client.c +++ b/client.c @@ -57,17 +57,7 @@ int fio_client_connect(const char *host) static int send_file_buf(char *buf, off_t size) { - struct fio_net_cmd *cmd; - int ret; - - cmd = malloc(sizeof(*cmd) + size); - - fio_init_net_cmd(cmd, FIO_NET_CMD_JOB_END, buf, size); - fio_net_cmd_crc(cmd); - - ret = fio_send_data(fio_client_fd, cmd, sizeof(*cmd) + size); - free(cmd); - return ret; + return fio_net_send_cmd(fio_client_fd, FIO_NET_CMD_JOB, buf, size); } /* diff --git a/server.c b/server.c index e7b77417..38698bc3 100644 --- a/server.c +++ b/server.c @@ -29,6 +29,8 @@ static int server_fd; int fio_send_data(int sk, const void *p, unsigned int len) { + assert(len <= sizeof(struct fio_net_cmd) + FIO_SERVER_MAX_PDU); + do { int ret = send(sk, p, len, 0); @@ -157,6 +159,35 @@ void fio_net_cmd_crc(struct fio_net_cmd *cmd) cmd->pdu_crc16 = cpu_to_le16(crc16(cmd->payload, pdu_len)); } +int fio_net_send_cmd(int fd, uint16_t opcode, const char *buf, off_t size) +{ + struct fio_net_cmd *cmd; + size_t this_len; + int ret; + + do { + this_len = size; + if (this_len > FIO_SERVER_MAX_PDU) + this_len = FIO_SERVER_MAX_PDU; + + cmd = malloc(sizeof(*cmd) + this_len); + + fio_init_net_cmd(cmd, opcode, buf, this_len); + + if (this_len < size) + cmd->flags |= FIO_NET_CMD_F_MORE; + + fio_net_cmd_crc(cmd); + + ret = fio_send_data(fd, cmd, sizeof(*cmd) + this_len); + free(cmd); + size -= this_len; + buf += this_len; + } while (!ret && size); + + return ret; +} + static int send_simple_command(int sk, uint16_t opcode, uint64_t serial) { struct fio_net_cmd cmd = { @@ -194,7 +225,7 @@ static int send_quit_command(void) return send_simple_command(server_fd, FIO_NET_CMD_QUIT, 0); } -static int handle_cur_job(struct fio_net_cmd *cmd, int done) +static int handle_cur_job(struct fio_net_cmd *cmd) { unsigned int left = job_max_len - job_cur_len; int ret = 0; @@ -207,16 +238,19 @@ static int handle_cur_job(struct fio_net_cmd *cmd, int done) memcpy(job_buf + job_cur_len, cmd->payload, cmd->pdu_len); job_cur_len += cmd->pdu_len; - if (done) { - parse_jobs_ini(job_buf, 1, 0); - ret = exec_run(); - send_quit_command(); - reset_fio_state(); - free(job_buf); - job_buf = NULL; - job_cur_len = job_max_len = 0; - } + /* + * More data coming for this job + */ + if (cmd->flags & FIO_NET_CMD_F_MORE) + return 0; + parse_jobs_ini(job_buf, 1, 0); + ret = exec_run(); + send_quit_command(); + reset_fio_state(); + free(job_buf); + job_buf = NULL; + job_cur_len = job_max_len = 0; return ret; } @@ -233,10 +267,7 @@ static int handle_command(struct fio_net_cmd *cmd) case FIO_NET_CMD_NAK: return 1; case FIO_NET_CMD_JOB: - ret = handle_cur_job(cmd, 0); - break; - case FIO_NET_CMD_JOB_END: - ret = handle_cur_job(cmd, 1); + ret = handle_cur_job(cmd); break; default: log_err("fio: unknown opcode: %d\n", cmd->opcode); @@ -378,16 +409,7 @@ int fio_server(void) int fio_server_text_output(const char *buf, unsigned int len) { - struct fio_net_cmd *cmd; - int size = sizeof(*cmd) + len; - - cmd = malloc(size); - fio_init_net_cmd(cmd, FIO_NET_CMD_TEXT, buf, len); - fio_net_cmd_crc(cmd); - - fio_send_data(server_fd, cmd, size); - free(cmd); - return size; + return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len); } int fio_server_log(const char *format, ...) diff --git a/server.h b/server.h index 73e00a5c..c85f1bcc 100644 --- a/server.h +++ b/server.h @@ -23,14 +23,15 @@ enum { FIO_SERVER_VER = 1, FIO_SERVER_VER1 = 1, - FIO_SERVER_MAX_PDU = 4096, + FIO_SERVER_MAX_PDU = 64, FIO_NET_CMD_QUIT = 1, FIO_NET_CMD_JOB = 2, - FIO_NET_CMD_JOB_END = 3, - FIO_NET_CMD_ACK = 4, - FIO_NET_CMD_NAK = 5, - FIO_NET_CMD_TEXT = 6, + FIO_NET_CMD_ACK = 3, + FIO_NET_CMD_NAK = 4, + FIO_NET_CMD_TEXT = 5, + + FIO_NET_CMD_F_MORE = 1, /* crc does not include the crc fields */ FIO_NET_CMD_CRC_SZ = sizeof(struct fio_net_cmd) - @@ -40,6 +41,7 @@ enum { extern int fio_server(void); extern int fio_server_text_output(const char *, unsigned int len); extern int fio_server_log(const char *format, ...); +extern int fio_net_send_cmd(int, uint16_t, const char *, off_t); extern int fio_client_connect(const char *); extern int fio_client_send_ini(const char *); -- 2.25.1