Example #1
0
int process_get_public_key(CLIENT *client, const VCRYPT_PACKET *packet)
{
	MYSQL_RES *res = db_select("select public_key from users where username=%s",
			packet->username);

	VCRYPT_PACKET *ret_packet;

	if (res) {
		MYSQL_ROW row = mysql_fetch_row(res);
		unsigned long *lengths = mysql_fetch_lengths(res);

		if (row) {
			if (row[0]) {
				ret_packet = packet_new(DEST_SERVER, NULL, RESP_OK, lengths[0]);
				memcpy(ret_packet->payload, row[0], lengths[0]);
			} else {
				ret_packet = packet_new(DEST_SERVER, NULL, RESP_PUBLIC_KEY_NONE,
						0);
			}
		} else {
			ret_packet = packet_new(DEST_SERVER, NULL, RESP_ERR_NOSUCHUSER, 0);
		}
	} else {
		ret_packet = packet_new(DEST_SERVER, NULL, RESP_ERR_TEMPORARY, 0);
	}

	ret_packet->queue_id = packet->queue_id;
	int retval = packet_send_client(client, ret_packet);
	packet_free(ret_packet);
	return retval;
}
Example #2
0
packet_t *
create_arp_request(netif_t *netif, uint16_t vid, mac_address_t *peer_mac, ipv4_address_t *peer_ipv4)
{
    packet_t                       *packet                  = packet_new();
    ethernet_header_t              *ether                   = ethernet_header_new();
    arp_header_t                   *arp                     = arp_header_new();
    
    /* Ethernet */
    packet->head                                            = (header_t *) ether;
    ether->dest                                             = *peer_mac;
    ether->src                                              = netif->mac;
    ether->type                                             = ETHERTYPE_VLAN;
    
    /* VLAN */
    ether->vlan.vid                                         = vid;
    ether->vlan.dei                                         = 0;
    ether->vlan.pcp                                         = 5;
    ether->vlan.type                                        = ETHERTYPE_ARP;
    
    /* ARP */
    ether->header.next                                      = (header_t *) arp;
    arp->htype                                              = ARP_HTYPE_ETHERNET;   /* Hardware type (HTYPE)            */
    arp->ptype                                              = ARP_PTYPE_IPV4;       /* Protocol type (PTYPE)            */
    arp->hlen                                               = ARP_HLEN_ETHERNET;    /* Hardware address length (HLEN)   */
    arp->plen                                               = ARP_PLEN_IPV4;        /* Protocol address length (PLEN)   */
    arp->oper                                               = ARP_OPER_REQUEST;     /* Operation (OPER)                 */
    arp->sha                                                = netif->mac;           /* Sender hardware address (SHA)    */
    arp->spa                                                = netif->ipv4->address; /* Sender protocol address (SPA)    */
    arp->tha                                                = MAC_ADDRESS_NULL;     /* Target hardware address (THA)    */
    arp->tpa                                                = *peer_ipv4;           /* Target protocol address (TPA)    */
    
    return packet;
}
Example #3
0
// list of packet->next from key:[{},{}]
packet_t packet_get_packets(packet_t p, char *key)
{
  int i;
  packet_t parr, pent, plast, pret = NULL;
  if(!p || !key) return NULL;

  parr = packet_get_packet(p, key);
  if(!parr || *parr->json != '[')
  {
    packet_free(parr);
    return NULL;
  }

  // parse each object in the array, link together
	for(i=0;parr->js[i];i+=2)
	{
    pent = packet_new();
    packet_json(pent, parr->json+parr->js[i], parr->js[i+1]);
    if(!pret) pret = pent;
    else plast->next = pent;
    plast = pent;
	}

  packet_free(parr);
  return pret;
}
Example #4
0
Packet* packet_mouse_up_new(double x, double y)
{
	Packet* packet = packet_new(PACKET_TYPE_MOUSE_UP);
	packet_add_double(packet, x, MOUSE_UP_X);
	packet_add_double(packet, y, MOUSE_UP_Y);
	return packet;
}
Example #5
0
Packet* packet_mouse_move_new(double x, double y)
{
	Packet* packet = packet_new(PACKET_TYPE_MOUSE_MOVE);
	packet_add_double(packet, x, MOUSE_MOVE_X);
	packet_add_double(packet, y, MOUSE_MOVE_Y);
	return packet;
}
Example #6
0
packet_t packet_parse(unsigned char *raw, unsigned short len)
{
  packet_t p;
  uint16_t nlen, jlen;

  // make sure is at least size valid
  if(!raw || len < 2) return NULL;
  memcpy(&nlen,raw,2);
  jlen = platform_short(nlen);
  if(jlen > len-2) return NULL;

  // copy in and update pointers
  p = packet_new();
  if(!(p->raw = realloc(p->raw,len))) return packet_free(p);
  memcpy(p->raw,raw,len);
  p->json_len = jlen;
  p->json = p->raw+2;
  p->body_len = len-(2+p->json_len);
  p->body = p->raw+(2+p->json_len);
  
  // parse json (if any) and validate
  if(jlen >= 2 && js0n(p->json,p->json_len,p->js,JSONDENSITY)) return packet_free(p);
  
  return p;
}
Example #7
0
int check_packet_type(packet_t *packet, packet_type_t pkgType) {
	char *errorString;
	strbuffer_t *errorBuffer;

	if(packet->type != pkgType) {

		strbuffer_t *logMsg = strbuffer_new();
		strbuffer_append(logMsg, "Received packet with wrong type. Got ");
		strbuffer_append(logMsg, int_to_string(packet->type));
		strbuffer_append(logMsg, " instead of ");
		strbuffer_append(logMsg, int_to_string(pkgType));
		logger(LEVEL_ERR, logMsg->value);
		strbuffer_destroy(&logMsg);

		errorString = format_jsonrpc_error(JSONRPC_SERVER_ERROR, MSG_JSONRPC_ERRORS.server_error, "internal server error", 0);
		errorBuffer = strbuffer_new();
		strbuffer_append(errorBuffer, errorString);

		packet_t * errorPacket = packet_new();

		errorPacket->type = PKG_TYPE_OUTGOING_MESSAGE_STRING;
		errorPacket->payload.stringData = errorBuffer;
		errorPacket->transport = packet->transport;

		sendOutputMessage(errorPacket);

		return FALSE;

	}

	return TRUE;
}
Example #8
0
/*
 * Return 0 on success, if return -1 means the pkt
 * is unsupported(arp and ipv6) and will be sent later
 */
