예제 #1
0
axl_bool      vortex_sequencer_direct_send (VortexConnection    * connection,
					    VortexChannel       * channel,
					    VortexWriterData    * packet)
{
	/* reply number */
	axl_bool    result = axl_true;
#if defined(ENABLE_VORTEX_LOG)
	VortexCtx * ctx    = vortex_connection_get_ctx (connection);
#endif

#if defined(ENABLE_VORTEX_LOG)
	/* send the frame */
	if (vortex_log2_is_enabled (ctx))
		vortex_log2 (VORTEX_LEVEL_DEBUG, "Sending message, size (%d) over channel=%d (%p), connection id=%d, errno=%d, Content: \n%s",
			     packet->the_size,  
			     vortex_channel_get_number (channel), channel, vortex_connection_get_id (connection), errno, packet->the_frame);
	else
		vortex_log (VORTEX_LEVEL_DEBUG, "Sending message, size (%d) over channel=%d (%p), connection id=%d, errno=%d",
			    packet->the_size,  
			    vortex_channel_get_number (channel), channel, vortex_connection_get_id (connection), errno);
#endif

	if (! vortex_frame_send_raw (connection, packet->the_frame, packet->the_size)) {
		/* drop a log */
		vortex_log (VORTEX_LEVEL_CRITICAL, "unable to send frame over connection id=%d: errno=(%d): %s", 
			    vortex_connection_get_id (connection),
			    errno, vortex_errno_get_error (errno));
		
		/* set as non connected and flag the result */
		result = axl_false;
	}
	
	/* signal the message have been sent */
	if ((packet->type == VORTEX_FRAME_TYPE_RPY || packet->type == VORTEX_FRAME_TYPE_NUL) && packet->is_complete && ! packet->fixed_more) {  

		/* update reply sent */
		vortex_channel_update_status (channel, 0, packet->msg_no, UPDATE_RPY_NO_WRITTEN);

		/* unblock waiting thread for replies sent */
		vortex_channel_signal_reply_sent_on_close_blocked (channel);
		
		/* signal reply sent */
		vortex_channel_signal_rpy_sent (channel, packet->msg_no);
	}

	/* nothing more */
	return result;
}
예제 #2
0
/** 
 * @brief The ppath_selected function is used by turbulence to signal
 * modules that a connection was finally configured under the provided
 * profile path. This is important because a profile path defines how
 * the connection will be limited and configured to accept profiles,
 * configuring process permission and so on. 
 *
 * It is also useful because at the time a profile path is selected,
 * serverName name is available, allowing the module to take especial
 * actions.
 *
 * @param ctx The \ref TurbulenceCtx where the profile path was selected.
 *
 * @param ppath_selected Reference to the object representing the profile path selected. See \ref turbulence_ppath.
 *
 * @param conn The VortexConnection object that was configured with the provided profile path.
 *
 * @return axl_true to accept or not the connection. Keep in mind
 * returning axl_false may also terminate current child process
 * (according to \ref turbulence_clean_start "clean start" configuration).
 */
