int nbs_pack_envelope(void *packet, unsigned int dataid, size_t data_size){ /* * The envelope of the data packet contains: * * 4 bytes for the data id * 4 bytes for the size * 4 bytes for the checksum of the data[] * the data[] (see the function above for the case of fpath or nbs.c for * the case of the file content.) * * This function assumes that all the packet data is already * stored in &packet[NBS_ENVELOPE_SIZE] and then it fills the envelope. */ unsigned char *p; unsigned char *data; uint32_t checksum = 0; p = (unsigned char*)packet; data = &p[NBS_ENVELOPE_SIZE]; pack_uint32(p, dataid, 0); pack_uint32(p, data_size, 4); checksum = calc_checksum(data, data_size); pack_uint32(p, checksum, 8); return(0); }
static int try_serverlist(struct emwin_packet *ep, char *bbdata, int bbdata_size){ /* * See if the packet is actually a server list. * Some packets contain what seems to be a server list formatted * something like * * /ServerList/<ip:port>|<ip:port>|...|\ServerList\/SatServers/\SatServers\ * * i.e., an empty "SatServers". * * This function returns 0, or 2 if the packet does not contain a * server list. */ /* * First unxor the bbdata. Stricly speaking, the serverlist packet * is transmitted as a variable length packet and the clients have * to detect the end, as we have done (in bb_read_srvlist()). */ memset(ep->rawdata, '\0', EMWIN_PACKET_SIZE); memset(ep->bbdata, 0xff, EMWIN_PACKET_SIZE); memcpy(ep->bbdata, bbdata, bbdata_size); bb_xor(ep->rawdata, bbdata, bbdata_size); ep->bbdata_size = bbdata_size; ep->rawdata_size = bbdata_size; /* * Check if it looks like a server list */ if(strncmp(ep->rawdata, "/ServerList/", 12) != 0) return(2); /* * Fill out the entries that will be sent to the * client queues. */ memcpy(&ep->queue_data_v1[EMWIN_QUEUE_ENVELOPE_SIZE], ep->bbdata, ep->bbdata_size); pack_uint32(ep->queue_data_v1, (uint32_t)ep->bbdata_size, 0); ep->queue_data_v1_size = EMWIN_QUEUE_ENVELOPE_SIZE + ep->bbdata_size; memcpy(&ep->queue_data_v2[EMWIN_QUEUE_ENVELOPE_SIZE], ep->bbdata, ep->bbdata_size); pack_uint32(ep->queue_data_v2, (uint32_t)ep->bbdata_size, 0); ep->queue_data_v2_size = EMWIN_QUEUE_ENVELOPE_SIZE + ep->bbdata_size; return(0); }
static int fill_packet_struct_serial(struct emwin_packet *ep, char *serialdata, int datasize){ int i; char *fmt = "/PF%12s /PN %d /PT %d /CS %d /FD%22c"; char *b; /* * This (ep->bbdata) is the bb stuff that we get and what we will retransmit. * We should really retransmit the cleaned stuff (but of course * that would not a BB server). * * Note: Encrypt the data portion as well as the first and last six bytes. * If those should not be encrypted, then the loop below should read * * memset(ep->bbdata, '\0', EMWIN_PACKET_SIZE); * for(i = EMWIN_NULLPAD_SIZE; * i < datasize - EMWIN_NULLPAD_SIZE; ++i){ * ep->bbdata[i] = serialdata[i] ^ 0xff; * } */ /* bb_xor(ep->bbdata, serialdata, data_size); */ for(i = 0; i < datasize; ++i){ ep->bbdata[i] = serialdata[i] ^ 0xff; } ep->bbdata_size = datasize; /* * Get rid of the initial and final 6 NULL's that are always present. */ datasize -= EMWIN_NULLPAD_SIZE * 2; for(i = 0; i < datasize; ++i){ ep->rawdata[i] = serialdata[i + EMWIN_NULLPAD_SIZE]; } ep->rawdata_size = datasize; /* * let ep->data point to the real data. */ ep->data = &(ep->rawdata[EMWIN_HEADER_SIZE]); ep->data_size = datasize - EMWIN_HEADER_SIZE; /* * Form the V1 and V2 queue packets, as for the network case. */ memcpy(&ep->queue_data_v1[EMWIN_QUEUE_ENVELOPE_SIZE], ep->bbdata, ep->bbdata_size); pack_uint32(ep->queue_data_v1, (uint32_t)ep->bbdata_size, 0); ep->queue_data_v1_size = EMWIN_QUEUE_ENVELOPE_SIZE + ep->bbdata_size; if((g.serverprotocol == PROTOCOL_EMWIN1) || (build_queue_data_v2(ep) != 0) || (ep->compress_ratio >= g.min_compress_ratio)){ memcpy(&ep->queue_data_v2[EMWIN_QUEUE_ENVELOPE_SIZE], ep->bbdata, ep->bbdata_size); pack_uint32(ep->queue_data_v2, (uint32_t)ep->bbdata_size, 0); ep->queue_data_v2_size = EMWIN_QUEUE_ENVELOPE_SIZE + ep->bbdata_size; } update_stats_frames_received((unsigned int)ep->bbdata_size); i = sscanf(ep->rawdata, fmt, ep->header.filename, &ep->header.blockno, &ep->header.numblocks, &ep->header.checksum, &ep->header.dtstamp); /* * log_info("%d of %d", ep->header.blockno, ep->header.numblocks); */ if(i < 5){ update_stats_frames(1); return(2); /* error in header format */ } ep->header.dtstamp[EMWIN_TIMESTAMP_LEN - 1] = '\0'; if(checksum(ep) != 0){ update_stats_frames(1); return(3); } /* * This next function checks the file name and also converts it * to lower case. */ if(checkfilename(ep) != 0){ update_stats_frames(1); return(4); } /* * Sometimes, if the 1024 block does not contain enough data, * it is filled with NULL's. We get rid of them, but only if * it is txt file. */ if(is_text_file(ep->header.filename)){ b = &(ep->data[0]); i = 0; while((*b != '\0') && (i < ep->data_size)){ ++i; ++b; } ep->data_size = i; } update_stats_frames(0); return(0); }
static int fill_packet_struct_bb(struct emwin_packet *ep, char *bbdata, int datasize){ /* * The width of the string fields in fmt depend on what is defined * in emwin.h, for the length of the file name and the time stamp. * If the file name has exactly 12 characters this format PF%12s/PN is * correct. But if it has less, and the rest are blanks, the /PN * will not match. For that reason we write it as "PF%12s /PN" * because that space before the /PN is actually discarded. */ int i; /* char *fmt = "/PF%12s/PN %d /PT %d /CS %d /FD%31s"; */ char *fmt = "/PF%12s /PN %d /PT %d /CS %d /FD%22c"; char *b; /* * This (ep->bbdata) is the bb stuff that we get and what we will retransmit. * We should really retransmit the cleaned stuff (but of course * that would not a BB server). On the other hand, if we retransmit * just the cleaned data (and write the program to be prepared * to get the data as such) we can reduce bandwidth significantly * by eliminating the transmission of unnecessary stuff * (NULL's, padding, etc) that these packets contain. */ memcpy(ep->bbdata, bbdata, datasize); ep->bbdata_size = datasize; /* * Get the unxored header + data block. * Get rid of the initial and final 6 NULL's * that are always present, and decode each character. * ep->rawdata then contains the unxored header + data block. */ datasize -= (EMWIN_NULLPAD_SIZE * 2); for(i = 0; i < datasize; ++i){ ep->rawdata[i] = bbdata[i + EMWIN_NULLPAD_SIZE] ^ 0xff; } ep->rawdata_size = datasize; /* * ep->data points to the start of the data block. */ ep->data = &(ep->rawdata[EMWIN_HEADER_SIZE]); ep->data_size = datasize - EMWIN_HEADER_SIZE; /* * The V1 queue packet is just the bbdata, prepended by the size. The V2 * depends on the raw (unxored) data. */ memcpy(&ep->queue_data_v1[EMWIN_QUEUE_ENVELOPE_SIZE], ep->bbdata, ep->bbdata_size); pack_uint32(ep->queue_data_v1, (uint32_t)ep->bbdata_size, 0); ep->queue_data_v1_size = EMWIN_QUEUE_ENVELOPE_SIZE + ep->bbdata_size; /* * For V2 we use the function in v2.c. If it fails, fall back to a V1 * style queue packet as above. * * Moreover, if the configuration has specified a V1 only server, V2 clients * get V1 packages only. */ if((g.serverprotocol == PROTOCOL_EMWIN1) || (build_queue_data_v2(ep) != 0) || (ep->compress_ratio >= g.min_compress_ratio)){ memcpy(&ep->queue_data_v2[EMWIN_QUEUE_ENVELOPE_SIZE], ep->bbdata, ep->bbdata_size); pack_uint32(ep->queue_data_v2, (uint32_t)ep->bbdata_size, 0); ep->queue_data_v2_size = EMWIN_QUEUE_ENVELOPE_SIZE + ep->bbdata_size; } update_stats_frames_received((unsigned int)ep->bbdata_size); /* * Get the elements of the header. */ i = sscanf(ep->rawdata, fmt, ep->header.filename, &ep->header.blockno, &ep->header.numblocks, &ep->header.checksum, &ep->header.dtstamp); if(i < 5){ update_stats_frames(1); return(2); /* error in header format */ } ep->header.dtstamp[EMWIN_TIMESTAMP_LEN - 1] = '\0'; if(checksum(ep) != 0){ update_stats_frames(1); return(3); } /* * This next function checks the file name and also converts it * to lower case. */ if(checkfilename(ep) != 0){ update_stats_frames(1); return(4); } /* * log_verbose("%s: %d of %d", ep->header.filename, * ep->header.blockno, ep->header.numblocks); */ /* * Sometimes, if the 1024 block does not contain enough data, * it is filled with NULL's. We get rid of them, but only if * it is txt file. */ if(is_text_file(ep->header.filename)){ b = &(ep->data[0]); i = 0; while((*b != '\0') && (i < ep->data_size)){ ++i; ++b; } ep->data_size = i; } update_stats_frames(0); return(0); }
unsigned int MetaServerPacket::addPacketData(uint32_t i) { unsigned int ret_off = m_writePtr - m_headPtr; m_writePtr = pack_uint32(i,m_writePtr); return ret_off; }
static int onclose (WSPipeOut * pipeout, WSClient * client) { uint32_t hsize = sizeof (uint32_t) * 3; char *hdr = calloc (hsize, sizeof (char)); char *ptr = hdr; ptr += pack_uint32 (ptr, client->listener); ptr += pack_uint32 (ptr, 0x08); ptr += pack_uint32 (ptr, 0); ws_write_fifo (pipeout, hdr, hsize); free (hdr); return 0; }
/* Callback once a new connection is established * * It writes to a named pipe a header containing the socket, the * message type, the payload's length and the actual payload */ static int onopen (WSPipeOut * pipeout, WSClient * client) { uint32_t hsize = sizeof (uint32_t) * 3; char *hdr = calloc (hsize, sizeof (char)); char *ptr = hdr; ptr += pack_uint32 (ptr, client->listener); ptr += pack_uint32 (ptr, WS_OPCODE_TEXT); ptr += pack_uint32 (ptr, INET6_ADDRSTRLEN); ws_write_fifo (pipeout, hdr, hsize); ws_write_fifo (pipeout, client->remote_ip, INET6_ADDRSTRLEN); free (hdr); return 0; }
virtual void pack(std::vector<uint8_t>& bytes) const { bytes.clear(); bytes.resize(12); pack_int32(testInt, &(bytes[0])); pack_uint32(testUint, &(bytes[4])); pack_float32(testFloat, &(bytes[8])); }
void metaserver_terminate(int sockfd, const SA *servaddr, socklen_t servlen) { char mesg[MAXLINE]; unsigned int packet_size=0; pack_uint32(TERMINATE, mesg, &packet_size); Sendto(sockfd, mesg, packet_size, 0, servaddr, servlen); }
/* Pack the JSON data into a network byte order and writes it to a * pipe. * * On success, 0 is returned . */ int broadcast_holder (int fd, const char *buf, int len) { char *p = NULL, *ptr = NULL; p = calloc (sizeof (uint32_t) * 3, sizeof (char)); ptr = p; ptr += pack_uint32 (ptr, 0); ptr += pack_uint32 (ptr, 0x01); ptr += pack_uint32 (ptr, len); write_holder (fd, p, sizeof (uint32_t) * 3); write_holder (fd, buf, len); free (p); return 0; }
/* Pack the JSON data into a network byte order and write it to a * pipe. * * On success, 0 is returned . */ int send_holder_to_client (int fd, int listener, const char *buf, int len) { char *p = NULL, *ptr = NULL; p = calloc (sizeof (uint32_t) * 3, sizeof (char)); ptr = p; ptr += pack_uint32 (ptr, listener); ptr += pack_uint32 (ptr, 0x01); ptr += pack_uint32 (ptr, len); write_holder (fd, p, sizeof (uint32_t) * 3); write_holder (fd, buf, len); free (p); return 0; }
static int onmessage (WSPipeOut * pipeout, WSClient * client) { WSMessage **msg = &client->message; uint32_t hsize = sizeof (uint32_t) * 3; char *hdr = NULL, *ptr = NULL; hdr = calloc (hsize, sizeof (char)); ptr = hdr; ptr += pack_uint32 (ptr, client->listener); ptr += pack_uint32 (ptr, (*msg)->opcode); ptr += pack_uint32 (ptr, (*msg)->payloadsz); ws_write_fifo (pipeout, hdr, hsize); ws_write_fifo (pipeout, (*msg)->payload, (*msg)->payloadsz); free (hdr); return 0; }
int message_serialize_response(struct message_response *res, msgpack_packer *pk) { if (!pk || !res) return (-1); msgpack_pack_array(pk, 4); pack_uint8(pk, MESSAGE_TYPE_RESPONSE); pack_uint32(pk, res->msgid); pack_nil(pk); if (pack_params(pk, res->params) == -1) return (-1); return (0); }
void MetaServerPacket::setPacketType(const NetMsgType& nmt) { /** * */ m_packetPayload.fill(0); m_readPtr = m_packetPayload.data(); m_writePtr = m_packetPayload.data(); m_Bytes = 0; // write must occur prior to read m_writePtr = pack_uint32(nmt, m_writePtr); parsePacketType(); }
int message_serialize_request(struct message_request *req, msgpack_packer *pk) { if (!pk || !req) return (-1); msgpack_pack_array(pk, 4); pack_uint8(pk, MESSAGE_TYPE_REQUEST); pack_uint32(pk, req->msgid); if (req->method.str == NULL || (pack_string(pk, req->method) == -1)) return (-1); if (pack_params(pk, req->params) == -1) return (-1); return (0); }
int message_serialize_error_response(msgpack_packer *pk, struct api_error *api_error, uint32_t msgid) { struct message_object *err_data; array err_array; if (!pk || !api_error || !api_error->isset) return (-1); msgpack_pack_array(pk, 4); pack_uint8(pk, MESSAGE_TYPE_RESPONSE); pack_uint32(pk, msgid); err_array.size = 2; err_array.obj = CALLOC(2, struct message_object); if (!err_array.obj) { LOG_WARNING("Couldn't allocate memory for err_array object"); return (-1); } err_data = &err_array.obj[0]; err_data->type = OBJECT_TYPE_INT; err_data->data.integer = api_error->type; err_data = &err_array.obj[1]; err_data->type = OBJECT_TYPE_STR; err_data->data.string = cstring_to_string(api_error->msg); if (!err_data->data.string.str) { LOG_WARNING("Couldn't allocate memory for string in err_array object"); return (-1); } if (pack_params(pk, err_array) == -1) return (-1); pack_nil(pk); FREE(err_array.obj); return (0); }
void metaserver_keepalive(int sockfd, const SA *servaddr, socklen_t servlen) { char mesg[MAXLINE]; char *mesg_ptr; uint32_t handshake=0, command=0; SA addr; socklen_t addrlen; unsigned int packet_size; packet_size = 0; mesg_ptr = pack_uint32(SKEEP_ALIVE, mesg, &packet_size); Sendto(sockfd, mesg, packet_size, 0, servaddr, servlen); addrlen = sizeof(addr); Recvfrom(sockfd, mesg, MAXLINE, 0, &addr, &addrlen); mesg_ptr = unpack_uint32(&command, mesg); if(command == HANDSHAKE) { mesg_ptr = unpack_uint32(&handshake, mesg_ptr); printf("Server contacted successfully.\n"); packet_size = 0; mesg_ptr = pack_uint32(SERVERSHAKE, mesg, &packet_size); mesg_ptr = pack_uint32(handshake, mesg_ptr, &packet_size); Sendto(sockfd, mesg, packet_size, 0, servaddr, servlen); } }