static int packet_enqueue(CompareState *s, int mode, Connection **con)
{
    ConnectionKey key;
    Packet *pkt = NULL;
    Connection *conn;

    if (mode == PRIMARY_IN) {
        pkt = packet_new(s->pri_rs.buf,
                         s->pri_rs.packet_len,
                         s->pri_rs.vnet_hdr_len);
    } else {
        pkt = packet_new(s->sec_rs.buf,
                         s->sec_rs.packet_len,
                         s->sec_rs.vnet_hdr_len);
    }

    if (parse_packet_early(pkt)) {
        packet_destroy(pkt, NULL);
        pkt = NULL;
        return -1;
    }
    fill_connection_key(pkt, &key);

    conn = connection_get(s->connection_track_table,
                          &key,
                          &s->conn_list);

    if (!conn->processing) {
        g_queue_push_tail(&s->conn_list, conn);
        conn->processing = true;
    }

    if (mode == PRIMARY_IN) {
        if (!colo_insert_packet(&conn->primary_list, pkt)) {
            error_report("colo compare primary queue size too big,"
                         "drop packet");
        }
    } else {
        if (!colo_insert_packet(&conn->secondary_list, pkt)) {
            error_report("colo compare secondary queue size too big,"
                         "drop packet");
        }
    }
    *con = conn;

    return 0;
}
Example #9
0
struct packet *new_udp_packet(int address_family,
			       enum direction_t direction,
			       u16 udp_payload_bytes,
			       char **error)
{
	struct packet *packet = NULL;  /* the newly-allocated result packet */
	struct header *udp_header = NULL;  /* the UDP header info */
	/* Calculate lengths in bytes of all sections of the packet */
	const int ip_option_bytes = 0;
	const int ip_header_bytes = (ip_header_min_len(address_family) +
				     ip_option_bytes);
	const int udp_header_bytes = sizeof(struct udp);
	const int ip_bytes =
		 ip_header_bytes + udp_header_bytes + udp_payload_bytes;

	/* Sanity-check all the various lengths */
	if (ip_option_bytes & 0x3) {
		asprintf(error, "IP options are not padded correctly "
			 "to ensure IP header is a multiple of 4 bytes: "
			 "%d excess bytes", ip_option_bytes & 0x3);
		return NULL;
	}
	assert((udp_header_bytes & 0x3) == 0);
	assert((ip_header_bytes & 0x3) == 0);

	if (ip_bytes > MAX_UDP_DATAGRAM_BYTES) {
		asprintf(error, "UDP datagram too large");
		return NULL;
	}

	/* Allocate and zero out a packet object of the desired size */
	packet = packet_new(ip_bytes);
	memset(packet->buffer, 0, ip_bytes);

	packet->direction = direction;
	packet->flags = 0;
	packet->ecn = ECN_NONE;

	/* Set IP header fields */
	set_packet_ip_header(packet, address_family, ip_bytes,
			     packet->ecn, IPPROTO_UDP);

	udp_header = packet_append_header(packet, HEADER_UDP,
					  sizeof(struct udp));
	udp_header->total_bytes = udp_header_bytes + udp_payload_bytes;

	/* Find the start of UDP section of the packet */
	packet->udp = (struct udp *) (ip_start(packet) + ip_header_bytes);

	/* Set UDP header fields */
	packet->udp->src_port	= htons(0);
	packet->udp->dst_port	= htons(0);
	packet->udp->len	= htons(udp_header_bytes + udp_payload_bytes);
	packet->udp->check	= 0;

	packet->ip_bytes = ip_bytes;
	return packet;
}
Example #10
0
Packet* packet_add_point_new(int id, double x, double y)
{
	Packet* packet = packet_new(PACKET_TYPE_ADD_POINT);
	packet_add_int(packet, id, ADD_POINT_ID);
	packet_add_double(packet, x, ADD_POINT_X);
	packet_add_double(packet, y, ADD_POINT_Y);
	return packet;
	
}
Example #11
0
packet_t packet_link(packet_t parent, packet_t child)
{
  if(!parent) parent = packet_new();
  if(!parent) return NULL;
  if(parent->chain) packet_free(parent->chain);
  parent->chain = child;
  if(child && child->chain == parent) child->chain = NULL;
  return parent;
}
Example #12
0
Packet* packet_update_new(int id, double x, double y, double theta)
{
	Packet* packet = packet_new(PACKET_TYPE_UPDATE);
	packet_add_int(packet, id, UPDATE_ID);
	packet_add_double(packet, x, UPDATE_X);
	packet_add_double(packet, y, UPDATE_Y);
	packet_add_double(packet, theta, UPDATE_ROTATION);
	return packet;
}
Example #13
0
/**
 * @brief 客户端注册账号
 *
 * @param cli    客户端
 * @param user_name 用户名
 * @param pwd 密码
 *
 * @return 
 */