static axl_bool test_ppath_selected (TurbulenceCtx * ctx, TurbulencePPathDef * ppath_selected, VortexConnection * conn) {
	msg ("Turbulence configured ppath %s to connection id %d",
	     turbulence_ppath_get_name (ppath_selected), 
	     vortex_connection_get_id (conn));

	return axl_true;
}
예제 #3
0
axl_bool vortex_sequencer_queue_data (VortexCtx * ctx, VortexSequencerData * data)
{
	axl_bool is_stalled;

	v_return_val_if_fail (data, axl_false);

	/* check state before handling this message with the sequencer */
	if (ctx->vortex_exit || ctx->sequencer_state == NULL || ctx->sequencer_state->exit) {
		vortex_payload_feeder_unref (data->feeder);
		axl_free (data->message);
		axl_free (data);
		return axl_false;
	}

	/* update channel reference (this reference is associated to
	   the data) */
	/* if (! vortex_channel_ref (data->channel)) {
		vortex_log (VORTEX_LEVEL_WARNING, "trying to queue a message to be sent over a channel not opened (vortex_channel_ref failed)");
		vortex_payload_feeder_unref (data->feeder);
		axl_free (data->message);
		axl_free (data);
		return axl_false;
		} */

	vortex_log2 (VORTEX_LEVEL_DEBUG, "new message to be sent: msgno %d, channel %d, conn-id=%d, is-stalled: %d (size: %d):\n%s",
		     data->msg_no, 
		     data->channel_num, 
		     vortex_connection_get_id (vortex_channel_get_connection (data->channel)),
		     vortex_channel_is_stalled (data->channel),
		     data->message_size,
		     data->message ? data->message : "**** empty message ****");

	/* get current is stalled status */
	is_stalled = vortex_channel_is_stalled (data->channel);

	/* add the channel to the sequencer structure */
	if (! vortex_sequencer_add_channel (ctx, data)) 
		return axl_false;

	/* signal sequencer (but only if the channel is not stalled) */
	if (! is_stalled)
		vortex_sequencer_signal (ctx);

	return axl_true;
}
예제 #4
0
/* mod_test_11 ppath-selected handler */
static axl_bool mod_test_11_ppath_selected (TurbulenceCtx * _ctx, TurbulencePPathDef * ppath_selected, VortexConnection * conn) {

	/* mutex lock */
	vortex_mutex_lock (&mutex);
	
	/* unlock mutex */
	vortex_mutex_unlock (&mutex);

	msg ("Test 11: received profile path selected %s, connection id %d", 
	     turbulence_ppath_get_name (ppath_selected), vortex_connection_get_id (conn));

	/* register a profile at this point */
	vortex_profiles_register (TBC_VORTEX_CTX (ctx), "urn:aspl.es:beep:profiles:reg-test:profile-11",
				  NULL, NULL, NULL, NULL, mod_test_11_frame_received, NULL);

	/* notification ok */
	return true;
} /* end mod_test_11_ppath_selected */
예제 #5
0
void test_20_frame_received (VortexChannel    * channel, 
			     VortexConnection * conn,
			     VortexFrame      * frame,
			     axlPointer         user_data)
{
	const char         * profile_path;
	TurbulencePPathDef * ppath;
	char               * conn_id;
	if (axl_cmp ((const char *) vortex_frame_get_payload (frame),
		     "get-profile-path-name")) {
		/* get profile path */
		ppath = turbulence_ppath_selected (conn);
		if (ppath == NULL) {
			vortex_channel_send_rpy (channel, "no profile path selected!!!", 27, vortex_frame_get_msgno (frame));
			return;
		} /* end if */

		/* get profile path name */
		profile_path = turbulence_ppath_get_name (ppath);
		if (profile_path == NULL) {
			vortex_channel_send_rpy (channel, "no profile path name defined", 28, vortex_frame_get_msgno (frame));
			return;
		}

		printf ("Test 20: CHILD: returning profile path name: %s\n", profile_path);

		/* set profile path name */
		vortex_channel_send_rpy (channel, profile_path, strlen (profile_path), vortex_frame_get_msgno (frame));
		return;
	}

	/* send conn-id in case no other command was received */
	conn_id = axl_strdup_printf ("%d", vortex_connection_get_id (conn));
	vortex_channel_send_rpy (channel, conn_id, strlen (conn_id), vortex_frame_get_msgno (frame));
	axl_free (conn_id);

	return;
}
예제 #6
0
axl_bool __mod_sasl_mysql_prepare_query_and_auth (TurbulenceCtx    * ctx, 
						  const char       * _query,
						  VortexConnection * conn,
						  axlNode          * auth_db_node_conf,
						  const char       * auth_id,
						  const char       * authorization_id,
						  const char       * formated_password,
						  const char       * password,
						  const char       * serverName,
						  const char       * sasl_method,
						  axl_bool           just_run_query,
						  axl_bool           skip_login_error_reporting,
						  axlError        ** err)
{

	MYSQL_RES   * result;
	MYSQL_ROW     row;
	axl_bool      _result;
	char        * query;

	/* duplicate query */
	query = axl_strdup (_query);
	if (query == NULL) 
		return axl_false; /* allocation failure */

	/* replace query with recognized tokens */
	axl_replace (query, "%u", auth_id);
	axl_replace (query, "%n", serverName);
	axl_replace (query, "%i", authorization_id);
	axl_replace (query, "%m", sasl_method);
	axl_replace (query, "%p", vortex_connection_get_host (conn));

	if (! just_run_query) {
		msg ("Trying to auth [%s] with query string [%s], conn-id=%d from %s:%s ", auth_id, query, 
		     vortex_connection_get_id (conn), vortex_connection_get_host (conn), vortex_connection_get_port (conn));
	} /* end if */

	/* run query */
	result = mod_sasl_mysql_do_query (ctx, auth_db_node_conf, query, axl_false, err);
	axl_free (query);

	/* check if we have to only run this query */
	if (just_run_query) {
		mysql_free_result (result);
		return axl_true;
	} /* end if */

	/* check result */
	if (result == NULL) {
		error ("Unable to authenticate user, query string failed with %s", axl_error_get (*err));
		axl_error_free (*err);
		return axl_false;
	} /* end if */

	/* return content from the first [0][0] array position */
	row     = mysql_fetch_row (result);
	if (row == NULL) {
		if (! skip_login_error_reporting) { 
			/* log login failure */
			error ("login failure: %s, failed from: %s", auth_id, vortex_connection_get_host_ip (conn));
		} /* end if */

		mysql_free_result (result);
		return  axl_false;
	} /* end if */
	/* check result */
	_result = axl_cmp (row[0], formated_password);
	if (! _result) {
		/* if it fails, check password format */
		/* support here passwords schemes using  */
		/* http://wiki.dovecot.org/Authentication/PasswordSchemes */
		_result = common_sasl_check_crypt_password (password, row[0]);
	} /* end if */
	mysql_free_result (result);

	return _result;
}
예제 #7
0
void vortex_sequencer_process_channels (VortexCtx * ctx, VortexSequencerState * state, axl_bool process_channel_0)
{
	axl_bool               paused;
	axl_bool               complete;
	axl_bool               is_empty;
	axl_bool               is_stalled;	
	VortexChannel        * channel          = NULL;
	VortexConnection     * conn             = NULL;

	/* now iterate all ready channels */
	axl_hash_cursor_first (state->ready_cursor);
	while (axl_hash_cursor_has_item (state->ready_cursor)) {
		
		/* get the channel and manage it, unlocking
		 * during the process */
		channel = axl_hash_cursor_get_key (state->ready_cursor);
		
		/* check for remove flag */
		if (PTR_TO_INT (vortex_channel_get_data (channel, "vo:seq:del"))) {
			axl_hash_cursor_remove (state->ready_cursor);
			continue;
		}
		
		/* check if channel is stalled */
		if (vortex_channel_is_stalled (channel)) {
			vortex_log (VORTEX_LEVEL_DEBUG, "channel=%d (%p) is stalled, removing from ready set",
				    vortex_channel_get_number (channel), channel);
			axl_hash_cursor_remove (state->ready_cursor);
			continue;
		} /* end if */

		/* check what kind of channel is this to know if we
		 * have to process it */
		if (process_channel_0 && vortex_channel_get_number (channel) != 0) {
			axl_hash_cursor_next (state->ready_cursor);
			continue;
		}
		if (!process_channel_0 && vortex_channel_get_number (channel) == 0) {
			axl_hash_cursor_next (state->ready_cursor);
			continue;
		}

		/* get connection reference */
		conn = vortex_channel_get_connection (channel);
		
		/* acquire connection */
		if (! vortex_connection_ref (conn, "vortex-sequencer")) {
			vortex_log (VORTEX_LEVEL_CRITICAL, "Unable to acquire reference to the connection (%p) inside vortex sequencer to do sending round, dropping channel (%p)",
				    conn, channel);
			axl_hash_cursor_remove (state->ready_cursor);
			continue;
		} /* end if */

		vortex_log (VORTEX_LEVEL_DEBUG, "handling next send channel=%d (%p), conn-id=%d (%p)",
			    vortex_channel_get_number (channel), channel, vortex_connection_get_id (conn), conn);
		
		/* unlock and call */
		vortex_mutex_unlock (&state->mutex);
		
		/* call to do send operation */
		paused   = axl_false;
		complete = axl_false;
		is_empty = axl_false;
		__vortex_sequencer_do_send_round (ctx, channel, conn, &paused, &complete);
		
		vortex_log (VORTEX_LEVEL_DEBUG, "it seems the message was sent completely over conn-id=%d, channel=%d (%p)",
			    vortex_connection_get_id (conn), vortex_channel_get_number (channel), channel);
		
		/* release connection (unlock mutex to allow
		 * connection close process to reenter into
		 * sequencer module) */
		vortex_connection_unref (conn, "vortex-sequencer");
		
		vortex_mutex_lock (&state->mutex);
		
		/* remove message sent */
		is_stalled = vortex_channel_is_stalled (channel);
		if (complete) {
			/* remove message sent */
			is_empty = vortex_sequencer_remove_message_sent (ctx, channel);
		} /* end if */
		
		/* check for remove flag */
		if (PTR_TO_INT (vortex_channel_get_data (channel, "vo:seq:del"))) {
			axl_hash_cursor_remove (state->ready_cursor);
			continue;
		}
		
		/* check channel after send operation */
		if (is_empty) {
			vortex_log (VORTEX_LEVEL_DEBUG, "Channel %p is empty (no more pending messages), removing from sequencer", channel);
			/* no more send operations, remove channel from our registry but check
			 * first it wasn't removed during the unlock  */ 				
			axl_hash_cursor_remove (state->ready_cursor);
			continue;
		}
		
		/* now check stalled channel */
		if (is_stalled || paused) {
			vortex_log (VORTEX_LEVEL_DEBUG, "Channel %p is stalled or paused, removing from sequencer", channel);
			/* no more send operations, remove channel from our registry but check
			 * first it wasn't removed during the unlock  */ 				
			axl_hash_cursor_remove (state->ready_cursor);
			continue;
		} /* end if */
		
		/* next item */
		axl_hash_cursor_next (state->ready_cursor);
		
	} /* end while */

	return;
}
예제 #8
0
/** 
 * @internal Function that does a send round for a channel. The
 * function assumes the channel is not stalled (but can end stalled
 * after the function finished).
 *
 */ 
