示例#1
0
void
ORBit_handle_system_exception (CORBA_Environment *ev,
			       const CORBA_char *nom,
			       CORBA_completion_status status,
			       GIOPRecvBuffer *buf,
			       GIOPSendBuffer *sendbuf)
{
	CORBA_exception_set_system (ev, nom, status);
	giop_recv_buffer_unuse (buf);
	giop_send_buffer_unuse (sendbuf);
}
示例#2
0
static void
giop_connection_remove_frag (GIOPConnection *cnx, GList *frags)
{
	GList *l;

	g_return_if_fail (frags != NULL);

	for (l = frags->next; l; l = l->next)
		giop_recv_buffer_unuse (l->data);

	cnx->incoming_frags = g_list_remove (cnx->incoming_frags, frags);
	g_list_free (frags);
}
示例#3
0
void
giop_recv_list_zap (GIOPConnection *cnx)
{
	GList  *l, *next;
	GSList *sl, *notify = NULL;

	LINK_MUTEX_LOCK (giop_queued_messages_lock);

	for (l = giop_queued_messages; l; l = next) {
		GIOPMessageQueueEntry *ent = l->data;

		next = l->next;

		if (ent->cnx == cnx) {
			ent_lock (ent);

			dprintf (ERRORS, "Zap listener on dead cnx with buffer %p\n",
				 ent->buffer);

			giop_recv_buffer_unuse (ent->buffer);
			ent->buffer = NULL;

			giop_recv_destroy_queue_entry_T (ent);

			if (giop_thread_io () && !ent->async_cb)
				giop_incoming_signal_T (ent->src_thread, GIOP_CLOSECONNECTION);
			ent_unlock (ent);

			if (ent->async_cb)
				notify = g_slist_prepend (notify, ent);
			giop_queued_messages = g_list_delete_link (
				giop_queued_messages, l);
		}
	}

	LINK_MUTEX_UNLOCK (giop_queued_messages_lock);

	for (sl = notify; sl; sl = sl->next) {
		GIOPMessageQueueEntry *ent = sl->data;
		
		if (!ent->async_cb) {
			/* This should never happen */
			g_warning ("Extraordinary recv list re-enterancy");
			continue;
		}

		giop_invoke_async (ent);
	}
	g_slist_free (notify);
}
示例#4
0
void
giop_connection_destroy_frags (GIOPConnection *cnx)
{
	GList *l;

	for (l = cnx->incoming_frags; l; l = l->next) {
		GList *l2;

		for (l2 = l->data; l2; l2 = l2->next)
			giop_recv_buffer_unuse (l2->data);

		g_list_free (l->data);
	}
	g_list_free (cnx->incoming_frags);
	cnx->incoming_frags = NULL;
}
示例#5
0
CORBA_Object
CORBA_ORB_string_to_object (CORBA_ORB          orb,
			    const CORBA_char  *string,
			    CORBA_Environment *ev)
{
	CORBA_Object         retval = CORBA_OBJECT_NIL;
	CORBA_unsigned_long  len;
	GIOPRecvBuffer      *buf;
#if defined ENABLE_HTTP
	gchar               *ior = NULL;
#endif
	guchar              *tmpbuf;
	int                  i;

	if (strncmp (string, "IOR:", strlen("IOR:"))            &&
	    strncmp (string, "corbaloc:", strlen ("corbaloc:")) &&
	    strncmp (string, "iiop:", strlen ("iiop:"))         &&
	    strncmp (string, "iiops:", strlen ("iiops:"))       &&
	    strncmp (string, "ssliop:", strlen ("ssliop:"))     &&
	    strncmp (string, "uiop:", strlen ("uiop:"))) {

#if defined ENABLE_HTTP
		if (matecorba_use_http_iors &&
		    strstr (string, "://")) {
			/* FIXME: this code is a security hazard */
			ior = orb_http_resolve (string);
			if (!ior) {
				/* FIXME, set error minor code
				 * (vendor's error code) to tell user
				 * initial location of error, ie my
				 * local ORB, proxy's ORB, server's
				 * ORB, etc. */
				CORBA_exception_set_system (
					ev,
					ex_CORBA_BAD_PARAM,
					CORBA_COMPLETED_NO);

				return CORBA_OBJECT_NIL;
			}
			string = ior;
		} else
#endif
		{
			CORBA_exception_set_system (
					ev,
					ex_CORBA_BAD_PARAM,
					CORBA_COMPLETED_NO);

			return CORBA_OBJECT_NIL;
		}
	}

	if (!strncmp (string, "IOR:", strlen ("IOR:")))
	{
		string += 4;
		len = strlen (string);
		while (len > 0 && !g_ascii_isxdigit (string [len - 1]))
			len--;

		if (len % 2) {
#if defined ENABLE_HTTP
			g_free (ior);
#endif
			return CORBA_OBJECT_NIL;
		}

		tmpbuf = g_alloca (len / 2);

		for (i = 0; i < len; i += 2)
			tmpbuf [i/2] = (g_ascii_xdigit_value (string [i]) << 4) |
				g_ascii_xdigit_value (string [i + 1]);

		buf = giop_recv_buffer_use_encaps (tmpbuf, len / 2);

		if (MateCORBA_demarshal_object (&retval, buf, orb)) {
			CORBA_exception_set_system (
				ev,
				ex_CORBA_MARSHAL,
				CORBA_COMPLETED_NO);

			retval = CORBA_OBJECT_NIL;
		}

		giop_recv_buffer_unuse (buf);
#if defined ENABLE_HTTP
		g_free (ior);
#endif
		return retval;
	} else {
		return MateCORBA_object_by_corbaloc (orb, string, ev);
	}
}
示例#6
0
static GIOPConnection *
do_demarshal (CV *cv, I32 ax, I32 items,
	      CORBA_InterfaceDef_FullInterfaceDescription *desc, I32 index, 
	      GPtrArray *return_types,
	      guint *return_count,
	      CORBA_Object obj, GIOPConnection *connection,
	      GIOP_unsigned_long request_id)
{
    GIOPRecvBuffer *recv_buffer;
    SV *error_sv = NULL;
    SV **results = NULL;
    CORBA_unsigned_long i;
    CORBA_OperationDescription *opr = NULL;

    dTHR;
    
    if (index >= PORBIT_OPERATION_BASE && index < PORBIT_GETTER_BASE)
	opr = &desc->operations._buffer[index-PORBIT_OPERATION_BASE];

    recv_buffer = giop_recv_reply_buffer_use_2(connection, request_id, TRUE);
    if (!recv_buffer) {
	    error_sv =
		porbit_system_except ("IDL:omg.org/CORBA/COMM_FAILURE:1.0",
				      0, CORBA_COMPLETED_MAYBE);
	    goto exception;
    }
	
    if (recv_buffer->message.u.reply.reply_status == GIOP_LOCATION_FORWARD) {

	if (obj->forward_locations != NULL)
	    ORBit_delete_profiles(obj->forward_locations);
	obj->forward_locations = ORBit_demarshal_IOR(recv_buffer);
	connection = ORBit_object_get_forwarded_connection(obj);
	
	giop_recv_buffer_unuse(recv_buffer);

	return connection;
	
    } else if (recv_buffer->message.u.reply.reply_status != GIOP_NO_EXCEPTION) {
	error_sv = porbit_get_exception (recv_buffer, NULL,
					 recv_buffer->message.u.reply.reply_status, opr);
	if (!error_sv)
	    error_sv = porbit_system_except ("IDL:omg.org/CORBA/MARSHAL:1.0", 
					     0, CORBA_COMPLETED_YES);

	goto exception;
    }

    /* Demarshal return parameters */

    results = g_new0 (SV *, return_types->len);
    for (i=0; i<return_types->len; i++) {
	results[i] = porbit_get_sv (recv_buffer, return_types->pdata[i]);
	if (!results[i]) {
	    warn ("Error demarshalling result");
	    error_sv = porbit_system_except ("IDL:omg.org/CORBA/MARSHAL:1.0", 
					     0, CORBA_COMPLETED_YES);

	    goto exception;
	}
    }
    
    if (index >= PORBIT_OPERATION_BASE && index < PORBIT_GETTER_BASE) {

	CORBA_unsigned_long i, st_index, ret_index;

	/* First write back INOUT parameters into their references.
	 * (Is this safe? If we end up calling back to perl, could the
	 *  stack already be overridden?)
	 */
	st_index = 1;
	ret_index = (opr->result->kind == CORBA_tk_void) ? 0 : 1;
	for (i = 0 ; i<opr->parameters._length; i++) {
	    switch (opr->parameters._buffer[i].mode) {
	    case CORBA_PARAM_IN:
		st_index++;
		break;
	    case CORBA_PARAM_INOUT:
		sv_setsv (SvRV(ST(st_index)), results[ret_index]);
		st_index++;
		ret_index++;
		break;
	    case CORBA_PARAM_OUT:
		ret_index++;
		break;
	    }
	}

	/* Now write out return value and OUT parameters to stack
	 */
	st_index = 0;
	ret_index = 0;
	if (opr->result->kind != CORBA_tk_void) {
	    ST(st_index) = sv_2mortal(results[0]);
	    st_index++;
	    ret_index++;
	}

	for (i = 0 ; i<opr->parameters._length; i++) {
	    switch (opr->parameters._buffer[i].mode) {
	    case CORBA_PARAM_IN:
		break;
	    case CORBA_PARAM_INOUT:
		ret_index++;
		break;
	    case CORBA_PARAM_OUT:
		ST(st_index) = sv_2mortal (results[ret_index]);
		st_index++;
		ret_index++;
		break;
	    }
	}

	*return_count = st_index;
    } else if (index >= PORBIT_GETTER_BASE && index < PORBIT_SETTER_BASE) {
	ST(0) = sv_2mortal(results[0]);
    }
    
    g_free (results);
    results = NULL;
    
 exception:
    if (results) {
	for (i=0; i < return_types->len; i++)
	    if (results[i])
		SvREFCNT_dec (results[i]);
	g_free (results);
    }
    g_ptr_array_free (return_types, TRUE);
    giop_recv_buffer_unuse(recv_buffer);
    
    if (error_sv)
	porbit_throw (error_sv);

    return NULL;
}
示例#7
0
Account
factory_newAccount(factory _obj, const CORBA_unsigned_long balance,
		   CORBA_Environment * ev)
{
   register GIOP_unsigned_long _ORBIT_request_id,
    _ORBIT_system_exception_minor;
   register CORBA_completion_status _ORBIT_completion_status;
   register GIOPSendBuffer *_ORBIT_send_buffer;
   register GIOPRecvBuffer *_ORBIT_recv_buffer;
   register GIOPConnection *_cnx;
   Account _ORBIT_retval;

   if (_obj->servant && _obj->vepv && factory__classid) {
      _ORBIT_retval =
	 ((POA_factory__epv *) _obj->vepv[factory__classid])->
	 newAccount(_obj->servant, balance, ev);
      return _ORBIT_retval;
   }
   _cnx = ORBit_object_get_connection(_obj);
 _ORBIT_retry_request:
   _ORBIT_send_buffer = NULL;
   _ORBIT_recv_buffer = NULL;
   _ORBIT_completion_status = CORBA_COMPLETED_NO;
   _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
   {				/* marshalling */
      static const struct
      {
	 CORBA_unsigned_long len;
	 char opname[11];
      }
      _ORBIT_operation_name_data =
      {
      11, "newAccount"};
      static const struct iovec _ORBIT_operation_vec =
	 { (gpointer) & _ORBIT_operation_name_data, 15 };

      _ORBIT_send_buffer =
	 giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
				      CORBA_TRUE,
				      &(_obj->active_profile->object_key_vec),
				      &_ORBIT_operation_vec,
				      &ORBit_default_principal_iovec);

      _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
      if (!_ORBIT_send_buffer)
	 goto _ORBIT_system_exception;
      giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
				       (_ORBIT_send_buffer), 4);
      giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
				     &(balance), sizeof(balance));
      giop_send_buffer_write(_ORBIT_send_buffer);
      _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
      giop_send_buffer_unuse(_ORBIT_send_buffer);
      _ORBIT_send_buffer = NULL;
   }
   {				/* demarshalling */
      register guchar *_ORBIT_curptr;

      _ORBIT_recv_buffer =
	 giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
      if (!_ORBIT_recv_buffer)
	 goto _ORBIT_system_exception;
      _ORBIT_completion_status = CORBA_COMPLETED_YES;
      if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
	  GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
      _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
      if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
	 GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
	 _ORBIT_retval =
	    ORBit_demarshal_object(_ORBIT_recv_buffer,
				   GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
				   connection->orb_data);
	 _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
      } else {
	 GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
	 _ORBIT_retval =
	    ORBit_demarshal_object(_ORBIT_recv_buffer,
				   GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
				   connection->orb_data);
	 _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
      }
      giop_recv_buffer_unuse(_ORBIT_recv_buffer);
      return _ORBIT_retval;
    _ORBIT_system_exception:
      CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
				 _ORBIT_completion_status);
      giop_recv_buffer_unuse(_ORBIT_recv_buffer);
      giop_send_buffer_unuse(_ORBIT_send_buffer);
      return _ORBIT_retval;
    _ORBIT_msg_exception:
      if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
	  GIOP_LOCATION_FORWARD) {
	 if (_obj->forward_locations != NULL)
	    ORBit_delete_profiles(_obj->forward_locations);
	 _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
	 _cnx = ORBit_object_get_forwarded_connection(_obj);
	 giop_recv_buffer_unuse(_ORBIT_recv_buffer);

	 goto _ORBIT_retry_request;
      } else {
	 ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
	 giop_recv_buffer_unuse(_ORBIT_recv_buffer);
	 return _ORBIT_retval;
      }
   }
}
示例#8
0
/*
 * FIXME: we should definately handle things more asynchronously,
 * perhaps even at the expense of having to go to the GSource
 * twice in order to get fresh input (?)
 * or should we poll ourselves on the source to see what's up?
 *
 * The whole locking concept here looks broken to me,
 * especially since 'read' can flag the connection disconnected
 * giving a nice deadlock.
 */