int client_register(ChatClient *cli)
{
    ChatPacket *pkt = packet_new(cli->name, SERV_NAME);
    pkt->nmsg = 2;
    pkt->msg[0] = strdup(g_cmd[CMD_REGISTER]);
    pkt->msg[1] = strdup(cli->password);
    pkt->time = gettime();
    cli->pktsnd = pkt;
    return client_flush(cli);
}
Example #14
0
int send_to_client(ChatClient *cli, const char *msg, MsgType msg_type)
{
    ChatPacket *pkt = packet_new(SERV_NAME, cli->name);
    pkt->nmsg = 1;
    pkt->msg[0] = strdup(msg);
    pkt->time = gettime();
    pkt->type = get_msg_type(msg_type);
    cli->pktsnd = pkt;
    return client_flush(cli);
}
Example #15
0
/**
 * Request the server to send us an updated copy of a file.
 * @param filename
 * What to request.
 */
static void file_updates_request(char *filename)
{
    packet_struct *packet;

    file_updates_requested++;

    packet = packet_new(SERVER_CMD_REQUEST_UPDATE, 64, 64);
    packet_append_string_terminated(packet, filename);
    socket_send_packet(packet);

}
Example #16
0
packet_t packet_chain(packet_t p)
{
  packet_t np = packet_new();
  if(!np) return NULL;
  np->chain = p;
  // copy in meta-pointers for convenience
  np->to = p->to;
  np->from = p->from;
  np->out = p->out;
  return np;
}
Example #17
0
/*
 * this function builds a UDP packet and sends to the virtual node given by the
 * ip and port parameters. this function assumes that the socket is already
 * bound to a local port, no matter if that happened explicitly or implicitly.
 */
