Esempio n. 1
0
PRIVATE rpc_binding_rep_t *rpc__cn_binding_alloc
(
  boolean32               is_server,
  unsigned32              *st
)
{
    rpc_cn_binding_rep_p_t brp;

    CODING_ERROR (st);

    /*
     * A server binding is allocated from the receiver thread which
     * has already acquired the CN global mutex.
     */
    if (!is_server)
    {
        RPC_CN_LOCK ();
    }
    else
    {
        RPC_CN_LOCK_ASSERT ();
    }

    /*
     * Allocate a binding rep off the lookaside list.
     */
    brp = (rpc_cn_binding_rep_p_t)
        rpc__list_element_alloc (&rpc_g_cn_binding_lookaside_list,
                                 true);
    if (brp == NULL)
    {
        *st = rpc_s_no_memory;
        RPC_CN_UNLOCK ();
        return NULL;
    }
    if (!is_server)
    {
        ((rpc_cn_binding_rep_t *)brp)->being_resolved = false;
        RPC_CN_UNLOCK ();
    }

    brp->common.rpc_addr = NULL;
    brp->common.auth_info = NULL;
    brp->common.transport_info = NULL;

    *st = rpc_s_ok;
    return ((rpc_binding_rep_p_t) brp);
}
Esempio n. 2
0
PRIVATE void rpc__cn_binding_init
(
 rpc_binding_rep_p_t     binding_r,
 unsigned32              *st
)
{
    unsigned32                  type;
    rpc_cn_local_id_t           grp_id;

    CODING_ERROR (st);

    /*
     * Determine the type of association group we are looking for.
     */
    if (RPC_BINDING_IS_SERVER (binding_r))
    {
        type = RPC_C_CN_ASSOC_GRP_SERVER;
    }
    else
    {
        type = RPC_C_CN_ASSOC_GRP_CLIENT;

        /*
         * Use the RPC address contained in the binding rep to find an
         * association group.
         */
        RPC_CN_LOCK ();
        grp_id = rpc__cn_assoc_grp_lkup_by_addr (binding_r->rpc_addr,
                                                 binding_r->transport_info,
                                                 type,
                                                 st);

        /*
         * Record its the association group id returned into the
         * binding rep. Note that the group id returned may be invalid.
         */
        ((rpc_cn_binding_rep_t *)binding_r)->grp_id = grp_id;
        RPC_CN_UNLOCK ();
    }

    /*
     * Return a good status code no matter what happened.
     */
    *st = rpc_s_ok;
}
Esempio n. 3
0
PRIVATE void rpc__cn_call_executor 
(pointer_t arg, boolean32 call_was_queued ATTRIBUTE_UNUSED) 
{
    rpc_binding_rep_t           *binding_r;
    rpc_cn_call_rep_t           *call_r;
    rpc_iovector_t              iovector;
    dce_uuid_t                      type_uuid;
    rpc_mgr_epv_t               manager_epv;
    rpc_v2_server_stub_epv_t    server_stub_epv;
    rpc_if_rep_p_t              if_spec_rep;
    unsigned32                  flags;
    unsigned32                  max_calls;
    unsigned32                  max_rpc_size;
    rpc_if_callback_fn_t        if_callback;
    unsigned32                  status;

    RPC_LOG_CN_CTHD_NTR;

    RPC_DBG_PRINTF (rpc_e_dbg_general, RPC_C_CN_DBG_GENERAL,
                   ("CN: call_rep->%x call executor running ... %s queued\n", arg, (call_was_queued ? "WAS" : "WAS NOT")));

    /*
     * The arg passed in is really a call rep.
     */
    call_r = (rpc_cn_call_rep_t *) arg;

    /*
     * Release the call rep lock which was acquired for us in the
     * common code.
     */
    RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);

    /*
     * If there is an object uuid, see if there's a type uuid
     * associated with it.
     */
    rpc_object_inq_type (&call_r->binding_rep->obj, &type_uuid, &status);
    if ((status != rpc_s_object_not_found) && (status != rpc_s_ok))
    {
        RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
        rpc__cthread_cancel_caf ((rpc_call_rep_t *) call_r);
        RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);
        RPC_CN_LOCK ();
        rpc__cn_call_reject ((rpc_call_rep_p_t) call_r, status);
        RPC_CN_UNLOCK ();
        goto CLEANUP;
    }
    
    /*
     * Get the if rep and the server stub and manager EPV.
     */
    rpc__if_lookup2 (call_r->u.server.if_id,
                     call_r->u.server.if_vers,
                     &type_uuid, 
                     &call_r->u.server.ihint, 
                     &if_spec_rep,
                     &server_stub_epv, 
                     &manager_epv, 
                     &flags, 
                     &max_calls, 
                     &max_rpc_size, 
                     &if_callback, 
                     &status);
    if (status != rpc_s_ok)
    {
        RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
        rpc__cthread_cancel_caf ((rpc_call_rep_t *) call_r);
        RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);
        RPC_CN_LOCK ();
        rpc__cn_call_reject ((rpc_call_rep_p_t) call_r, status);
        RPC_CN_UNLOCK ();
        goto CLEANUP;
    }
    
    /*
     * If the operation number is out of range, indicate a fault to
     * the protocol service, otherwise process the incoming packet(s).
     */
    if (call_r->opnum >= if_spec_rep->opcnt)
    {
        RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
        rpc__cthread_cancel_caf ((rpc_call_rep_t *) call_r);
        RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);
        RPC_CN_LOCK ();
        rpc__cn_call_reject ((rpc_call_rep_p_t) call_r, rpc_s_op_rng_error);
        RPC_CN_UNLOCK ();
        goto CLEANUP;
    }

    /*
     * Receive the first packet.
     */
    rpc__cn_call_receive ((rpc_call_rep_t *) call_r,
                          &iovector.elt[0], 
                          &status);
    if (status != rpc_s_ok)
    {
        RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
        rpc__cthread_cancel_caf ((rpc_call_rep_t *) call_r);
        RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);
        RPC_CN_LOCK ();
        rpc__cn_call_reject ((rpc_call_rep_p_t) call_r, rpc_s_op_rng_error);
        RPC_CN_UNLOCK ();
        goto CLEANUP;
    }
    
    /*
     * Mark the call as having executed.
     */
    call_r->call_executed = true;
    
    /*
     * Enable posting of cancels to this call executor thread.
     * This will also post any queued cancels.
     */
    RPC_DBG_PRINTF (rpc_e_dbg_cancel, RPC_C_CN_DBG_CANCEL,
                   ("(rpc__cn_call_executor) call_rep->%x enabling posting of cancels and posting any queued cancels\n", call_r));
    RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
    rpc__cthread_cancel_enable_post ((rpc_call_rep_p_t) call_r);
    RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);
   
    /*
     * Dispatch appropriately depending on the stub version.
     */
    switch (if_spec_rep->stub_rtl_if_vers)
    {
        /*
         * If this is an old v0 or v1 stub runtime interface
         * then do the dirty work out of line.
         */
        case 0:
        case 1:
	/*
	 * rpc_m_pre_v2_ifspec
	 * "(%s) Pre-v2 interface spec"
	 */
	RPC_DCE_SVC_PRINTF ((
	    DCE_SVC(RPC__SVC_HANDLE, "%s"),
	    rpc_svc_server_call,
	    svc_c_sev_fatal | svc_c_action_abort,
	    rpc_m_pre_v2_ifspec,
	    "rpc__cn_call_executor" ));
	break;

        /*
         * This is the v2 (new) stub runtime interface.
         */
        case 2:
        
        RPC_LOG_SERVER_STUB_PRE;
        ((*server_stub_epv[call_r->opnum])) 
        ((handle_t) call_r->binding_rep,
         (rpc_call_handle_t) call_r,
         &iovector.elt[0],
         &(RPC_CN_ASSOC_NDR_FORMAT (call_r->assoc)),
         &call_r->transfer_syntax,
         manager_epv, 
         &status);
        RPC_LOG_SERVER_STUB_POST;
        break;
        
        /*
         * Unknown version
         */
        default:
	/*
	 * rpc_m_unk_ifspec
	 * "(%s) Unknown interface spec version"
	 */
	RPC_DCE_SVC_PRINTF ((
	    DCE_SVC(RPC__SVC_HANDLE, "%s"),
	    rpc_svc_server_call,
	    svc_c_sev_fatal | svc_c_action_abort,
	    rpc_m_pre_v2_ifspec,
	    "rpc__cn_call_executor" ));
	break;
    }

    /*
     * Check for an error while in the server stub but before the
     * manager routine was entered.
     */
    if (status != rpc_s_ok)
    {
        RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
        rpc__cthread_cancel_caf ((rpc_call_rep_t *) call_r);
        RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);
        RPC_CN_LOCK ();
        rpc__cn_call_reject ((rpc_call_rep_p_t) call_r, status);
        RPC_CN_UNLOCK ();
        goto CLEANUP;
    }

    /*
     * If the stub returned successfully, end the call and free the binding handle.
     */
    binding_r = (rpc_binding_rep_t *) call_r->binding_rep;
    RPC_CALL_LOCK ((rpc_call_rep_t *) call_r);
    rpc__cthread_cancel_caf ((rpc_call_rep_t *) call_r);
    RPC_CALL_UNLOCK ((rpc_call_rep_t *) call_r);