gboolean
giop_connection_handle_input (LinkConnection *lcnx)
{
	GIOPRecvBuffer *buf;
	GIOPConnection *cnx = (GIOPConnection *) lcnx;

	do {
		int n;

		if (!cnx->incoming_msg)
			cnx->incoming_msg = giop_recv_buffer_use_buf (cnx);

		buf = cnx->incoming_msg;

		n = link_connection_read (
			lcnx, buf->cur, buf->left_to_read, FALSE);

		if (n == 0) /* We'll be back */
			return TRUE;

		if (n < 0 || !buf->left_to_read) /* HUP */
			goto msg_error;

/*		fprintf (stderr, "Read %d\n", n);
		giop_dump (stderr, buf->cur, n, 0); */

		buf->left_to_read -= n;
		buf->cur += n;

		if (buf->left_to_read == 0) {

#ifdef G_ENABLE_DEBUG
			if (giop_debug_hook_incoming_mangler)
				giop_debug_hook_incoming_mangler (buf);
#endif

			switch (buf->state) {

			case GIOP_MSG_READING_HEADER:
				if (giop_recv_msg_reading_body (buf, cnx->parent.is_auth)) {
					dprintf (ERRORS, "OOB incoming msg header data\n");
					goto msg_error;
				}
				buf->state = GIOP_MSG_READING_BODY;
				break;

			case GIOP_MSG_READING_BODY: {

				dprintf (GIOP, "Incoming IIOP body:\n");

				buf->cur = buf->message_body + 12;
				if ((buf->cur + buf->msg.header.message_size) > buf->end) {
					dprintf (ERRORS, "broken incoming length data\n");
					goto msg_error;
				}
				do_giop_dump (stderr, buf->cur, buf->msg.header.message_size, 12);

				buf->state = GIOP_MSG_READY;

				if (giop_recv_buffer_demarshal (buf)) {
					dprintf (ERRORS, "broken incoming header data\n");
					goto msg_error;
				}

				if (MORE_FRAGMENTS_FOLLOW (buf)) {
					if (giop_recv_buffer_handle_fragmented (&buf, cnx))
						goto msg_error;

					else {
						cnx->incoming_msg = NULL;
						goto frag_out;
					}

				} else if (buf->msg.header.message_type == GIOP_FRAGMENT) {
					if (giop_recv_buffer_handle_fragmented (&buf, cnx))
						goto msg_error;
					/* else last fragment */
				}
				break;
			}

			case GIOP_MSG_AWAITING_FRAGMENTS:
			case GIOP_MSG_READY:
				g_assert_not_reached ();
				break;
			}
		}

	} while (cnx->incoming_msg &&
		 buf->left_to_read > 0 &&
		 buf->state != GIOP_MSG_READY);

	cnx->incoming_msg = NULL;

	switch (buf->msg.header.message_type) {
	case GIOP_REPLY:
	case GIOP_LOCATEREPLY:
		dprintf (MESSAGES, "handling reply\n");
		if (handle_reply (buf)) /* dodgy inbound data, pull the cnx */
			link_connection_state_changed (lcnx, LINK_DISCONNECTED);
		break;

	case GIOP_REQUEST:
		dprintf (MESSAGES, "handling request\n");
		ORBit_handle_request (cnx->orb_data, buf);
		break;

	case GIOP_LOCATEREQUEST:
		dprintf (MESSAGES, "handling locate request\n");
		ORBit_handle_locate_request (cnx->orb_data, buf);
		break;

	case GIOP_CANCELREQUEST:
	case GIOP_MESSAGEERROR:
		dprintf (ERRORS, "dropping an unusual & unhandled input buffer 0x%x",
			 buf->msg.header.message_type);
		giop_recv_buffer_unuse (buf);
		break;

	case GIOP_CLOSECONNECTION:
		dprintf (MESSAGES, "received close connection\n");
		giop_recv_buffer_unuse (buf);
		link_connection_state_changed (lcnx, LINK_DISCONNECTED);
		break;

	case GIOP_FRAGMENT:
		dprintf (ERRORS, "Fragment got in the wrong channel\n");
	default:
		dprintf (ERRORS, "dropping an out of bound input buffer "
			 "on the floor 0x%x\n", buf->msg.header.message_type);
		goto msg_error;
		break;
	}

 frag_out:	
	return TRUE;

 msg_error:
	cnx->incoming_msg = NULL;

	buf->msg.header.message_type = GIOP_MESSAGEERROR;
	buf->msg.header.message_size = 0;

	giop_recv_buffer_unuse (buf);

	/* Zap it for badness.
	 * XXX We should probably handle oversized
	 * messages more graciously XXX */
	link_connection_state_changed (LINK_CONNECTION (cnx),
				       LINK_DISCONNECTED);

	return TRUE;
}
示例#9
0
static gboolean
handle_reply (GIOPRecvBuffer *buf)
{
	GList                 *l;
	gboolean               error;
	GIOPMessageQueueEntry *ent;
	CORBA_unsigned_long    request_id;

	request_id = giop_recv_buffer_get_request_id (buf);

	error = FALSE;

	LINK_MUTEX_LOCK (giop_queued_messages_lock);

	for (l = giop_queued_messages; l; l = l->next) {
		ent = l->data;

		if (ent->request_id == request_id &&
		    ent->msg_type == buf->msg.header.message_type)
			break;
	}

	ent = l ? l->data : NULL;

	if (!ent) {
		if (giop_recv_buffer_reply_status (buf) ==
		    CORBA_SYSTEM_EXCEPTION) {
			/*
			 * Unexpected - but sometimes a oneway
			 * method invocation on a de-activated
			 * object results in us getting a bogus
			 * system exception in reply.
			 */
 		} else {
#ifdef G_ENABLE_DEBUG
			if (giop_debug_hook_unexpected_reply)
				giop_debug_hook_unexpected_reply (buf);
			else
				dprintf (ERRORS, "We received an unexpected reply\n");
#endif /* G_ENABLE_DEBUG */
			error = TRUE;
		}

	} else if (ent->cnx != buf->connection) {
#ifdef G_ENABLE_DEBUG
		if (giop_debug_hook_spoofed_reply)
			giop_debug_hook_spoofed_reply (buf, ent);
#endif
		dprintf (ERRORS, "We received a bogus reply\n");

		error = TRUE;

	} else {
#ifdef DEBUG
		g_warning ("Pop XX:%p:%p - %d",
			   ent, ent->async_cb,
			   g_list_length (giop_queued_messages));
#endif
		giop_queued_messages = g_list_delete_link
			(giop_queued_messages, l);
	}

	LINK_MUTEX_UNLOCK (giop_queued_messages_lock);

	if (ent && !error) {
		gboolean async = FALSE;

		ent_lock (ent);
		ent->buffer = buf;

		if (giop_thread_io () && !ent->async_cb)
			giop_incoming_signal_T (ent->src_thread,
						GIOP_REPLY);

		else if (ent->async_cb)
			async = TRUE;

		ent_unlock (ent);

		if (async)
			giop_invoke_async (ent);

		buf = NULL;
	}
	
	giop_recv_buffer_unuse (buf);

	return error;
}