void zmq::amqp_marshaller_t::connection_tune_ok ( uint16_t channel_, uint16_t channel_max_, uint32_t frame_max_, uint16_t heartbeat_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, channel_max_); offset += sizeof (uint16_t); assert (offset + sizeof (uint32_t) <= i_amqp::frame_min_size); put_uint32 (args + offset, frame_max_); offset += sizeof (uint32_t); assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, heartbeat_); offset += sizeof (uint16_t); command_t cmd = { channel_, i_amqp::connection_id, i_amqp::connection_tune_ok_id, args, offset }; command_queue.push (cmd); }
/* * send Notification payload (for ISAKMP SA) in Informational exchange */ int isakmp_info_send_n1(struct ph1handle *iph1, int type, rc_vchar_t *data) { rc_vchar_t *payload = NULL; int tlen; int error = 0; struct isakmp_pl_n *n; int spisiz; /* * note on SPI size: which description is correct? I have chosen * this to be 0. * * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by * Initiator/Responder cookie and SPI has no meaning, SPI size = 0. * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified * by cookie and SPI has no meaning, 0 <= SPI size <= 16. * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16. */ if (type == ISAKMP_NTYPE_INITIAL_CONTACT) spisiz = sizeof(isakmp_index_t); else spisiz = 0; tlen = sizeof(*n) + spisiz; if (data) tlen += data->l; payload = rc_vmalloc(tlen); if (payload == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer to send.\n"); return errno; } n = (struct isakmp_pl_n *)payload->v; n->h.np = ISAKMP_NPTYPE_NONE; put_uint16(&n->h.len, tlen); put_uint32(&n->doi, ikev1_doitype(iph1->rmconf)); n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */ n->spi_size = spisiz; put_uint16(&n->type, type); if (spisiz) memcpy(n + 1, &iph1->index, sizeof(isakmp_index_t)); if (data) memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); rc_vfree(payload); return error; }
void zmq::amqp_marshaller_t::queue_purge ( uint16_t channel_, uint16_t reserved_1_, const i_amqp::shortstr_t queue_, bool no_wait_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reserved_1_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + queue_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, queue_.size); offset += sizeof (uint8_t); memcpy (args + offset, queue_.data, queue_.size); offset += queue_.size; assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size); args [offset] = ( ((no_wait_ ? 1 : 0) << 0)); offset += sizeof (uint8_t); command_t cmd = { channel_, i_amqp::queue_id, i_amqp::queue_purge_id, args, offset }; command_queue.push (cmd); }
void zmq::amqp_marshaller_t::basic_qos ( uint16_t channel_, uint32_t prefetch_size_, uint16_t prefetch_count_, bool global_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint32_t) <= i_amqp::frame_min_size); put_uint32 (args + offset, prefetch_size_); offset += sizeof (uint32_t); assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, prefetch_count_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size); args [offset] = ( ((global_ ? 1 : 0) << 0)); offset += sizeof (uint8_t); command_t cmd = { channel_, i_amqp::basic_id, i_amqp::basic_qos_id, args, offset }; command_queue.push (cmd); }
void channel_header_pack( channel_header_t *header , unsigned char **packed , size_t *size ) { unsigned char *p = NULL; uint16_t temp_header = 0; *packed = NULL; *size = 0; if( ! header ) return; *packed = ( unsigned char *)malloc( CHANNEL_HEADER_PACKED_SIZE ); if( ! packed ) return; memset( *packed, 0, CHANNEL_HEADER_PACKED_SIZE ); p = *packed; temp_header |= ( header->S << 15 ); temp_header |= ( ( ( header->chan == 0 ? 0 : header->chan - 1 ) & 0x0f ) << 11 ); temp_header |= ( ( header->H & 0x01 ) << 10 ); temp_header |= ( ( header->len & 0x03ff ) ); put_uint16( &p, temp_header, size ); *p = header->bitfield; *size += sizeof( header->bitfield ); }
void zmq::pgm_sender_t::out_event () { // POLLOUT event from send socket. If write buffer is empty, // try to read new data from the encoder. if (write_size == 0) { // First two bytes (sizeof uint16_t) are used to store message // offset in following steps. Note that by passing our buffer to // the get data function we prevent it from returning its own buffer. unsigned char *bf = out_buffer + sizeof (uint16_t); size_t bfsz = out_buffer_size - sizeof (uint16_t); int offset = -1; encoder.get_data (&bf, &bfsz, &offset); // If there are no data to write stop polling for output. if (!bfsz) { reset_pollout (handle); return; } // Put offset information in the buffer. write_size = bfsz + sizeof (uint16_t); put_uint16 (out_buffer, offset == -1 ? 0xffff : (uint16_t) offset); } // Send the data. size_t nbytes = pgm_socket.send (out_buffer, write_size); // We can write either all data or 0 which means rate limit reached. if (nbytes == write_size) write_size = 0; else zmq_assert (nbytes == 0); }
int zmq::null_mechanism_t::next_handshake_command (msg_t *msg_) { if (ready_command_sent) { errno = EAGAIN; return -1; } if (zap_connected && !zap_reply_received) { if (zap_request_sent) { errno = EAGAIN; return -1; } send_zap_request (); zap_request_sent = true; const int rc = receive_and_process_zap_reply (); if (rc != 0) return -1; zap_reply_received = true; } unsigned char * const command_buffer = (unsigned char *) malloc (512); alloc_assert (command_buffer); unsigned char *ptr = command_buffer; // Add mechanism string memcpy (ptr, "\5READY", 6); ptr += 6; // Add socket type property const char *socket_type = socket_type_string (options.type); ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type)); // Add identity property if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER || options.type == ZMQ_ROUTER) { ptr += add_property (ptr, "Identity", options.identity, options.identity_size); } // Add keepalive property, with 16 bit value in tenths of a second unsigned char keepalive_ivl_nbo[2]; put_uint16 (keepalive_ivl_nbo, static_cast <uint16_t> (options.keepalive_ivl / 100)); ptr += add_property (ptr, "Keepalive", keepalive_ivl_nbo, sizeof(keepalive_ivl_nbo)); const size_t command_size = ptr - command_buffer; const int rc = msg_->init_size (command_size); errno_assert (rc == 0); memcpy (msg_->data (), command_buffer, command_size); free (command_buffer); ready_command_sent = true; return 0; }
zmq::zmq_init_t::zmq_init_t (io_thread_t *io_thread_, socket_base_t *socket_, session_t *session_, fd_t fd_, const options_t &options_) : own_t (io_thread_, options_), ephemeral_engine (NULL), received (false), socket (socket_), session (session_), io_thread (io_thread_) { // Create the engine object for this connection. engine = new (std::nothrow) zmq_engine_t (fd_, options); alloc_assert (engine); // Generate an unique identity. unsigned char identity [uuid_t::uuid_blob_len + 1]; identity [0] = 0; memcpy (identity + 1, uuid_t ().to_blob (), uuid_t::uuid_blob_len); peer_identity.assign (identity, uuid_t::uuid_blob_len + 1); // Create a list of props to send. zmq_msg_t msg; int rc = zmq_msg_init_size (&msg, 4); errno_assert (rc == 0); unsigned char *data = (unsigned char*) zmq_msg_data (&msg); put_uint16 (data, prop_type); put_uint16 (data + 2, options.type); msg.flags |= ZMQ_MSG_MORE; to_send.push_back (msg); if (!options.identity.empty ()) { rc = zmq_msg_init_size (&msg, 2 + options.identity.size ()); errno_assert (rc == 0); data = (unsigned char*) zmq_msg_data (&msg); put_uint16 (data, prop_identity); memcpy (data + 2, options.identity.data (), options.identity.size ()); msg.flags |= ZMQ_MSG_MORE; to_send.push_back (msg); } // Remove the MORE flag from the last prop. to_send.back ().flags &= ~ZMQ_MSG_MORE; }
/* * add a notify payload to buffer by reallocating buffer. * If buf == NULL, the function only create a notify payload. * * XXX Which is SPI to be included, inbound or outbound ? */ rc_vchar_t * isakmp_add_pl_n(rc_vchar_t *buf0, uint8_t **np_p, int type, struct saproto *pr, rc_vchar_t *data) { rc_vchar_t *buf = NULL; struct isakmp_pl_n *n; int tlen; int oldlen = 0; if (*np_p) **np_p = ISAKMP_NPTYPE_N; tlen = sizeof(*n) + pr->spisize; if (data) tlen += data->l; if (buf0) { oldlen = buf0->l; buf = rc_vrealloc(buf0, buf0->l + tlen); } else buf = rc_vmalloc(tlen); if (!buf) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get a payload buffer.\n"); return NULL; } n = (struct isakmp_pl_n *)(buf->v + oldlen); n->h.np = ISAKMP_NPTYPE_NONE; put_uint16(&n->h.len, tlen); put_uint32(&n->doi, IPSEC_DOI); /* IPSEC DOI (1) */ n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ n->spi_size = pr->spisize; put_uint16(&n->type, type); memcpy((uint8_t *)(n + 1), &pr->spi, pr->spisize); if (data) memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); /* save the pointer of next payload type */ *np_p = &n->h.np; return buf; }
/* * send Notification payload (for IPsec SA) in Informational exchange */ int isakmp_info_send_n2(struct ph2handle *iph2, int type, rc_vchar_t *data) { struct ph1handle *iph1 = iph2->ph1; rc_vchar_t *payload = NULL; int tlen; int error = 0; struct isakmp_pl_n *n; struct saproto *pr; if (!iph2->approval) return EINVAL; pr = iph2->approval->head; /* XXX must be get proper spi */ tlen = sizeof(*n) + pr->spisize; if (data) tlen += data->l; payload = rc_vmalloc(tlen); if (payload == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer to send.\n"); return errno; } n = (struct isakmp_pl_n *)payload->v; n->h.np = ISAKMP_NPTYPE_NONE; put_uint16(&n->h.len, tlen); put_uint32(&n->doi, IPSEC_DOI); /* IPSEC DOI (1) */ n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ n->spi_size = pr->spisize; put_uint16(&n->type, type); memcpy((uint8_t *)(n + 1), &pr->spi, pr->spisize); if (data) memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */ error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags); rc_vfree(payload); return error; }
size_t zmq::bp_pgm_sender_t::write_one_pkt_with_offset (unsigned char *data_, size_t size_, uint16_t offset_) { // Put offset information in the buffer. put_uint16 (data_, offset_); // Send data. size_t nbytes = pgm_socket.send_data (data_, size_); return nbytes; }
int xs::sub_t::filter_unsubscribed (const unsigned char *data_, size_t size_) { // Create the unsubscription message. msg_t msg; int rc = msg.init_size (size_ + 4); errno_assert (rc == 0); unsigned char *data = (unsigned char*) msg.data (); put_uint16 (data, XS_CMD_UNSUBSCRIBE); put_uint16 (data + 2, options.filter); memcpy (data + 4, data_, size_); // Pass it further on in the stack. int err = 0; rc = xsub_t::xsend (&msg, 0); if (rc != 0) err = errno; int rc2 = msg.close (); errno_assert (rc2 == 0); if (rc != 0) errno = err; return rc; }
/* * send Delete payload (for ISAKMP SA) in Informational exchange. */ int isakmp_info_send_d1(struct ph1handle *iph1) { struct isakmp_pl_d *d; rc_vchar_t *payload = NULL; int tlen; int error = 0; if (iph1->status != PHASE2ST_ESTABLISHED) return 0; /* create delete payload */ /* send SPIs of inbound SAs. */ /* XXX should send outbound SAs's ? */ tlen = sizeof(*d) + sizeof(isakmp_index_t); payload = rc_vmalloc(tlen); if (payload == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer for payload.\n"); return errno; } d = (struct isakmp_pl_d *)payload->v; d->h.np = ISAKMP_NPTYPE_NONE; put_uint16(&d->h.len, tlen); put_uint32(&d->doi, IPSEC_DOI); d->proto_id = IPSECDOI_PROTO_ISAKMP; d->spi_size = sizeof(isakmp_index_t); put_uint16(&d->num_spi, 1); memcpy(d + 1, &iph1->index, sizeof(isakmp_index_t)); error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_D, 0); rc_vfree(payload); return error; }
void zmq::amqp_marshaller_t::exchange_declare ( uint16_t channel_, uint16_t reserved_1_, const i_amqp::shortstr_t exchange_, const i_amqp::shortstr_t type_, bool passive_, bool durable_, bool reserved_2_, bool reserved_3_, bool no_wait_, const i_amqp::field_table_t &arguments_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reserved_1_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + exchange_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, exchange_.size); offset += sizeof (uint8_t); memcpy (args + offset, exchange_.data, exchange_.size); offset += exchange_.size; assert (offset + sizeof (uint8_t) + type_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, type_.size); offset += sizeof (uint8_t); memcpy (args + offset, type_.data, type_.size); offset += type_.size; assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size); args [offset] = ( ((passive_ ? 1 : 0) << 0) | ((durable_ ? 1 : 0) << 1) | ((reserved_2_ ? 1 : 0) << 2) | ((reserved_3_ ? 1 : 0) << 3) | ((no_wait_ ? 1 : 0) << 4)); offset += sizeof (uint8_t); put_field_table (args, i_amqp::frame_min_size, offset, arguments_); command_t cmd = { channel_, i_amqp::exchange_id, i_amqp::exchange_declare_id, args, offset }; command_queue.push (cmd); }
void zmq::amqp_marshaller_t::queue_bind ( uint16_t channel_, uint16_t reserved_1_, const i_amqp::shortstr_t queue_, const i_amqp::shortstr_t exchange_, const i_amqp::shortstr_t routing_key_, bool no_wait_, const i_amqp::field_table_t &arguments_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reserved_1_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + queue_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, queue_.size); offset += sizeof (uint8_t); memcpy (args + offset, queue_.data, queue_.size); offset += queue_.size; assert (offset + sizeof (uint8_t) + exchange_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, exchange_.size); offset += sizeof (uint8_t); memcpy (args + offset, exchange_.data, exchange_.size); offset += exchange_.size; assert (offset + sizeof (uint8_t) + routing_key_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, routing_key_.size); offset += sizeof (uint8_t); memcpy (args + offset, routing_key_.data, routing_key_.size); offset += routing_key_.size; assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size); args [offset] = ( ((no_wait_ ? 1 : 0) << 0)); offset += sizeof (uint8_t); put_field_table (args, i_amqp::frame_min_size, offset, arguments_); command_t cmd = { channel_, i_amqp::queue_id, i_amqp::queue_bind_id, args, offset }; command_queue.push (cmd); }
void zmq::amqp_marshaller_t::channel_close ( uint16_t channel_, uint16_t reply_code_, const i_amqp::shortstr_t reply_text_, uint16_t class_id_, uint16_t method_id_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reply_code_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + reply_text_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, reply_text_.size); offset += sizeof (uint8_t); memcpy (args + offset, reply_text_.data, reply_text_.size); offset += reply_text_.size; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, class_id_); offset += sizeof (uint16_t); assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, method_id_); offset += sizeof (uint16_t); command_t cmd = { channel_, i_amqp::channel_id, i_amqp::channel_close_id, args, offset }; command_queue.push (cmd); }
void zmq::amqp_marshaller_t::basic_consume ( uint16_t channel_, uint16_t reserved_1_, const i_amqp::shortstr_t queue_, const i_amqp::shortstr_t consumer_tag_, bool no_local_, bool no_ack_, bool exclusive_, bool no_wait_, const i_amqp::field_table_t &arguments_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reserved_1_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + queue_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, queue_.size); offset += sizeof (uint8_t); memcpy (args + offset, queue_.data, queue_.size); offset += queue_.size; assert (offset + sizeof (uint8_t) + consumer_tag_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, consumer_tag_.size); offset += sizeof (uint8_t); memcpy (args + offset, consumer_tag_.data, consumer_tag_.size); offset += consumer_tag_.size; assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size); args [offset] = ( ((no_local_ ? 1 : 0) << 0) | ((no_ack_ ? 1 : 0) << 1) | ((exclusive_ ? 1 : 0) << 2) | ((no_wait_ ? 1 : 0) << 3)); offset += sizeof (uint8_t); put_field_table (args, i_amqp::frame_min_size, offset, arguments_); command_t cmd = { channel_, i_amqp::basic_id, i_amqp::basic_consume_id, args, offset }; command_queue.push (cmd); }
void zmq::amqp_marshaller_t::basic_publish ( uint16_t channel_, uint16_t reserved_1_, const i_amqp::shortstr_t exchange_, const i_amqp::shortstr_t routing_key_, bool mandatory_, bool immediate_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reserved_1_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + exchange_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, exchange_.size); offset += sizeof (uint8_t); memcpy (args + offset, exchange_.data, exchange_.size); offset += exchange_.size; assert (offset + sizeof (uint8_t) + routing_key_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, routing_key_.size); offset += sizeof (uint8_t); memcpy (args + offset, routing_key_.data, routing_key_.size); offset += routing_key_.size; assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size); args [offset] = ( ((mandatory_ ? 1 : 0) << 0) | ((immediate_ ? 1 : 0) << 1)); offset += sizeof (uint8_t); command_t cmd = { channel_, i_amqp::basic_id, i_amqp::basic_publish_id, args, offset }; command_queue.push (cmd); }
void zmq::amqp_marshaller_t::basic_return ( uint16_t channel_, uint16_t reply_code_, const i_amqp::shortstr_t reply_text_, const i_amqp::shortstr_t exchange_, const i_amqp::shortstr_t routing_key_) { unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size); assert (args); size_t offset = 0; assert (offset + sizeof (uint16_t) <= i_amqp::frame_min_size); put_uint16 (args + offset, reply_code_); offset += sizeof (uint16_t); assert (offset + sizeof (uint8_t) + reply_text_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, reply_text_.size); offset += sizeof (uint8_t); memcpy (args + offset, reply_text_.data, reply_text_.size); offset += reply_text_.size; assert (offset + sizeof (uint8_t) + exchange_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, exchange_.size); offset += sizeof (uint8_t); memcpy (args + offset, exchange_.data, exchange_.size); offset += exchange_.size; assert (offset + sizeof (uint8_t) + routing_key_.size <= i_amqp::frame_min_size); put_uint8 (args + offset, routing_key_.size); offset += sizeof (uint8_t); memcpy (args + offset, routing_key_.data, routing_key_.size); offset += routing_key_.size; command_t cmd = { channel_, i_amqp::basic_id, i_amqp::basic_return_id, args, offset }; command_queue.push (cmd); }
void journal_header_pack( journal_header_t *header , char **packed , size_t *size ) { char *p = NULL; *packed = NULL; *size = 0; if( ! header ) return; *packed = ( char *)malloc( JOURNAL_HEADER_PACKED_SIZE ); if( ! packed ) return; memset( *packed, 0 , JOURNAL_HEADER_PACKED_SIZE ); p = *packed; *p |= ( ( header->bitfield & 0x0f ) << 4 ); *p |= ( ( header->totchan == 0 ? 0 : header->totchan - 1 ) & 0x0f ) ; p += sizeof( char ); *size += sizeof( char ); put_uint16( (unsigned char **)&p, header->seq, size ); }
/* * set Config attribute header */ static void cfg_attrib_set(struct ikev2cfg_attrib *a, unsigned int type, unsigned int length) { put_uint16(&a->type, type); put_uint16(&a->length, length); }
void zmq::pgm_sender_t::out_event () { // POLLOUT event from send socket. If write buffer is empty, // try to read new data from the encoder. if (write_size == 0) { // First two bytes (sizeof uint16_t) are used to store message // offset in following steps. Note that by passing our buffer to // the get data function we prevent it from returning its own buffer. unsigned char *bf = out_buffer + sizeof (uint16_t); size_t bfsz = out_buffer_size - sizeof (uint16_t); uint16_t offset = 0xffff; size_t bytes = encoder.encode (&bf, bfsz); while (bytes < bfsz) { if (!more_flag && offset == 0xffff) offset = static_cast <uint16_t> (bytes); int rc = session->pull_msg (&msg); if (rc == -1) break; more_flag = msg.flags () & msg_t::more; encoder.load_msg (&msg); bf = out_buffer + sizeof (uint16_t) + bytes; bytes += encoder.encode (&bf, bfsz - bytes); } // If there are no data to write stop polling for output. if (bytes == 0) { reset_pollout (handle); return; } write_size = sizeof (uint16_t) + bytes; // Put offset information in the buffer. put_uint16 (out_buffer, offset); } if (has_tx_timer) { cancel_timer (tx_timer_id); set_pollout (handle); has_tx_timer = false; } // Send the data. size_t nbytes = pgm_socket.send (out_buffer, write_size); // We can write either all data or 0 which means rate limit reached. if (nbytes == write_size) write_size = 0; else { zmq_assert (nbytes == 0); if (errno == ENOMEM) { // Stop polling handle and wait for tx timeout const long timeout = pgm_socket.get_tx_timeout (); add_timer (timeout, tx_timer_id); reset_pollout (handle); has_tx_timer = true; } else errno_assert (errno == EBUSY); } }
/* * send Delete payload (for IPsec SA) in Informational exchange, based on * pfkey msg. It sends always single SPI. */ int isakmp_info_send_d2(struct ph2handle *iph2) { struct ph1handle *iph1; struct saproto *pr; struct isakmp_pl_d *d; rc_vchar_t *payload = NULL; int tlen; int error = 0; uint8_t *spi; if (iph2->status != PHASE2ST_ESTABLISHED) return 0; /* * don't send delete information if there is no phase 1 handler. * It's nonsensical to negotiate phase 1 to send the information. */ iph1 = getph1byaddr(iph2->src, iph2->dst); if (iph1 == NULL) return 0; /* create delete payload */ for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { /* send SPIs of inbound SAs. */ /* * XXX should I send outbound SAs's ? * I send inbound SAs's SPI only at the moment because I can't * decode any more if peer send encoded packet without aware of * deletion of SA. Outbound SAs don't come under the situation. */ tlen = sizeof(*d) + pr->spisize; payload = rc_vmalloc(tlen); if (payload == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer for payload.\n"); return errno; } d = (struct isakmp_pl_d *)payload->v; d->h.np = ISAKMP_NPTYPE_NONE; put_uint16(&d->h.len, tlen); put_uint32(&d->doi, IPSEC_DOI); d->proto_id = pr->proto_id; d->spi_size = pr->spisize; put_uint16(&d->num_spi, 1); /* * XXX SPI bits are left-filled, for use with IPComp. * we should be switching to variable-length spi field... */ spi = (uint8_t *)&pr->spi; spi += sizeof(pr->spi); spi -= pr->spisize; memcpy(d + 1, spi, pr->spisize); error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_D, 0); rc_vfree(payload); } return error; }
/* * send Information * When ph1->skeyid_a == NULL, send message without encoding. */ int isakmp_info_send_common(struct ph1handle *iph1, rc_vchar_t *payload, uint32_t np, int flags) { struct ph2handle *iph2 = NULL; rc_vchar_t *hash = NULL; struct isakmp *isakmp; struct isakmp_gen *gen; char *p; int tlen; int error = -1; /* add new entry to isakmp status table */ iph2 = newph2(); if (iph2 == NULL) goto end; iph2->dst = rcs_sadup(iph1->remote); if (iph2->dst == NULL) { delph2(iph2); goto end; } iph2->src = rcs_sadup(iph1->local); if (iph2->src == NULL) { delph2(iph2); goto end; } iph2->ph1 = iph1; iph2->side = INITIATOR; iph2->status = PHASE2ST_START; iph2->msgid = isakmp_newmsgid2(iph1); /* get IV and HASH(1) if skeyid_a was generated. */ if (iph1->skeyid_a != NULL) { iph2->ivm = oakley_newiv2(iph1, iph2->msgid); if (iph2->ivm == NULL) { delph2(iph2); goto end; } /* generate HASH(1) */ hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); if (hash == NULL) { delph2(iph2); goto end; } /* initialized total buffer length */ tlen = hash->l; tlen += sizeof(*gen); } else { /* IKE-SA is not established */ hash = NULL; /* initialized total buffer length */ tlen = 0; } if ((flags & ISAKMP_FLAG_A) == 0) iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); else iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); insph2(iph2); bindph12(iph1, iph2); tlen += sizeof(*isakmp) + payload->l; /* create buffer for isakmp payload */ iph2->sendbuf = rc_vmalloc(tlen); if (iph2->sendbuf == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer to send.\n"); goto err; } /* create isakmp header */ isakmp = (struct isakmp *)iph2->sendbuf->v; memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(isakmp_cookie_t)); memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(isakmp_cookie_t)); isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; isakmp->v = iph1->version; isakmp->etype = ISAKMP_ETYPE_INFO; isakmp->flags = iph2->flags; memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); put_uint32(&isakmp->len, tlen); p = (char *)(isakmp + 1); /* create HASH payload */ if (hash != NULL) { gen = (struct isakmp_gen *)p; gen->np = np & 0xff; put_uint16(&gen->len, sizeof(*gen) + hash->l); p += sizeof(*gen); memcpy(p, hash->v, hash->l); p += hash->l; } /* add payload */ memcpy(p, payload->v, payload->l); p += payload->l; #ifdef HAVE_PRINT_ISAKMP_C isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); #endif /* encoding */ if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { rc_vchar_t *tmp; tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive, iph2->ivm->iv); VPTRINIT(iph2->sendbuf); if (tmp == NULL) goto err; iph2->sendbuf = tmp; } /* HDR*, HASH(1), N */ if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { VPTRINIT(iph2->sendbuf); goto err; } plog(PLOG_DEBUG, PLOGLOC, NULL, "sendto Information %s.\n", s_isakmp_nptype(np)); /* * don't resend notify message because peer can use Acknowledged * Informational if peer requires the reply of the notify message. */ /* XXX If Acknowledged Informational required, don't delete ph2handle */ error = 0; VPTRINIT(iph2->sendbuf); goto err; /* XXX */ end: if (hash) rc_vfree(hash); return error; err: unbindph12(iph2); remph2(iph2); delph2(iph2); goto end; }
/* * send Notification payload (for without ISAKMP SA) in Informational exchange */ int isakmp_info_send_nx(struct isakmp *isakmp, struct sockaddr *remote, struct sockaddr *local, int type, rc_vchar_t *data) { struct ph1handle *iph1 = NULL; struct rcf_remote *rmconf; rc_vchar_t *payload = NULL; int tlen; int error = -1; struct isakmp_pl_n *n; int spisiz = 0; /* see below */ /* search appropreate configuration */ rmconf = getrmconf(remote); if (rmconf == NULL) { plog(PLOG_INTERR, PLOGLOC, 0, "no configuration found for peer address.\n"); goto end; } /* add new entry to isakmp status table. */ iph1 = newph1(); if (iph1 == NULL) return -1; memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(isakmp_cookie_t)); isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); iph1->status = PHASE1ST_START; iph1->rmconf = rmconf; iph1->side = INITIATOR; iph1->version = isakmp->v; iph1->flags = 0; iph1->msgid = 0; /* XXX */ #ifdef ENABLE_HYBRID if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { error = -1; goto end; } #endif #ifdef ENABLE_FRAG iph1->frag = 0; iph1->frag_chain = NULL; #endif iph1->proposal = ikev1_conf_to_isakmpsa(rmconf); /* copy remote address */ if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { error = -1; goto end; } tlen = sizeof(*n) + spisiz; if (data) tlen += data->l; payload = rc_vmalloc(tlen); if (payload == NULL) { plog(PLOG_INTERR, PLOGLOC, NULL, "failed to get buffer to send.\n"); error = -1; goto end; } n = (struct isakmp_pl_n *)payload->v; n->h.np = ISAKMP_NPTYPE_NONE; put_uint16(&n->h.len, tlen); put_uint32(&n->doi, IPSEC_DOI); n->proto_id = IPSECDOI_KEY_IKE; n->spi_size = spisiz; put_uint16(&n->type, type); if (spisiz) memset(n + 1, 0, spisiz); /*XXX*/ if (data) memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); rc_vfree(payload); end: if (iph1 != NULL) delph1(iph1); return error; }