示例#1
0
void
ikev2_msg_retransmit_timeout(struct iked *env, void *arg)
{
	struct iked_message	*msg = arg;
	struct iked_sa		*sa = msg->msg_sa;

	if (msg->msg_tries < IKED_RETRANSMIT_TRIES) {
		if (sendtofrom(msg->msg_fd, ibuf_data(msg->msg_data),
		    ibuf_size(msg->msg_data), 0,
		    (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen,
		    (struct sockaddr *)&msg->msg_local,
		    msg->msg_locallen) == -1) {
			log_warn("%s: sendtofrom", __func__);
			sa_free(env, sa);
			return;
		}
		/* Exponential timeout */
		timer_add(env, &msg->msg_timer,
		    IKED_RETRANSMIT_TIMEOUT * (2 << (msg->msg_tries++)));
	} else {
		log_debug("%s: retransmit limit reached for msgid %u",
		    __func__, msg->msg_msgid);
		sa_free(env, sa);
	}
}
示例#2
0
int
ikev2_msg_retransmit_response(struct iked *env, struct iked_sa *sa,
    struct iked_message *msg)
{
	if (sendtofrom(msg->msg_fd, ibuf_data(msg->msg_data),
	    ibuf_size(msg->msg_data), 0,
	    (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen,
	    (struct sockaddr *)&msg->msg_local, msg->msg_locallen) == -1) {
		log_warn("%s: sendtofrom", __func__);
		return (-1);
	}

	timer_add(env, &msg->msg_timer, IKED_RESPONSE_TIMEOUT);
	return (0);
}
示例#3
0
int
ikev2_msg_send(struct iked *env, struct iked_message *msg)
{
	struct iked_sa		*sa = msg->msg_sa;
	struct ibuf		*buf = msg->msg_data;
	uint32_t		 natt = 0x00000000;
	int			 isnatt = 0;
	uint8_t			 exchange, flags;
	struct ike_header	*hdr;
	struct iked_message	*m;

	if (buf == NULL || (hdr = ibuf_seek(msg->msg_data,
	    msg->msg_offset, sizeof(*hdr))) == NULL)
		return (-1);

	isnatt = (msg->msg_natt || (msg->msg_sa && msg->msg_sa->sa_natt));

	exchange = hdr->ike_exchange;
	flags = hdr->ike_flags;
	log_info("%s: %s %s from %s to %s msgid %u, %ld bytes%s", __func__,
	    print_map(exchange, ikev2_exchange_map),
	    (flags & IKEV2_FLAG_RESPONSE) ? "response" : "request",
	    print_host((struct sockaddr *)&msg->msg_local, NULL, 0),
	    print_host((struct sockaddr *)&msg->msg_peer, NULL, 0),
	    betoh32(hdr->ike_msgid),
	    ibuf_length(buf), isnatt ? ", NAT-T" : "");

	if (isnatt) {
		if (ibuf_prepend(buf, &natt, sizeof(natt)) == -1) {
			log_debug("%s: failed to set NAT-T", __func__);
			return (-1);
		}
		msg->msg_offset += sizeof(natt);
	}

	if (sendtofrom(msg->msg_fd, ibuf_data(buf), ibuf_size(buf), 0,
	    (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen,
	    (struct sockaddr *)&msg->msg_local, msg->msg_locallen) == -1) {
		log_warn("%s: sendtofrom", __func__);
		return (-1);
	}

	if (!sa)
		return (0);

	if ((m = ikev2_msg_copy(env, msg)) == NULL) {
		log_debug("%s: failed to copy a message", __func__);
		return (-1);
	}
	m->msg_exchange = exchange;

	if (flags & IKEV2_FLAG_RESPONSE) {
		TAILQ_INSERT_TAIL(&sa->sa_responses, m, msg_entry);
		timer_set(env, &m->msg_timer, ikev2_msg_response_timeout, m);
		timer_add(env, &m->msg_timer, IKED_RESPONSE_TIMEOUT);
	} else {
		TAILQ_INSERT_TAIL(&sa->sa_requests, m, msg_entry);
		timer_set(env, &m->msg_timer, ikev2_msg_retransmit_timeout, m);
		timer_add(env, &m->msg_timer, IKED_RETRANSMIT_TIMEOUT);
	}

	return (0);
}
示例#4
0
smcp_status_t
smcp_plat_outbound_finish(smcp_t self,const uint8_t* data_ptr, coap_size_t data_len, int flags)
{
	SMCP_EMBEDDED_SELF_HOOK;
	smcp_status_t ret = SMCP_STATUS_FAILURE;
	ssize_t sent_bytes = -1;
	int fd;

#if SMCP_DTLS
	if (smcp_plat_get_session_type() == SMCP_SESSION_TYPE_DTLS) {
		ret = smcp_plat_ssl_outbound_packet_process(self, data_ptr, data_len);
	} else
#endif
	if (smcp_plat_get_session_type() == SMCP_SESSION_TYPE_UDP) {
		fd = smcp_get_current_instance()->plat.fd_udp;

		assert(fd >= 0);

		require(data_len > 0, bail);

#if VERBOSE_DEBUG
		{
			char addr_str[50] = "???";
			uint16_t port = ntohs(smcp_plat_get_remote_sockaddr()->smcp_port);
			SMCP_ADDR_NTOP(addr_str,sizeof(addr_str),&smcp_plat_get_remote_sockaddr()->smcp_addr);
			DEBUG_PRINTF("smcp(%p): Outbound packet to [%s]:%d", self,addr_str,(int)port);
			coap_dump_header(
				SMCP_DEBUG_OUT_FILE,
				"Outbound:\t",
				(struct coap_header_s*)data_ptr,
				(coap_size_t)data_len
			);
		}
#endif

		sent_bytes = sendtofrom(
			fd,
			data_ptr,
			data_len,
			0,
			(struct sockaddr *)smcp_plat_get_remote_sockaddr(),
			sizeof(smcp_sockaddr_t),
			(struct sockaddr *)smcp_plat_get_local_sockaddr(),
			sizeof(smcp_sockaddr_t)
		);

		require_action_string(
			(sent_bytes >= 0),
			bail, ret = SMCP_STATUS_ERRNO, strerror(errno)
		);

		require_action_string(
			(sent_bytes == data_len),
			bail, ret = SMCP_STATUS_FAILURE, "sendto() returned less than len"
		);

		ret = SMCP_STATUS_OK;

	} else {
		ret = SMCP_STATUS_NOT_IMPLEMENTED;
	}
bail:
	return ret;
}