void __vortex_sequencer_do_send_round (VortexCtx * ctx, VortexChannel * channel, VortexConnection * conn, axl_bool * paused, axl_bool * complete)
{
	VortexSequencerData  * data;
#if defined(ENABLE_VORTEX_LOG)
	int                    message_size;
	int                    max_seq_no = 0;
#endif
	int                    size_to_copy;
	VortexWriterData       packet;

	/* get data from channel */
	data  = vortex_channel_next_pending_message (channel);
	if (data == NULL) {
		/* no pending message on this channel */
		vortex_log (VORTEX_LEVEL_DEBUG, "no data were found to sequence on this channel, remove channel");
		return;
	}

	vortex_log (VORTEX_LEVEL_DEBUG, "a new message to be sequenced: (conn-id=%d, channel=%d, size=%d)..",
		    vortex_connection_get_id (conn), data->channel_num, data->message_size);
	
	/* if feeder is defined, get pending message size */
	if (data->feeder)
		data->message_size = vortex_payload_feeder_get_pending_size (data->feeder);

	/* refresh all sending data */
	data->first_seq_no     = vortex_channel_get_next_seq_no (channel);
#if defined(ENABLE_VORTEX_LOG)
	message_size           = data->message_size;
	max_seq_no             = vortex_channel_get_max_seq_no_remote_accepted (channel);
#endif

	vortex_log (VORTEX_LEVEL_DEBUG, "sequence operation (%p): type=%d, msgno=%d, next seq no=%u message size=%d max seq no=%u step=%u",
		    data, data->type, data->msg_no, data->first_seq_no, message_size, max_seq_no, data->step);
  		
	/* build the packet to send */
	size_to_copy = vortex_sequencer_build_packet_to_send (ctx, channel, conn, data, &packet);
	*complete    = packet.is_complete;

	/* check if the transfer is cancelled or paused */
	if (size_to_copy < 0) {
		*paused = axl_true;
		return;
	}
			
	/* STEP 1: now queue the rest of the message if it wasn't
	 * completly sequence. We do this before sending the frame to
	 * avoid a possible race condition between sending the message
	 * sequenced, be processed at the remote side, the remote side
	 * generate a SEQ frame, send it, and our vortex reader
	 * process it, finding that there is not pending, not yet
	 * completely sequenced message.
	 *
	 * Incredible, but true!
	 */
	if (! packet.is_complete) {
		
		/* well, it seems we didn't be able to send the hole
		 * message, so there are some remaining bytes. Just
		 * keep track about how many bytes we have sent. We
		 * will used this information once the message is
		 * enabled to be sent again on the next SEQ
		 * received. */
		data->step          = data->step + size_to_copy;
		/* make next seq no value to point to the next byte to send */
		data->first_seq_no  = (data->first_seq_no + size_to_copy) % (MAX_SEQ_NO);
		/* make message size to be decreased the amount of bytes sent. */
		data->message_size  = data->message_size - size_to_copy;

		vortex_log (VORTEX_LEVEL_DEBUG, 
			    "updating message sequencing status: next seq no=%u max seq no accepted=%u message size=%d step=%u",
			    data->first_seq_no, max_seq_no, data->message_size, data->step);

		vortex_log (VORTEX_LEVEL_DEBUG, "the message sequenced is not going to be sent completely (%d != %d)", 
			    size_to_copy, message_size);

	} /* end if */

	/* because we have sent the message, update remote seqno buffer used */
	vortex_channel_update_status (channel, size_to_copy, 0, UPDATE_SEQ_NO);
		
	/* STEP 2: now, send the package built, queueing it at the
	 * channel queue. At this point, we have prepared the rest to
	 * be sequenced message. */
	/* now, perform a send operation for the frame built */
	vortex_log (VORTEX_LEVEL_DEBUG, "frame built, send the frame directly (over channel=%d, conn-id=%d)",
		    vortex_channel_get_number (channel), vortex_connection_get_id (conn));

	if (! vortex_sequencer_direct_send (conn, channel, &packet)) {
		vortex_log (VORTEX_LEVEL_WARNING, "unable to send data at this moment");
		return;
	}

	/* that's all vortex sequencer process can do */
	return;
}
예제 #9
0
int vortex_sequencer_build_packet_to_send (VortexCtx           * ctx, 
					   VortexChannel       * channel, 
					   VortexConnection    * conn, 
					   VortexSequencerData * data, 
					   VortexWriterData    * packet)
{
 	int          size_to_copy        = 0;
 	unsigned int max_seq_no_accepted = vortex_channel_get_max_seq_no_remote_accepted (channel);
	char       * payload             = NULL;

	/* clear packet */
	memset (packet, 0, sizeof (VortexWriterData));

	/* flag as not complete until something different is set */
	packet->is_complete = axl_false;

	/* check particular case where an empty message is to be sent
	 * and the message is NUL */
	if (data->message_size == 0 && data->type == VORTEX_FRAME_TYPE_NUL)
		goto build_frame;
  
	/* calculate how many bytes to copy from the payload
	 * according to max_seq_no */
	size_to_copy = vortex_channel_get_next_frame_size (channel,  
							   data->first_seq_no, 
							   data->message_size, 
 							   max_seq_no_accepted);

	/* check that the next_frame_size do not report wrong values */
	if (size_to_copy > data->message_size || size_to_copy <= 0) {
		__vortex_connection_shutdown_and_record_error (
			conn, VortexProtocolError,
			"vortex_channel_get_next_frame_size is reporting wrong values (size to copy: %d > message size: %d), this will cause protocol failures...shutdown connection id=%d (channel stalled: %d)", 
			size_to_copy, data->message_size, 
			vortex_connection_get_id (conn), vortex_channel_is_stalled (channel));
		return 0;
	}

	/* check here if we have a feeder defined */
	if (data->feeder) {
		if (data->feeder->status == 0) {
			/* check and increase buffer */
			CHECK_AND_INCREASE_BUFFER (size_to_copy, ctx->sequencer_feeder_buffer, ctx->sequencer_feeder_buffer_size);

			/* get content available at this moment to be sent */
			size_to_copy = vortex_payload_feeder_get_content (data->feeder, size_to_copy, ctx->sequencer_feeder_buffer);
		} else {
			vortex_log (VORTEX_LEVEL_DEBUG, "feeder cancelled, close transfer status is: %d", data->feeder->close_transfer);
			if (! data->feeder->close_transfer) {
				/* also record current msgno to
				   continue in the future */
				data->feeder->msg_no = data->msg_no;

				/* remove queued request if found same pointer */
				if (data == vortex_channel_next_pending_message (channel)) {
					/* remove the queued request but ensure we are the only thread touching this */
					vortex_sequencer_remove_message_sent (ctx, channel);
				}

				/* signal caller to stop delivering this content */
				return -1;
			} /* end if */

			/* flag this feeder is about being cancelled/paused */
			size_to_copy = -1;
		} /* end if */
	} /* end if */
	
	vortex_log (VORTEX_LEVEL_DEBUG, "the channel=%d (on conn-id=%d) is not stalled, continue with sequencing, about to send (size_to_copy:%d) bytes as payload (buffer:%d)...",
 		    vortex_channel_get_number (channel), 
		    vortex_connection_get_id (vortex_channel_get_connection (channel)), size_to_copy, ctx->sequencer_send_buffer_size);
 	vortex_log (VORTEX_LEVEL_DEBUG, "channel remote max seq no accepted: %u (proposed: %u)...",
 		    vortex_channel_get_max_seq_no_remote_accepted (channel), max_seq_no_accepted);
	
	/* create the new package to be managed by the vortex writer */
	packet->msg_no = data->msg_no;
 
	if (size_to_copy > 0) {
		/* check if we have to realloc buffer */
		CHECK_AND_INCREASE_BUFFER (size_to_copy, ctx->sequencer_send_buffer, ctx->sequencer_send_buffer_size);
	}
	
	/* we have the payload on buffer */
build_frame:
	/* set datatype for this package */
	packet->type = data->type;

	/* report what we are going to sequence */
	vortex_log (VORTEX_LEVEL_DEBUG, "sequencing next message: type=%d, channel num=%d, msgno=%d, more=%d, next seq=%u size=%d ansno=%d",
		    data->type, data->channel_num, data->msg_no, !(data->message_size == size_to_copy), 
		    data->first_seq_no, size_to_copy, data->ansno);
	vortex_log (VORTEX_LEVEL_DEBUG, "                         message=%p, step=%u, message-size=%u",
		    data->message, data->step, data->message_size);

	/* point to payload */
	if (data->feeder) {
		payload = (size_to_copy > 0) ? ctx->sequencer_feeder_buffer : NULL;
	} else
		payload = (data->message != NULL) ? (data->message + data->step) : NULL;

	/* check if the packet is complete (either last frame or all
	 * the payload fits into a single frame */
	if (data->feeder) {
		/* prepare is complete flag */
		packet->is_complete = (data->feeder->status != 0 && data->feeder->close_transfer) ? axl_true : vortex_payload_feeder_is_finished (data->feeder);

		/* normalize size_to_copy to avoid the caller to skipp ending this empty frame */
		if (size_to_copy < 0)
			size_to_copy = 0;
	} else
		packet->is_complete = (size_to_copy == data->message_size);

	/* build frame */
	packet->the_frame = vortex_frame_build_up_from_params_s_buffer (
		data->type,        /* frame type to be created */
		data->channel_num, /* channel number the frame applies to */
		data->msg_no,      /* the message number */
		/* frame payload size to be created */
		!packet->is_complete || data->fixed_more, /* have more frames */
		data->first_seq_no,   /* sequence number for the frame to be created */
		/* size for the payload starting from previous sequence number */
		size_to_copy,
		/* an optional ansno value, only used for ANS frames */
		data->ansno,
		/* no mime configuration, already handled from vortex channel module */
		NULL, 
		/* no mime configuration for transfer encoding, 
		 * already handler by vortex channel module */
		NULL, 
		/* the frame payload itself */
		payload,
		/* calculated frame size */
		&(packet->the_size),
		/* buffer and its size */
		ctx->sequencer_send_buffer, ctx->sequencer_send_buffer_size);

	/* update fixed more flag on packet */
	packet->fixed_more = data->fixed_more;
	
	/* return size used from the entire message */
	return size_to_copy;
}
예제 #10
0
/** 
 * implements vortex.tls.start_tls
 */
