示例#1
0
/**
 * \brief This function handles node commands, when payload packet was received.
 *
 * This function also detects packet loss of previous not received payload
 * packets. All node commands are unpacked from the buffer and added to incoming queue.
 *
 * \param[in]	*C	The verse context.
 *
 * \return		This function returns RECEIVE_PACKET_DELAYED, when delayd packet
 * was received, otherwise it returns RECEIVE_PACKET_SUCCESS.
 */
static int handle_node_commands(struct vContext *C)
{
	struct VSession *vsession = CTX_current_session(C);
	struct VDgramConn *vconn = CTX_current_dgram_conn(C);
	struct VPacket *r_packet = CTX_r_packet(C);
	struct Ack_Nak_Cmd ack_nak_cmd;

	/* Note: when ACK and NAK command are add to the AckNak history,
	 * then this vector of commands is automatically compressed. */

	/* Was any packet lost since last receiving of packet? */
	if(r_packet->header.payload_id > vconn->last_r_pay+1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Packet(s) lost: %d - %d\n",
				vconn->last_r_pay+1, r_packet->header.payload_id-1);
		/* Add NAK command to the list of ACK NAK commands */
		ack_nak_cmd.id = CMD_NAK_ID;
		ack_nak_cmd.pay_id = vconn->last_r_pay+1;
		v_ack_nak_history_add_cmd(&vconn->ack_nak, &ack_nak_cmd);
	/* Was some delayed packet received? */
	} else if(r_packet->header.payload_id < vconn->last_r_pay+1) {
		if(is_log_level(VRS_PRINT_WARNING))
			v_print_log(VRS_PRINT_WARNING, "Received unordered packet: %d, expected: %d\n", r_packet->header.payload_id, vconn->last_r_pay+1);
		/* Drop this packet */
		return RECEIVE_PACKET_UNORDERED;
	}

	/* ADD ACK command to the list of ACK NAK commands */
	ack_nak_cmd.id = CMD_ACK_ID;
	ack_nak_cmd.pay_id = r_packet->header.payload_id;
	v_ack_nak_history_add_cmd(&vconn->ack_nak, &ack_nak_cmd);

	/* Check if there are really node commands */
	if(r_packet->data!=NULL) {
		/* Unpack node commands and put them to the queue of incoming commands */
		v_cmd_unpack((char*)r_packet->data, r_packet->data_size, vsession->in_queue);
	}

	return RECEIVE_PACKET_SUCCESS;
}
示例#2
0
int vc_OPEN_loop(struct vContext *C)
{
	struct VDgramConn *dgram_conn = CTX_current_dgram_conn(C);
	struct VPacket *r_packet = CTX_r_packet(C);
	struct Ack_Nak_Cmd ack_cmd;
	int ret;

	/* OPEN state */
	if(is_log_level(VRS_PRINT_DEBUG_MSG)) {
		printf("%c[%d;%dm", 27, 1, 31);
		v_print_log(VRS_PRINT_DEBUG_MSG, "Client state: OPEN\n");
		printf("%c[%dm", 27, 0);
	}

	/* Add ACK command to the list of ACK NAK commands to be send to the peer */
	ack_cmd.id = CMD_ACK_ID;
	ack_cmd.pay_id = r_packet->header.payload_id;
	v_ack_nak_history_add_cmd(&dgram_conn->ack_nak, &ack_cmd);

	/* Receiving of last packet in previous packet had to be successful, because
	 * client is in this state now :-). */
	ret = RECEIVE_PACKET_SUCCESS;

	while(dgram_conn->host_state == UDP_CLIENT_STATE_OPEN) {

		dgram_conn->state[UDP_CLIENT_STATE_OPEN].attempts++;

		/* Send payload data or keep-alive packet */
		if( vc_OPEN_send_packet(C) == SEND_PACKET_ERROR ) {
			return STATE_EXIT_ERROR;
		}

		/* Try to receive packet and handle received packet */
		ret = vc_receive_and_handle_packet(C, vc_OPEN_handle_packet);
		if(ret == RECEIVE_PACKET_SUCCESS) {
			continue;
		} else if(ret == RECEIVE_PACKET_TIMEOUT) {
			struct timeval tv;
			gettimeofday(&tv, NULL);
			/* When no valid packet received from server for defined time, then consider this
			 * connection as dead and return error */
			if((tv.tv_sec - dgram_conn->tv_pay_recv.tv_sec) >= VRS_TIMEOUT) {
				return STATE_EXIT_ERROR;
			} else {
				continue;
			}
		} else if(ret == RECEIVE_PACKET_CORRUPTED) {
			continue;
		} else if(ret == RECEIVE_PACKET_FAKED) {
			return STATE_EXIT_ERROR;
		} else if(ret == RECEIVE_PACKET_ERROR) {
			return STATE_EXIT_ERROR;
		}

#ifdef WITH_OPENSSL
		if(dgram_conn->io_ctx.flags & SOCKET_SECURED) {
			/* Did server close DTLS connection? */
			if((SSL_get_shutdown(dgram_conn->io_ctx.ssl) & SSL_RECEIVED_SHUTDOWN)) {
				return STATE_EXIT_ERROR;
			}
		}
#endif
	}

	return STATE_EXIT_SUCCESS;
}