diff mbox series

[1/3] trace-cmd: Use text encoding for options in protocol V3

Message ID 20190315153326.5602-2-kaslevs@vmware.com (mailing list archive)
State Accepted
Commit ab5ec1bdddefcbfb92f1f5c42f27eb29acec0c4b
Headers show
Series Switch V3 messages to text encoding of variable length buffer | expand

Commit Message

Slavomir Kaslev March 15, 2019, 3:33 p.m. UTC
Options are now encoded as text in the buffer at the end of protocol V3 messages.

Unrecognized options are logged and ignored by the listener to support adding
new options in the future.

Signed-off-by: Slavomir Kaslev <kaslevs@vmware.com>
---
 tracecmd/trace-msg.c | 82 +++++++++++++++++---------------------------
 1 file changed, 32 insertions(+), 50 deletions(-)
diff mbox series

Patch

diff --git a/tracecmd/trace-msg.c b/tracecmd/trace-msg.c
index 51d0ac8..4b43849 100644
--- a/tracecmd/trace-msg.c
+++ b/tracecmd/trace-msg.c
@@ -49,11 +49,6 @@  static inline void dprint(const char *fmt, ...)
 
 unsigned int page_size;
 
-struct tracecmd_msg_opt {
-	be32 size;
-	be32 opt_cmd;
-} __attribute__((packed));
-
 struct tracecmd_msg_tinit {
 	be32 cpus;
 	be32 page_size;
@@ -110,7 +105,6 @@  struct tracecmd_msg {
 		struct tracecmd_msg_rinit	rinit;
 	};
 	union {
-		struct tracecmd_msg_opt		*opt;
 		be32				*port_array;
 		void				*buf;
 	};
@@ -143,27 +137,17 @@  static int msg_write(int fd, struct tracecmd_msg *msg)
 	return __do_write_check(fd, msg->buf, data_size);
 }
 
-enum msg_opt_command {
-	MSGOPT_USETCP = 1,
-};
-
 static int make_tinit(struct tracecmd_msg_handle *msg_handle,
 		      struct tracecmd_msg *msg)
 {
-	struct tracecmd_msg_opt *opt;
 	int cpu_count = msg_handle->cpu_count;
 	int opt_num = 0;
 	int data_size = 0;
 
 	if (msg_handle->flags & TRACECMD_MSG_FL_USE_TCP) {
 		opt_num++;
-		opt = malloc(sizeof(*opt));
-		if (!opt)
-			return -ENOMEM;
-		opt->size = htonl(sizeof(*opt));
-		opt->opt_cmd = htonl(MSGOPT_USETCP);
-		msg->opt = opt;
-		data_size += sizeof(*opt);
+		msg->buf = strdup("tcp");
+		data_size += 4;
 	}
 
 	msg->tinit.cpus = htonl(cpu_count);
@@ -441,10 +425,10 @@  out:
 }
 
 static bool process_option(struct tracecmd_msg_handle *msg_handle,
-			   struct tracecmd_msg_opt *opt)
+			   const char *opt)
 {
-	/* currently the only option we have is to us TCP */
-	if (ntohl(opt->opt_cmd) == MSGOPT_USETCP) {
+	/* currently the only option we have is to use TCP */
+	if (strcmp(opt, "tcp") == 0) {
 		msg_handle->flags |= TRACECMD_MSG_FL_USE_TCP;
 		return true;
 	}
@@ -475,15 +459,15 @@  void tracecmd_msg_handle_close(struct tracecmd_msg_handle *msg_handle)
 
 int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle)
 {
-	struct tracecmd_msg_opt *opt;
 	struct tracecmd_msg msg;
+	char *p, *buf_end;
+	ssize_t buf_len;
 	int pagesize;
-	int options, i, s;
+	int options, i;
 	int cpus;
 	int ret;
-	int offset = 0;
-	u32 size;
 
+	memset(&msg, 0, sizeof(msg));
 	ret = tracecmd_msg_recv_wait(msg_handle->fd, &msg);
 	if (ret < 0) {
 		if (ret == -ETIMEDOUT)
@@ -512,38 +496,36 @@  int tracecmd_msg_initial_setting(struct tracecmd_msg_handle *msg_handle)
 		goto error;
 	}
 
-	size = MSG_HDR_LEN + ntohl(msg.hdr.cmd_size);
+	buf_len = ntohl(msg.hdr.size) - MSG_HDR_LEN - ntohl(msg.hdr.cmd_size);
+	if (buf_len < 0) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (buf_len == 0)
+		goto no_options;
+
+	if (((char *)msg.buf)[buf_len-1] != '\0') {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	buf_end = (char *)msg.buf + buf_len;
 	options = ntohl(msg.tinit.opt_num);
-	for (i = 0; i < options; i++) {
-		if (size + sizeof(*opt) > ntohl(msg.hdr.size)) {
-			plog("Not enough message for options\n");
+	for (i = 0, p = msg.buf; i < options; i++, p++) {
+		if (p >= buf_end) {
 			ret = -EINVAL;
 			goto error;
 		}
-		opt = (void *)msg.opt + offset;
-		offset += ntohl(opt->size);
-		size += ntohl(opt->size);
-		if (ntohl(msg.hdr.size) < size) {
-			plog("Not enough message for options\n");
-			ret = -EINVAL;
-			goto error;
-		}
-		/* prevent a client from killing us */
-		if (ntohl(opt->size) > MAX_OPTION_SIZE) {
-			plog("Exceed MAX_OPTION_SIZE\n");
-			ret = -EINVAL;
-			goto error;
-		}
-		s = process_option(msg_handle, opt);
+
 		/* do we understand this option? */
-		if (!s) {
-			plog("Cannot understand(%d:%d:%d)\n",
-			     i, ntohl(opt->size), ntohl(opt->opt_cmd));
-			ret = -EINVAL;
-			goto error;
-		}
+		if (!process_option(msg_handle, p))
+			plog("Cannot understand option '%s'\n", p);
+
+		p = strchr(p, '\0');
 	}
 
+no_options:
 	msg_free(&msg);
 	return pagesize;