int lua_vortex_tls_start_tls (lua_State * L) {
	VortexConnection   ** conn;
	VortexConnection    * conn2;
	VortexStatus          status              = VortexError;
	char                * status_msg          = NULL;
	const char          * serverName          = NULL;
	LuaVortexRefs       * references          = NULL;
	
	/* check parameters */
	if (! lua_vortex_check_params (L, "o|zfd")) 
		return 0;

	/* get context */
	conn = lua_touserdata (L, 1);

	/* get serverName value */
	if (lua_gettop (L) > 1)
		serverName = lua_tostring (L, 2);

	/* acquire a reference to the connection during the process */
	if (! vortex_connection_ref (*conn, "start tls")) {
		lua_vortex_error (L, "Failed to acquire reference to the connection during handshake..");
		return 0;
	} /* end if */

	lua_vortex_log (LUA_VORTEX_DEBUG, "Starting TLS process over conn-id=%d, with ref count=%d", 
			vortex_connection_get_id (*conn), vortex_connection_ref_count (*conn));

	/* check for async notification */
	if (lua_gettop (L) > 2) {
		lua_vortex_log (LUA_VORTEX_DEBUG, "Detected async tls activation..");
		/* create reference */
		references = lua_vortex_acquire_references (CONN_CTX (*conn), L, 3, 4, 0);
		
		/* call to start TLS async */
		vortex_tls_start_negotiation (*conn, lua_tostring (L, 2), 
					      lua_vortex_tls_bridge_async_notify,
					      references);
		
		return 0;
	} /* end if */

	/* unlock during operation */
	LUA_VORTEX_UNLOCK (L, axl_false);

	/* call to authenticate in a blocking manner */
	conn2   = vortex_tls_start_negotiation_sync (*conn, serverName, &status, &status_msg);

	lua_vortex_log (LUA_VORTEX_DEBUG, "Finished TLS process with status=%d, message=%s (old ref count: %d)", 
			status, status_msg, vortex_connection_ref_count (*conn));

	/* unlock during operation */
	LUA_VORTEX_LOCK (L, axl_false);

	if (status != 2) {
		/* reduce reference because tls process didn't finished */
		vortex_connection_unref (*conn, "start tls");
	} else {
		/* ok tls was ok, flag old connection as transient to
		 * only unref */
		lua_vortex_log (LUA_VORTEX_DEBUG, "Flagging connection id=%d as transient due to TLS ok status",
				vortex_connection_get_id (*conn));
		lua_vortex_metatable_set_bool (L, 1, "transient", axl_true);
	} /* end if */

	/* build connection result */
	lua_vortex_connection_new_ref (L, conn2, axl_false);
	vortex_connection_unref (conn2, "start tls");

	/* push status */
	lua_pushnumber (L, status);
	lua_pushstring (L, status_msg);
	
	return 3;
}
예제 #11
0
/**
 * @brief  a frame received Callback
 */