gssize udp_sendUserData(UDP* udp, gconstpointer buffer, gsize nBytes, in_addr_t ip, in_port_t port) {
	MAGIC_ASSERT(udp);

	gsize space = socket_getOutputBufferSpace(&(udp->super));
	if(space < nBytes) {
		/* not enough space to buffer the data */
		return -1;
	}

	/* break data into segments and send each in a packet */
	gsize maxPacketLength = CONFIG_DATAGRAM_MAX_SIZE;
	gsize remaining = nBytes;
	gsize offset = 0;

	/* create as many packets as needed */
	while(remaining > 0) {
		gsize copyLength = MIN(maxPacketLength, remaining);

		/* use default destination if none was specified */
		in_addr_t destinationIP = (ip != 0) ? ip : udp->super.peerIP;
		in_port_t destinationPort = (port != 0) ? port : udp->super.peerPort;

		/* create the UDP packet */
		Packet* packet = packet_new(buffer + offset, copyLength);
		packet_setUDP(packet, PUDP_NONE, socket_getBinding(&(udp->super)),
				udp->super.boundPort, destinationIP, destinationPort);

		/* buffer it in the transport layer, to be sent out when possible */
		gboolean success = socket_addToOutputBuffer((Socket*) udp, packet);

		/* counter maintenance */
		if(success) {
			remaining -= copyLength;
			offset += copyLength;
		} else {
			warning("unable to send UDP packet");
			break;
		}
	}

	/* update the tracker output buffer stats */
	Tracker* tracker = node_getTracker(worker_getPrivate()->cached_node);
	Socket* socket = (Socket* )udp;
	Descriptor* descriptor = (Descriptor *)socket;
	gsize outLength = socket_getOutputBufferLength(socket);
	gsize outSize = socket_getOutputBufferSize(socket);
	tracker_updateSocketOutputBuffer(tracker, descriptor->handle, outLength, outSize);

	debug("buffered %"G_GSIZE_FORMAT" outbound UDP bytes from user", offset);

	return (gssize) offset;
}
Example #18
0
void process_user_reqs(struct pollfd *pfd, int *ctl_fd)
{
	if (pfd->revents & POLLHUP) {
		*ctl_fd = reopen_user_chan(*ctl_fd);
		return;
	}
	struct packet *pkt = packet_new();
	int n;
	n = read(pfd->fd, pkt->pkt_data, PKT_BUFF_SIZE);
	if (n == 0)
		*ctl_fd = reopen_user_chan(*ctl_fd);
	printf("read %d bytes from user\n", n);
}
Example #19
0
/**
 * Toggle the locked status of an object.
 * @param op
 * Object.
 */
void toggle_locked(object *op)
{
    packet_struct *packet;

    /* If object is on the ground, don't lock it. */
    if (!op || !op->env || op->env->tag == 0) {
        return;
    }

    packet = packet_new(SERVER_CMD_ITEM_LOCK, 8, 0);
    packet_append_uint32(packet, op->tag);
    socket_send_packet(packet);
}
Example #20
0
Packet* packet_mouse_down_new(double x, double y, char type, char fill, double width, double r, double g, double b)
{
	Packet* packet = packet_new(PACKET_TYPE_MOUSE_DOWN);
	packet_add_double(packet, x, MOUSE_DOWN_X);
	packet_add_double(packet, y, MOUSE_DOWN_Y);
	packet_add_byte(packet, type, MOUSE_DOWN_SHAPE_TYPE);
	packet_add_byte(packet, fill, MOUSE_DOWN_FILL);
	packet_add_double(packet, width, MOUSE_DOWN_WIDTH);
	packet_add_double(packet, r, MOUSE_DOWN_R);
	packet_add_double(packet, g, MOUSE_DOWN_G);
	packet_add_double(packet, b, MOUSE_DOWN_B);
	return packet;
}
Example #21
0
// creates new packet from key:object
packet_t packet_get_packet(packet_t p, char *key)
{
  packet_t pp;
  int val;
  if(!p || !key) return NULL;

  val = j0g_val(key,(char*)p->json,p->js);
  if(!val) return NULL;

  pp = packet_new();
  packet_json(pp, p->json+p->js[val], p->js[val+1]);
  return pp;
}
Example #22
0
/* Create a new request packet. */
krb5_error_code
krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
                        const krad_attrset *set, krad_packet_iter_cb cb,
                        void *data, krad_packet **request)
{
    krb5_error_code retval;
    krad_packet *pkt;
    uchar id;
    size_t attrset_len;

    pkt = packet_new();
    if (pkt == NULL) {
        if (cb != NULL)
            (*cb)(data, TRUE);
        return ENOMEM;
    }

    /* Generate the ID. */
    retval = id_generate(ctx, cb, data, &id);
    if (retval != 0)
        goto error;
    pkt_id_set(pkt, id);

    /* Generate the authenticator. */
    retval = auth_generate_random(ctx, pkt_auth(pkt));
    if (retval != 0)
        goto error;

    /* Encode the attributes. */
    retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
                               &attrset_len);
    if (retval != 0)
        goto error;

    /* Set the code, ID and length. */
    pkt->pkt.length = attrset_len + OFFSET_ATTR;
    pkt_code_set(pkt, code);
    pkt_len_set(pkt, pkt->pkt.length);

    /* Copy the attrset for future use. */
    retval = packet_set_attrset(ctx, secret, pkt);
    if (retval != 0)
        goto error;

    *request = pkt;
    return 0;

