|
|
BSD 4.3reno
/* dapinvoke.c - DAP : Invoke DAP operations */
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/dsap/net/dapinvoke.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $";
#endif
/*
* $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/dsap/net/dapinvoke.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $
*
*
* $Log: dapinvoke.c,v $
* Revision 1.1.1.1 2018/04/24 16:12:56 root
* BSD 4.3reno
*
* Revision 7.0 90/07/26 14:45:21 mrose
* *** empty log message ***
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
/* LINTLIBRARY */
#include <stdio.h>
#include "logger.h"
#include "quipu/util.h"
#include "quipu/dap2.h"
extern LLog * log_dsap;
extern void ros_log();
#ifdef PDU_DUMP
#define DUMP_ARG "arg"
#define DUMP_RES "res"
#define DUMP_ERR "err"
#endif
int DapInvokeReqAux (sd, id, op, pe, di, asyn)
int sd;
int id;
int op;
PE pe;
struct DAPindication * di;
int asyn;
{
#ifdef PDU_DUMP
pdu_dump (pe,DUMP_ARG,op);
#endif
#ifdef HEAVY_DEBUG
pdu_arg_log (pe, op);
#endif
switch (asyn)
{
case ROS_SYNC:
return (DapSyncInvokeRequest (sd, id, op, pe, di));
case ROS_INTR:
return (DapIntrInvokeRequest (sd, id, op, pe, di));
case ROS_ASYNC:
return (DapAsynInvokeRequest (sd, id, op, pe, di));
default:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapInvokeReqAux(): asyn has unknown value: %d", asyn));
return (daplose (di, DP_INVOKE, NULLCP, "Unknown synchronicity"));
}
}
int DapSyncInvokeRequest (sd, id, op, pe, di)
int sd;
int id;
int op;
PE pe;
struct DAPindication * di;
{
int result;
struct RoSAPindication roi_s;
struct RoSAPindication * roi = &(roi_s);
struct RoSAPpreject * rop = &(roi->roi_preject);
DLOG (log_dsap,LLOG_TRACE,( "DapSyncInvokeRequest()"));
result = RoInvokeRequest (sd, op, ROS_SYNC, pe,
id, NULLIP, ROS_NOPRIO, roi);
if (result != OK)
{
if (roi->roi_type != ROI_PREJECT)
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest(): Failed without rejection"));
return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest inconsistent result"));
}
if (ROS_FATAL (rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER))
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest(): Fatal rejection"));
return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest failed"));
}
else
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest(): Non-Fatal rejection"));
return (dapreject (di, DP_INVOKE, id, NULLCP, "RoInvokeRequest failed"));
}
}
switch(roi->roi_type)
{
case ROI_INVOKE:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Invocation received"));
DRejectRequest (sd, ROS_IP_UNRECOG, roi->roi_invoke.rox_id);
return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept invokes"));
case ROI_RESULT:
return (DapDecodeResult (sd, &(roi->roi_result), di));
case ROI_ERROR:
return (DapDecodeError (sd, &(roi->roi_error), di));
case ROI_UREJECT:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Operation (%d) user rejected (%d)", roi->roi_ureject.rou_id, roi->roi_ureject.rou_reason));
return (ros2dapreject (di, "ROI_UREJECT", &(roi->roi_ureject)));
case ROI_PREJECT:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Operation (%d) provider rejected", roi->roi_preject.rop_id));
return (ros2daplose (di, "ROI_PREJECT", &(roi->roi_preject)));
case ROI_FINISH:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapSyncInvokeRequest: Unbind request received"));
return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept unbind requests"));
default:
LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown indication type : %d", roi->roi_type));
break;
}
return (OK);
}
int DapIntrInvokeRequest (sd, id, op, pe, di)
int sd;
int id;
int op;
PE pe;
struct DAPindication * di;
{
int result;
struct RoSAPindication roi_s;
struct RoSAPindication * roi = &(roi_s);
struct RoSAPpreject * rop = &(roi->roi_preject);
DLOG (log_dsap,LLOG_TRACE,( "DapIntrInvokeRequest()"));
result = RoIntrRequest (sd, op, pe, id, NULLIP, ROS_NOPRIO, roi);
if (result != OK)
{
if (roi->roi_type != ROI_PREJECT)
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest(): Failed without rejection"));
return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest inconsistent result"));
}
if (rop->rop_reason == ROS_INTERRUPTED)
{
return (DapInterrupt(sd, id, op, di));
}
if (ROS_FATAL (rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER))
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest(): Fatal rejection"));
return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest failed"));
}
else
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest(): Non-Fatal rejection"));
return (dapreject (di, DP_INVOKE, id, NULLCP, "RoInvokeRequest failed"));
}
}
switch(roi->roi_type)
{
case ROI_INVOKE:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Invocation received"));
DRejectRequest (sd, ROS_IP_UNRECOG, roi->roi_invoke.rox_id);
return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept invokes"));
case ROI_RESULT:
return (DapDecodeResult (sd, &(roi->roi_result), di));
case ROI_ERROR:
return (DapDecodeError (sd, &(roi->roi_error), di));
case ROI_UREJECT:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Operation (%d) user rejected (%d)", roi->roi_ureject.rou_id, roi->roi_ureject.rou_reason));
return (ros2dapreject (di, "ROI_UREJECT", &(roi->roi_ureject)));
case ROI_PREJECT:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Operation (%d) provider rejected", roi->roi_preject.rop_id));
return (ros2daplose (di, "ROI_PREJECT", &(roi->roi_preject)));
case ROI_FINISH:
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapIntrInvokeRequest: Unbind request received"));
return (daplose (di, DP_ROS, NULLCP, "DAP initiator cannot accept unbind requests"));
default:
LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown indication type : %d", roi->roi_type));
break;
}
return (OK);
}
int DapAsynInvokeRequest (sd, id, op, pe, di)
int sd;
int id;
int op;
PE pe;
struct DAPindication * di;
{
int result;
struct RoSAPindication roi_s;
struct RoSAPindication * roi = &(roi_s);
struct RoSAPpreject * rop = &(roi->roi_preject);
result = RoInvokeRequest (sd, op, ROS_ASYNC, pe,
id, NULLIP, ROS_NOPRIO, roi);
if (result != OK)
{
if (roi->roi_type != ROI_PREJECT)
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapAsynInvokeRequest(): Failed without rejection"));
return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest inconsistent result"));
}
if (ROS_FATAL (rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER))
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapAsynInvokeRequest(): Fatal rejection"));
return (daplose (di, DP_INVOKE, NULLCP, "RoInvokeRequest failed"));
}
else
{
LLOG (log_dsap, LLOG_EXCEPTIONS, ("DapAsynInvokeRequest(): Non-Fatal rejection"));
return (dapreject (di, DP_INVOKE, id, NULLCP, "RoInvokeRequest failed"));
}
}
return (OK);
}
int DapInterrupt(sd, id, op, di)
int sd;
int id;
int op;
struct DAPindication * di;
{
/*
* Abandoning. Trickier than it looks!
* Need to RoInvoke an abandon op, which will receive
* One of the following:
* Result/Error for op being abandoned sent before
* this abandon arrived at the DSA;
* Abandoned error for op being abandoned;
* Result for abandon op which has overtaken the
* abandoned error for previous op between DSA and DUA
* Error for abandon because DSA has screwed up.
*
* Unless something goes wrong there should be 2 Ro events to
* collect before returning.
*/
/* abandon operation */
struct ds_abandon_arg ab_arg;
struct DSError ab_err;
PE ab_req_pe;
int old_id;
int new_id;
int ret1;
int ret2;
struct RoSAPindication roi1_s;
struct RoSAPindication * roi1 = &(roi1_s);
struct RoSAPpreject * rop1 = &(roi1->roi_preject);
struct RoSAPindication roi2_s;
struct RoSAPindication * roi2 = &(roi2_s);
struct RoSAPpreject * rop2 = &(roi2->roi_preject);
struct RoSAPindication * result_roi;
ab_arg.aba_invokeid = old_id = id;
new_id = ++id;
if(encode_DAS_AbandonArgument(&ab_req_pe,1,0,NULLCP,&ab_arg) != OK)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to encode an abandon operation"));
/* Go on listening for result or dump out ?? */
return(dapreject (di, DP_INVOKE, old_id, NULLCP, "DapInterrupt: Abandon argument encoding failed"));
}
else
{
DLOG(log_dsap, LLOG_DEBUG, ("Abandon invoke request"));
ret1 = RoInvokeRequest(sd,OP_ABANDON,ROS_SYNC,ab_req_pe,new_id,NULLIP,ROS_NOPRIO,roi1);
DLOG(log_dsap, LLOG_DEBUG, ("Abandon RoInvoke returns: %d", ret1));
if (ab_req_pe != NULLPE)
pe_free(ab_req_pe);
switch(ret1)
{
case OK:
/* What have we got? */
switch(roi1->roi_type)
{
case ROI_RESULT:
if(roi1->roi_result.ror_id == old_id)
{
/* Ferret result away for later */
result_roi = roi1;
}
else if(roi1->roi_result.ror_id == (old_id + 1))
{
RORFREE (&(roi1->roi_result));
}
else
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("ARRGH! Abandon sent: event for neither op nor abandon op returned!!"));
return(dapreject (di, DP_INVOKE, roi1->roi_result.ror_id, NULLCP, "Unexpected operation identifier"));
}
break;
case ROI_ERROR:
#ifdef PDU_DUMP
pdu_dump (roi1->roi_error.roe_param,DUMP_ERR,op);
#endif
if(roi1->roi_error.roe_id == old_id)
{
/* Ferret error away for later */
result_roi = roi1;
}
else if(roi1->roi_error.roe_id == (old_id + 1))
{
if (roi1->roi_error.roe_error != DSE_ABANDON_FAILED)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to abandon correctly"));
return(dapreject (di, DP_INVOKE, roi1->roi_error.roe_id, NULLCP, "Error mistyped for abandon"));
}
else
{
if(decode_DAS_AbandonFailedParm (roi1->roi_error.roe_param, 1, NULLIP, NULLVP, &(ab_err.dse_un.dse_un_abandon_fail)) != OK)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to decode abandonFailed"));
return(dapreject (di, DP_INVOKE, old_id, NULLCP, "Abandon error decoding failed"));
}
else
{
LLOG(log_dsap, LLOG_NOTICE, ("Abandon failed error!!!"));
ab_err.dse_type = DSE_ABANDON_FAILED;
log_ds_error(&ab_err);
ds_error_free(&ab_err);
}
}
}
else
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Abandon sent : event for neither op nor abandon op returned!!"));
return(dapreject (di, DP_INVOKE, roi1->roi_error.roe_id, NULLCP, "Unrecognised op id"));
}
break;
default:
LLOG(log_dsap, LLOG_FATAL, ("Unexpected roi_type : %d", roi1->roi_type));
return(dapreject (di, DP_INVOKE, -1, NULLCP, "Unrecognised event"));
}
break;
case NOTOK:
ros_log(rop1, "RO-INVOKE.REQUEST");
if (ROS_FATAL (rop2->rop_reason))
{
return (ros2daplose (di, "DapInterrupt", rop2));
}
else
{
return (dapreject (di, DP_ROS, -1, NULLCP, "DapInterrupt: Non-fatal reject"));
}
case DONE:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Responder has sent Finish!"));
return(daplose (di, DP_ROS, NULLCP, "Received Finish"));
default:
LLOG(log_dsap, LLOG_FATAL, ("Unknown return from RoInvokeRequest : %d", ret1));
return(daplose (di, DP_ROS, NULLCP, "RoInvokeRequest error"));
}
ret2 = RoWaitRequest(sd, NOTOK, roi2);
DLOG(log_dsap, LLOG_DEBUG, ("Abandon RoInvoke returns: %d", ret1));
switch(ret2)
{
case OK:
/* What have we got? */
switch(roi2->roi_type)
{
case ROI_RESULT:
if(roi2->roi_result.ror_id == old_id)
{
/* Ferret result away for later */
result_roi = roi2;
}
else if(roi2->roi_result.ror_id == (old_id + 1))
{
RORFREE (&(roi2->roi_result));
}
else
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("ARRGH! Abandon sent and event for neither op nor abandon op returned!!"));
return(dapreject (di, DP_INVOKE, roi1->roi_result.ror_id, NULLCP, "Unexpected operation identifier"));
}
break;
case ROI_ERROR:
#ifdef PDU_DUMP
pdu_dump (roi1->roi_error.roe_param,DUMP_ERR,op);
#endif
if(roi2->roi_error.roe_id == old_id)
{
/* Ferret error away for later */
result_roi = roi2;
}
else if(roi2->roi_error.roe_id == (old_id + 1))
{
if (roi2->roi_error.roe_error != DSE_ABANDON_FAILED)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to abandon correctly"));
return(dapreject (di, DP_INVOKE, roi2->roi_error.roe_id, NULLCP, "Error mistyped for abandon"));
}
else
{
if(decode_DAS_AbandonFailedParm (roi2->roi_error.roe_param, 1, NULLIP, NULLVP, &(ab_err.dse_un.dse_un_abandon_fail)) != OK)
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Failed to decode abandonFailed"));
return(dapreject (di, DP_INVOKE, old_id, NULLCP, "Abandon error decoding failed"));
}
else
{
LLOG(log_dsap, LLOG_NOTICE, ("Abandon failed error!!!"));
ab_err.dse_type = DSE_ABANDON_FAILED;
log_ds_error(&ab_err);
ds_error_free(&ab_err);
}
}
}
else
{
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Abandon sent : event for neither op nor abandon op returned!!"));
return(dapreject (di, DP_INVOKE, roi1->roi_error.roe_id, NULLCP, "Unrecognised op id"));
}
break;
default:
LLOG(log_dsap, LLOG_FATAL, ("Unexpected roi_type : %d", roi2->roi_type));
return(dapreject (di, DP_INVOKE, -1, NULLCP, "Unrecognised event"));
}
break;
case NOTOK:
ros_log(rop2, "RO-WAIT.REQUEST (Abandon)");
if (ROS_FATAL (rop1->rop_reason))
{
return (ros2daplose (di, "DapInterrupt", rop2));
}
else
{
return (dapreject (di, DP_ROS, -1, NULLCP, "DapInterrupt: Non-fatal reject"));
}
case DONE:
LLOG(log_dsap, LLOG_EXCEPTIONS, ("Responder has sent Finish!"));
return(daplose (di, DP_ROS, NULLCP, "Received Finish"));
default:
LLOG(log_dsap, LLOG_FATAL, ("Unknown return from RoInvokeRequest : %d", ret2));
return(daplose (di, DP_ROS, NULLCP, "RoInvokeRequest error"));
}
}
switch(result_roi->roi_type)
{
case ROI_RESULT:
return (DapDecodeResult (sd, &(result_roi->roi_result), di));
case ROI_ERROR:
return (DapDecodeError (sd, &(result_roi->roi_error), di));
default:
return (dapreject (di, DP_ROS, old_id, NULLCP, "DapInterrupt erroneous"));
}
}
#ifdef PDU_DUMP
static int pdu_count = -1;
static char * pdu_dir = NULLCP;
pdu_dump_init (dir)
char * dir;
{
pdu_count = 0;
pdu_dir = strdup (dir);
LLOG (log_dsap, LLOG_NOTICE, ("PDU Tracing enabled - %s",dir));
(void) mkdir (pdu_dir,0755);
}
pdu_dump (pe,type,op)
PE pe;
char * type;
int op;
{
char filename [BUFSIZE];
char * oper;
PS ps;
FILE * fptr;
if ( pdu_count == -1)
return;
if (strcmp (type,DUMP_ARG) == 0)
pdu_count++;
switch (op) {
case OP_READ:
oper = "read";
break;
case OP_COMPARE:
oper = "compare";
break;
case OP_ABANDON: /* Humm ... */
oper = "abandon";
break;
case OP_LIST:
oper = "list";
break;
case OP_SEARCH:
oper = "search";
break;
case OP_ADDENTRY:
oper = "add";
break;
case OP_REMOVEENTRY:
oper = "remove";
break;
case OP_MODIFYENTRY:
oper = "modify";
break;
case OP_MODIFYRDN:
oper = "modifyrdn";
break;
case OP_GETEDB:
oper = "getedb";
break;
case 100: /* special case for bind */
oper = "bind";
break;
}
(void) sprintf (filename, "%s/%s_%s.%d",pdu_dir,oper,type,pdu_count);
DLOG (log_dsap,LLOG_DEBUG,("Writing PDU to file %s",filename));
if ((fptr = fopen (filename,"w")) == (FILE *) NULL) {
LLOG(log_dsap,LLOG_EXCEPTIONS,("Cant open PDU file %s",filename));
return;
}
ps = ps_alloc (std_open);
if (std_setup (ps,fptr) != OK) {
(void) fclose (fptr);
return;
}
(void) pe2pl (ps,pe);
(void) fclose (fptr);
ps_free (ps);
}
#endif
#ifdef HEAVY_DEBUG
pdu_arg_log (pe,op)
PE pe;
int op;
{
/* PDU Level Logging */
switch (op) {
case OP_READ:
PLOG (log_dsap, print_DAS_ReadArgument, pe, "Read", 0);
break;
case OP_COMPARE:
PLOG (log_dsap, print_DAS_CompareArgument, pe, "Compare", 0);
break;
case OP_ABANDON:
PLOG (log_dsap, print_DAS_AbandonArgument, pe, "Abandon", 0);
break;
case OP_LIST:
PLOG (log_dsap, print_DAS_ListArgument, pe, "List", 0);
break;
case OP_SEARCH:
PLOG (log_dsap, print_DAS_SearchArgument, pe, "Search", 0);
break;
case OP_ADDENTRY:
PLOG (log_dsap, print_DAS_AddEntryArgument, pe, "AddEntry", 0);
break;
case OP_REMOVEENTRY:
PLOG (log_dsap, print_DAS_RemoveEntryArgument, pe, "RemoveEntry", 0);
break;
case OP_MODIFYENTRY:
PLOG (log_dsap, print_DAS_ModifyEntryArgument, pe, "ModifyEntry", 0);
break;
case OP_MODIFYRDN:
PLOG (log_dsap, print_DAS_ModifyRDNArgument, pe, "ModifyRDN", 0);
break;
case OP_GETEDB:
PLOG (log_dsap, print_Quipu_GetEntryDataBlockArgument, pe, "GetEDB", 0);
break;
default:
LLOG (log_dsap, LLOG_PDUS, ("Unknown operation (%d) - no argument PDU logged",op));
}
}
pdu_res_log (pe, op)
PE pe;
int op;
{
/* PDU Level Logging */
switch (op)
{
case OP_READ:
PLOG (log_dsap, print_DAS_ReadResult, pe, "Read", 1);
break;
case OP_COMPARE:
PLOG (log_dsap, print_DAS_CompareResult, pe, "Compare", 1);
break;
case OP_ABANDON:
PLOG (log_dsap, print_DAS_AbandonResult, pe, "Abandon", 1);
break;
case OP_LIST:
PLOG (log_dsap, print_DAS_ListResult, pe, "List", 1);
break;
case OP_SEARCH:
PLOG (log_dsap, print_DAS_SearchResult, pe, "Search", 1);
break;
case OP_ADDENTRY:
PLOG (log_dsap, print_DAS_AddEntryResult, pe, "AddEntry", 1);
break;
case OP_REMOVEENTRY:
PLOG (log_dsap, print_DAS_RemoveEntryResult, pe, "RemoveEntry",1);
break;
case OP_MODIFYENTRY:
PLOG (log_dsap, print_DAS_ModifyEntryResult, pe, "ModifyEntry",1);
break;
case OP_MODIFYRDN:
PLOG (log_dsap, print_DAS_ModifyRDNResult, pe, "ModifyRDN", 1);
break;
case OP_GETEDB:
PLOG (log_dsap, print_Quipu_GetEntryDataBlockResult, pe, "GetEDB", 1);
break;
default:
LLOG (log_dsap, LLOG_PDUS, ("Unknown operation (%d) - no result PDU logged",op));
}
}
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.