CLEANUP:
    binding_r = (rpc_binding_rep_t *) call_r->binding_rep;
    rpc__cn_call_end ((rpc_call_rep_p_t *) &call_r, &status);
    RPC_LOCK (0);
    RPC_BINDING_RELEASE (&binding_r,
                         &status);
    RPC_UNLOCK (0);
    RPC_LOG_CN_CTHD_XIT;
}
Esempio n. 4
0
PRIVATE void rpc__cn_binding_inq_addr
(
  rpc_binding_rep_p_t     binding_r,
  rpc_addr_p_t            *rpc_addr,
  unsigned32              *st
)
{
    unsigned32          type;
    rpc_cn_local_id_t   grp_id;
    rpc_cn_assoc_grp_t  *assoc_grp;
    rpc_protseq_id_t    protseq_id;

    CODING_ERROR (st);

    /*
     * Determine the type of association group we are looking for.
     */
    if (RPC_BINDING_IS_SERVER (binding_r))
    {
        type = RPC_C_CN_ASSOC_GRP_SERVER;
    }
    else
    {
        type = RPC_C_CN_ASSOC_GRP_CLIENT;
    }

    /*
     * Use the group id contained in the binding rep to find an
     * association group.
     */
    RPC_CN_LOCK ();
    grp_id = rpc__cn_assoc_grp_lkup_by_id (
                 ((rpc_cn_binding_rep_t *)binding_r)->grp_id,
                 type,
                 binding_r->transport_info,
                 st);

    /*
     * Check whether an association group was found or not.
     */
    if (RPC_CN_LOCAL_ID_VALID (grp_id))
    {
        /*
         * An association group was found. Check whether it
         * contains an RPC address.
         */
        assoc_grp = RPC_CN_ASSOC_GRP (grp_id);
        if (assoc_grp->grp_address != NULL)
        {
            /*
             * The association group contains an RPC address.
             * Copy it into the binding.
             */
            rpc__naf_addr_copy (assoc_grp->grp_address,
                                rpc_addr,
                                st);
        }
        else
        {
            /*
             * The association doesn't have an RPC address. Find
             * it out using one of the connections attached to the
             * association group.
             */
            rpc__naf_desc_inq_protseq_id
                (((rpc_cn_assoc_t *)assoc_grp->grp_assoc_list.next)->cn_ctlblk.cn_sock,
                 RPC_C_PROTOCOL_ID_NCACN,
                 &protseq_id,
                 st);
            if (*st == rpc_s_ok)
            {
                rpc__naf_desc_inq_peer_addr
                    (((rpc_cn_assoc_t *)assoc_grp->grp_assoc_list.next)->cn_ctlblk.cn_sock,
                     protseq_id,
                     rpc_addr,
                     st);
                if (*st == rpc_s_ok)
                {
                    rpc__naf_addr_copy (*rpc_addr,
                                        &assoc_grp->grp_address,
                                        st);
                }
            }
        }
        binding_r->rpc_addr = *rpc_addr;
    }
    else
    {
        *st = rpc_s_connection_closed;
    }
    RPC_CN_UNLOCK ();
}