error:
    free(pkt);
    return retval;
}
Example #23
0
File: posix.c Project: fis/mcmap
static void console_line_ready(char *line)
{
	if (line)
	{
		add_history(line);
		inject_to_server(packet_new(PACKET_CHAT_MESSAGE, line));
	}
	else /* ^D */
		exit(0);

	free(line);

	rl_callback_handler_install("> ", console_line_ready);
}
Example #24
0
Packet* packet_new_stroke_new(int id, double x, double y, char type, char fill, double width, double r, double g, double b)
{
	Packet* packet = packet_new(PACKET_TYPE_NEW_STROKE);
	packet_add_int(packet, id, NEW_STROKE_ID);
	packet_add_double(packet, x, NEW_STROKE_X);
	packet_add_double(packet, y, NEW_STROKE_Y);
	packet_add_byte(packet, type, NEW_STROKE_SHAPE_TYPE);
	packet_add_byte(packet, fill, NEW_STROKE_FILL);
	packet_add_double(packet, width, NEW_STROKE_WIDTH);
	packet_add_double(packet, r, NEW_STROKE_R);
	packet_add_double(packet, g, NEW_STROKE_G);
	packet_add_double(packet, b, NEW_STROKE_B);
	
	return packet;
}
Example #25
0
/* Create a new request packet. */
krb5_error_code
krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
                         const krad_attrset *set, const krad_packet *request,
                         krad_packet **response)
{
    krb5_error_code retval;
    krad_packet *pkt;
    size_t attrset_len;

    pkt = packet_new();
    if (pkt == NULL)
        return ENOMEM;

    /* Encode the attributes. */
    retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
                               &attrset_len);
    if (retval != 0)
        goto error;

    /* Set the code, ID and length. */
    pkt->pkt.length = attrset_len + OFFSET_ATTR;
    pkt_code_set(pkt, code);
    pkt_id_set(pkt, pkt_id_get(request));
    pkt_len_set(pkt, pkt->pkt.length);

    /* Generate the authenticator. */
    retval = auth_generate_response(ctx, secret, pkt, pkt_auth(request),
                                    pkt_auth(pkt));
    if (retval != 0)
        goto error;

    /* Copy the attrset for future use. */
    retval = packet_set_attrset(ctx, secret, pkt);
    if (retval != 0)
        goto error;

    *response = pkt;
    return 0;

error:
    free(pkt);
    return retval;
}
Example #26
0
/* Decode a packet. */
static krb5_error_code
decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer,
              krad_packet **pkt)
{
    krb5_error_code retval;
    krad_packet *tmp;
    krb5_ui_2 len;

    tmp = packet_new();
    if (tmp == NULL) {
        retval = ENOMEM;
        goto error;
    }

    /* Ensure a proper message length. */
    retval = (buffer->length < OFFSET_ATTR) ? EMSGSIZE : 0;
    if (retval != 0)
        goto error;
    len = load_16_be(offset(buffer, OFFSET_LENGTH));
    retval = (len < OFFSET_ATTR) ? EBADMSG : 0;
    if (retval != 0)
        goto error;
    retval = (len > buffer->length || len > tmp->pkt.length) ? EBADMSG : 0;
    if (retval != 0)
        goto error;

    /* Copy over the buffer. */
    tmp->pkt.length = len;
    memcpy(tmp->pkt.data, buffer->data, len);

    /* Parse the packet to ensure it is well-formed. */
    retval = packet_set_attrset(ctx, secret, tmp);
    if (retval != 0)
        goto error;

    *pkt = tmp;
    return 0;

error:
    krad_packet_free(tmp);
    return retval;
}
Example #27
0
packet_t *
create_ptp2_arp_reply(mac_address_t *arp_mac, ipv4_address_t *arp_ipv4)
{
    packet_t                       *packet                  = packet_new();
    ethernet_header_t              *ether                   = ethernet_header_new();
    arp_header_t                   *arp                     = arp_header_new();

    packet->head                                            = (header_t *) ether;
    ether->header.next                                      = (header_t *) arp;

    /* Ethernet */
    //ether->dest                                             = master_mac;
    //ether->src                                              = *slave_mac;
    ether->type                                             = ETHERTYPE_IPV4;

    /* ARP */
    

    return packet;
}
Example #28
0
/**
 * Update the marked object.
 * @param op
 * The object.
 */
