/* * _cerebrod_message_check_version * * Check that the version is correct prior to unmarshalling * * Returns 0 if version is correct, -1 if not */ static int _cerebrod_message_check_version(const char *buf, unsigned int buflen) { int32_t version; if (!Unmarshall_int32(&version, buf, buflen)) return -1; if (version != CEREBROD_MESSAGE_PROTOCOL_VERSION) return -1; return 0; }
/* * _event_server_request_check_version * * Check that the version is correct prior to unmarshalling * * Returns 0 if version is correct, -1 if not */ static int _event_server_request_check_version(const char *buf, unsigned int buflen, int32_t *version) { assert(buflen >= sizeof(int32_t) && version); if (!Unmarshall_int32(version, buf, buflen)) { CEREBROD_DBG(("version could not be unmarshalled")); return -1; } if (*version != CEREBRO_EVENT_SERVER_PROTOCOL_VERSION) return -1; return 0; }
/* * _event_server_request_unmarshall * * unmarshall contents of a event server request packet buffer * * Returns 0 on success, -1 on error */ static int _event_server_request_unmarshall(struct cerebro_event_server_request *req, const char *buf, unsigned int buflen) { int bufPtrlen, c = 0; char *bufPtr; assert(req && buf); bufPtr = req->event_name; bufPtrlen = sizeof(req->event_name); c += Unmarshall_int32(&(req->version), buf + c, buflen - c); c += Unmarshall_buffer(bufPtr, bufPtrlen, buf + c, buflen - c); c += Unmarshall_u_int32(&(req->flags), buf + c, buflen - c); if (c != CEREBRO_EVENT_SERVER_REQUEST_PACKET_LEN) return -1; return 0; }
/* * _cerebrod_message_unmarshall * * unmarshall contents of a message packet buffer and * return in an allocated message * * Returns message data on success, NULL on error */ static struct cerebrod_message * _cerebrod_message_unmarshall(const char *buf, unsigned int buflen) { struct cerebrod_message *msg = NULL; struct cerebrod_message_metric *mm = NULL; unsigned int size; char *bufPtr; int i, n, bufPtrlen, c = 0; assert(buf); msg = Malloc(sizeof(struct cerebrod_message)); memset(msg, '\0', sizeof(struct cerebrod_message)); if (!(n = Unmarshall_int32(&(msg->version), buf + c, buflen - c))) goto cleanup; c += n; bufPtr = msg->nodename; bufPtrlen = sizeof(msg->nodename); if (!(n = Unmarshall_buffer(bufPtr, bufPtrlen, buf + c, buflen - c))) goto cleanup; c += n; if (!(n = Unmarshall_u_int32(&(msg->metrics_len), buf + c, buflen - c))) goto cleanup; c += n; /* If no metrics in this packet, just return with the header */ if (!msg->metrics_len) { if (buflen != CEREBROD_MESSAGE_HEADER_LEN) { CEREBROD_DBG(("invalid packet length for no metrics")); goto cleanup; } msg->metrics = NULL; return msg; } size = sizeof(struct cerebrod_message_metric *)*(msg->metrics_len + 1); msg->metrics = Malloc(size); memset(msg->metrics, '\0', size); for (i = 0; i < msg->metrics_len; i++) { char *mname; int mnamelen; mm = Malloc(sizeof(struct cerebrod_message_metric)); memset(mm, '\0', sizeof(struct cerebrod_message_metric)); mname = mm->metric_name; mnamelen = sizeof(mm->metric_name); if (!(n = Unmarshall_buffer(mname, mnamelen, buf + c, buflen - c))) goto cleanup; c += n; if ((n = unmarshall_data_type_len(&(mm->metric_value_type), &(mm->metric_value_len), buf + c, buflen - c, NULL)) < 0) goto cleanup; c += n; if (check_data_type_len(mm->metric_value_type, mm->metric_value_len) < 0) goto cleanup; mm->metric_value = NULL; if (mm->metric_value_len) { mm->metric_value = Malloc(mm->metric_value_len); if ((n = unmarshall_data_value(mm->metric_value_type, mm->metric_value_len, mm->metric_value, mm->metric_value_len, buf + c, buflen - c, NULL)) < 0) goto cleanup; c += n; } msg->metrics[i] = mm; } mm = NULL; return msg; cleanup: if (mm) { if (mm->metric_value) Free(mm->metric_value); Free(mm); } if (msg) { if (msg->metrics) { i = 0; while (msg->metrics[i]) { if (msg->metrics[i]->metric_value) Free(msg->metrics[i]->metric_value); Free(msg->metrics[i]); i++; } Free(msg->metrics); } Free(msg); } return NULL; }