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); }
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); }
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); }
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; }
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); } }
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; }
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; } } }
/* * 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; }
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; }