void object_send_mark(object *op)
{
    packet_struct *packet;

    /* If object is on the ground, don't mark it. */
    if (!op || !op->env || op->env->tag == 0) {
        return;
    }

    if (cpl.mark_count == op->tag) {
        cpl.mark_count = 0;
    } else {
        cpl.mark_count = op->tag;
    }

    object_redraw(op);

    packet = packet_new(SERVER_CMD_ITEM_MARK, 8, 0);
    packet_append_uint32(packet, op->tag);
    socket_send_packet(packet);
}
Example #29
0
packet_t crypt_deopenize_1a(crypt_t self, packet_t open)
{
  unsigned char secret[uECC_BYTES], iv[16], b64[uECC_BYTES*2*2], hash[32];
  packet_t inner, tmp;
  crypt_1a_t cs = (crypt_1a_t)self->cs;

  if(open->body_len <= (4+40)) return NULL;
  inner = packet_new();
  if(!packet_body(inner,NULL,open->body_len-(4+40))) return packet_free(inner);

  // get the shared secret to create the iv+key for the open aes
  if(!uECC_shared_secret(open->body+4, cs->id_private, secret)) return packet_free(inner);
  crypt_hash(secret,uECC_BYTES,hash);
  fold1(hash,hash);
  memset(iv,0,16);
  iv[15] = 1;

  // decrypt the inner
  aes_128_ctr(hash,inner->body_len,iv,open->body+4+40,inner->body);

  // load inner packet
  if((tmp = packet_parse(inner->body,inner->body_len)) == NULL) return packet_free(inner);
  packet_free(inner);
  inner = tmp;

  // generate secret for hmac
  if(inner->body_len != uECC_BYTES*2) return packet_free(inner);
  if(!uECC_shared_secret(inner->body, cs->id_private, secret)) return packet_free(inner);

  // verify
  hmac_256(secret,uECC_BYTES,open->body+4,open->body_len-4,hash);
  fold3(hash,hash);
  if(memcmp(hash,open->body,4) != 0) return packet_free(inner);

  // stash the hex line key w/ the inner
  util_hex(open->body+4,40,b64);
  packet_set_str(inner,"ecc",(char*)b64);

  return inner;
}
Example #30
0
static Packet* _tcp_createPacket(TCP* tcp, enum ProtocolTCPFlags flags, gconstpointer payload, gsize payloadLength) {
	MAGIC_ASSERT(tcp);

	/*
	 * packets from children of a server must appear to be coming from the server
	 */
	in_addr_t sourceIP = tcp_getIP(tcp);
	in_port_t sourcePort = (tcp->child) ? tcp->child->parent->super.boundPort :
			tcp->super.boundPort;

	in_addr_t destinationIP = tcp_getPeerIP(tcp);
	in_port_t destinationPort = (tcp->server) ? tcp->server->lastPeerPort : tcp->super.peerPort;


	if(sourceIP == htonl(INADDR_ANY)) {
		sourceIP = node_getDefaultIP(worker_getPrivate()->cached_node);
	}

	g_assert(sourceIP && sourcePort && destinationIP && destinationPort);

	/* make sure our receive window is up to date before putting it in the packet */
	_tcp_updateReceiveWindow(tcp);

	/* control packets have no sequence number
	 * (except FIN, so we close after sending everything) */
	guint sequence = ((payloadLength > 0) || (flags & PTCP_FIN)) ? tcp->send.next : 0;

	/* create the TCP packet */
	Packet* packet = packet_new(payload, payloadLength);
	packet_setTCP(packet, flags, sourceIP, sourcePort, destinationIP, destinationPort,
			sequence, tcp->receive.next, tcp->receive.window);

	/* update sequence number */
	if(sequence > 0) {
		tcp->send.next++;
	}

	return packet;
}