void listenerFrameReceivedCallback (VortexChannel* channel,
                                     VortexConnection* connection,
                                     VortexFrame* frame,
                                     axlPointer user_data)
{

  VORTEXListenerFrameReceivedCallbackData* callbackData = (VORTEXListenerFrameReceivedCallbackData*) user_data;

  TML_INT32 iRet = TML_SUCCESS;
  /////////////////////////////////////////////////////////////////////////////
  // Fetching all necessary attributes from Vortex:


  ///////////////////////////
  // Die Connection ID:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_connection_get_id");
  int iConnectionID = vortex_connection_get_id(connection);
  ///////////////////////////
  // Die Host IP:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_connection_get_host_ip");
  const char* sHostIP = vortex_connection_get_host_ip(connection);
  ///////////////////////////
  // Der Port:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_connection_get_local_port");
  const char* sPort = vortex_connection_get_port(connection);
  ///////////////////////////
  // Die Channel ID:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_channel_get_number");
  int iChannelID = vortex_channel_get_number (channel);
  if (-1 == iChannelID)
    iRet = TML_ERR_LISTENER_COMMUNICATION;
  ///////////////////////////
  // Die Message ID:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_frame_get_msgno");
  int iMsgID = vortex_frame_get_msgno (frame);
  if (-1 == iMsgID)
    iRet = TML_ERR_LISTENER_COMMUNICATION;
  ///////////////////////////
  // Das Profil, mit dem der Sender conneted ist:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_channel_get_profile");
  const char* sProfile = vortex_channel_get_profile (channel);
  if (NULL == sProfile)
    iRet = TML_ERR_LISTENER_COMMUNICATION;
  ///////////////////////////
  // Das Payload:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_frame_get_payload");
  char* cPayload = (char*)vortex_frame_get_payload (frame);
  if (NULL == cPayload)
    iRet = TML_ERR_LISTENER_COMMUNICATION;
  ///////////////////////////
  // Die Payloadsize:
  callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_frame_get_payload_size");
  int iPayloadSize = vortex_frame_get_payload_size (frame);
  if (-1 == iPayloadSize)
    iRet = TML_ERR_LISTENER_COMMUNICATION;


  /////////////////////////////////////////////////////////////////////////////
  // Set all necessary Vortex attributes into the TML_COMMAND_HANDLE Obj:
  if (TML_SUCCESS == iRet){
    // A new TML_COMMAND_HANDLE object out of the payload:
    TML_COMMAND_HANDLE cmdHandle;
    iRet = tml_Cmd_Create(&cmdHandle);
    if (TML_SUCCESS == iRet){
      SIDEX_HANDLE sHandle;
      ///////////////////////////////////////////////
      // Acquire critical section use: 
      tml_Cmd_Acquire_Sidex_Handle(cmdHandle, &sHandle);
      iRet = sidex_Set_Content(sHandle, cPayload);
      ///////////////////////////////////////////////
      // Now I can release the critical section use: 
      tml_Cmd_Release_Sidex_Handle(cmdHandle);
    }
    if (TML_SUCCESS == iRet){
      // Vortex- session ID into the TML_COMMAND_HANDLE object:
      tml_Cmd_Attr_Set_Session_ID(cmdHandle, iConnectionID); // Don't mind of return value
      // Vortex- channel ID into the TML_COMMAND_HANDLE object:
      tml_Cmd_Attr_Set_Channel_ID(cmdHandle, iChannelID); // Don't mind of return value
      callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_channel_ref");
      vortex_channel_ref(channel); // I will be shure to have a valid channel until the reply is send
      // Vortex- channel into the TML_COMMAND_HANDLE object:
      tml_Cmd_Attr_Set_Channel(cmdHandle, channel); // Don't mind of return value
      // Vortex- message ID into the TML_COMMAND_HANDLE object:
      tml_Cmd_Attr_Set_Message_ID(cmdHandle, iMsgID); // Don't mind of return value
      // Vortex- profile into the TML_COMMAND_HANDLE object:
      tml_Cmd_Attr_Set_Profile(cmdHandle, sProfile);
      // The core handle:
      tml_Cmd_Attr_Set_Core_Reference(cmdHandle, callbackData->tmlcorehandle); // Don't mind of return value

      TML_CONNECTION_HANDLE connectionHandle = TML_HANDLE_TYPE_NULL;
      //////////////////////////////////////////////////////////////////
      // Add the connection to the list:
      if (NULL != sHostIP && NULL != sPort && NULL != connection){
        ((tmlCoreWrapper*)callbackData->tmlcorehandle)->tmlCoreWrapper_Connect(sHostIP, sPort, false, &connectionHandle, connection);
        ((tmlObjWrapper*)cmdHandle)->tmlObjWrapper_Set_Connection(connectionHandle);
      }

      // Now call the callback method:
      globalCallback(callbackData->callback, (void*) cmdHandle);
    }
  }
  else{
    callbackData->pLog->log ("TMLCoreListener", "listenerFrameReceivedCallback", "ERROR", "Problem on getting some attributes.");
  }
  return;
}