Пример #1
0
/* This routine is needed when the application is built on top of the bigemulator
 * layer of Charm. In this case, the real CCS handler must be called within a
 * worker thread. The function of this function is to receive the CCS message in
 * the bottom converse layer and forward it to the emulated layer. */
static void bg_req_fw_handler(char *msg) {
  /* Get out of the message who is the destination pe */
  int offset = CmiReservedHeaderSize + sizeof(CcsImplHeader);
  CcsImplHeader *hdr = (CcsImplHeader *)(msg+CmiReservedHeaderSize);
  int destPE = (int)ChMessageInt(hdr->pe);
  if (CpvAccess(_bgCcsAck) < BgNodeSize()) {
    CcsBufferMessage(msg);
    return;
  }
  //CmiPrintf("CCS scheduling message\n");
  if (destPE == -1) destPE = 0;
  if (destPE < -1) {
    ChMessageInt_t *pes_nbo = (ChMessageInt_t *)(msg+CmiReservedHeaderSize+sizeof(CcsImplHeader));
    destPE = ChMessageInt(pes_nbo[0]);
  }
  //CmiAssert(destPE >= 0); // FixME: should cover also broadcast and multicast -> create generic function to extract destpe
  (((CmiBlueGeneMsgHeader*)msg)->tID) = 0;
  (((CmiBlueGeneMsgHeader*)msg)->n) = 0;
  (((CmiBlueGeneMsgHeader*)msg)->flag) = 0;
  (((CmiBlueGeneMsgHeader*)msg)->t) = 0;
  (((CmiBlueGeneMsgHeader*)msg)->hID) = CpvAccess(_bgCcsHandlerIdx);
  /* Get the right thread to deliver to (for now assume it is using CyclicMapInfo) */
  addBgNodeInbuffer(msg, destPE/CmiNumPes());
  //CmiPrintf("message CCS added %d to %d\n",((CmiBlueGeneMsgHeader*)msg)->hID, ((CmiBlueGeneMsgHeader*)msg)->tID);
}
Пример #2
0
/**
 * This is the entrance point of a CCS request into the server.
 * It is executed only on proc 0, and it forwards the request to the appropriate PE.
 */
void CcsImpl_netRequest(CcsImplHeader *hdr,const void *reqData)
{
  char *msg;
  int len,repPE=ChMessageInt(hdr->pe);
  if (repPE<=-CmiNumPes() || repPE>=CmiNumPes()) {
#if ! CMK_BIGSIM_CHARM
    /*Treat out of bound values as errors. Helps detecting bugs*/
    if (repPE==-CmiNumPes()) CmiPrintf("Invalid processor index in CCS request: are you trying to do a broadcast instead?");
    else CmiPrintf("Invalid processor index in CCS request.");
    CpvAccess(ccsReq)=hdr;
    CcsSendReply(0,NULL); /*Send an empty reply to the possibly waiting client*/
    return;
#endif
  }

  msg=CcsImpl_ccs2converse(hdr,reqData,&len);
  if (repPE >= 0) {
    /* The following %CmiNumPes() follows the assumption that in BigSim the mapping is round-robin */
    //CmiPrintf("CCS message received for %d\n",repPE);
    CmiSyncSendAndFree(repPE%CmiNumPes(),len,msg);
  } else if (repPE == -1) {
    /* Broadcast to all processors */
    //CmiPrintf("CCS broadcast received\n");
    CmiSyncSendAndFree(0,len,msg);
  } else {
    /* Multicast to -repPE processors, specified right at the beginning of reqData (as a list of pes) */
    int firstPE = ChMessageInt(*(ChMessageInt_t*)reqData);
    /* The following %CmiNumPes() follows the assumption that in BigSim the mapping is round-robin */
    //CmiPrintf("CCS multicast received\n");
    CmiSyncSendAndFree(firstPE%CmiNumPes(),len,msg);
  }
}
Пример #3
0
/********************************************************
Authenticate incoming request for a client salt value.
Exchange looks like:

1.) Client sends request code 0x80 (SHA-1), 0x00 (version 0), 
0x01 (create salt), 0xNN (security level); followed by 
client challenge (4 bytes, s1)

2.) Server replies with server challenge (4 bytes, s2)

3.) Client replies with hashed key & server challenge (20 bytes, s2hash)

4.) Server replies with hashed key & client challenge (20 bytes, s1hash),
as well as client identifier and initial client salt. (8 bytes total).
*/
static const char *CcsServer_createSalt(SOCKET fd,CCS_AUTH_clients *cl,
					CcsSecMan *security,CcsSecAttr *attr)
{
  ChMessageInt_t s1;
  ChMessageInt_t s2=ChMessageInt_new(CCS_RAND_next(&cl->rand));
  SHA1_hash_t s2hash;
  int clientId;
  struct {
    SHA1_hash_t s1hash;
    ChMessageInt_t clientId;
    ChMessageInt_t clientSalt;
  } reply;
  if (-1==skt_recvN(fd,&s1,sizeof(s1))) return "ERROR> CreateSalt challenge recv";
  if (-1==skt_sendN(fd,&s2,sizeof(s2))) return "ERROR> CreateSalt challenge send";
  if (-1==skt_recvN(fd,&s2hash,sizeof(s2hash))) return "ERROR> CreateSalt reply recv";
  if (CCS_AUTH_differ(security->getKey(security,attr),ChMessageInt(s2),
		      NULL,&s2hash))
    return "ERROR> CreateSalt client hash mismatch! (bad password?)";
  CCS_AUTH_hash(security->getKey(security,attr),ChMessageInt(s1),
		NULL,&reply.s1hash);
  clientId=CCS_AUTH_addClient(cl);
  reply.clientId=ChMessageInt_new(clientId);
  reply.clientSalt=ChMessageInt_new(CCS_AUTH_clientSalt(cl,clientId));
  if (-1==skt_sendN(fd,&reply,sizeof(reply))) return "ERROR> CreateSalt reply send";
  /*HACK: this isn't an error return, and returning an error code
   here is wrong; but all we want is to close the socket (not process
   a CCS request), and printing out this text isn't a bad idea, so... 
  */
  return "Created new client";
}
Пример #4
0
static int CcsServer_recvRequestData(SOCKET fd,
				     CcsImplHeader *hdr,void **reqData)
{
  CcsMessageHeader req;/*CCS header, from requestor*/
  int reqBytes, numPes, destPE;
  const char *err;
  if (NULL!=(err=CcsServer_readHeader(fd,&ccs_clientlist,security,
				      &hdr->attr,&req))) 
  { /*Not a regular message-- write error message and return error.*/
    fprintf(stdout,"CCS %s\n",err);
    return 0;
  }

  /*Fill out the internal CCS header*/
  strncpy(hdr->handler,req.handler,CCS_MAXHANDLER);  
  hdr->pe=req.pe;
  hdr->len=req.len;
  hdr->replyFd=ChMessageInt_new(fd);

  /*Is it a multicast?*/
  numPes = 0;
  destPE = ChMessageInt(hdr->pe);
  if (destPE < -1) numPes = -destPE;
  
  /*Grab the user data portion of the message*/
  reqBytes=ChMessageInt(req.len) + numPes*sizeof(ChMessageInt_t);
  *reqData=(char *)malloc(reqBytes);
  if (-1==skt_recvN(fd,*reqData,reqBytes)) {
    fprintf(stdout,"CCS ERROR> Retrieving %d message bytes\n",reqBytes);
    free(*reqData);
    return 0;
  }
  return 1;
}
Пример #5
0
extern "C" void req_fw_handler(char *msg)
{
  int offset = CmiReservedHeaderSize + sizeof(CcsImplHeader);
  CcsImplHeader *hdr = (CcsImplHeader *)(msg+CmiReservedHeaderSize);
  int destPE = (int)ChMessageInt(hdr->pe);
  if (CmiMyPe() == 0 && destPE == -1) {
    /* Broadcast message to all other processors */
    int len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+ChMessageInt(hdr->len);
    CmiSyncBroadcast(len, msg);
  }
  else if (destPE < -1) {
    /* Multicast the message to your children */
    int len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+ChMessageInt(hdr->len)-destPE*sizeof(ChMessageInt_t);
    int index, child, i;
    int *pes = (int*)(msg+CmiReservedHeaderSize+sizeof(CcsImplHeader));
    ChMessageInt_t *pes_nbo = (ChMessageInt_t *)pes;
    offset -= destPE * sizeof(ChMessageInt_t);
    if (ChMessageInt(pes_nbo[0]) == CmiMyPe()) {
      for (index=0; index<-destPE; ++index) pes[index] = ChMessageInt(pes_nbo[index]);
    }
    for (index=0; index<-destPE; ++index) {
      if (pes[index] == CmiMyPe()) break;
    }
    child = (index << 2) + 1;
    for (i=0; i<4; ++i) {
      if (child+i < -destPE) {
        CmiSyncSend(pes[child+i], len, msg);
      }
    }
  }
  CcsHandleRequest(hdr, msg+offset);
  CmiFree(msg);
}
Пример #6
0
/* initnode node table reply format:
 +------------------------------------------------------- 
 | 4 bytes  |   Number of nodes n                       ^
 |          |   (big-endian binary integer)       4+12*n bytes
 +-------------------------------------------------     |
 ^  |        (one entry for each node)            ^     |
 |  | 4 bytes  |   Number of PEs for this node    |     |
 n  | 4 bytes  |   IP address of this node   12*n bytes |
 |  | 4 bytes  |   Data (UDP) port of this node   |     |
 v  |          |   (big-endian binary integers)   v     v
 ---+----------------------------------------------------
*/
static void node_addresses_store(ChMessage *msg)
{
  ChMessageInt_t *n32=(ChMessageInt_t *)msg->data;
  ChNodeinfo *d=(ChNodeinfo *)(n32+1);
  int nodestart;
  int i,j,n;
  MACHSTATE(1,"node_addresses_store {");	
  _Cmi_numnodes=ChMessageInt(n32[0]);

  if ((sizeof(ChMessageInt_t)+sizeof(ChNodeinfo)*_Cmi_numnodes)
         !=(unsigned int)msg->len)
    {printf("Node table has inconsistent length!");machine_exit(1);}

  nodes = (OtherNode)malloc(_Cmi_numnodes * sizeof(struct OtherNodeStruct));
  nodestart=0;
  for (i=0; i<_Cmi_numnodes; i++) {
    nodes[i].nodestart = nodestart;
    nodes[i].nodesize  = ChMessageInt(d[i].nPE);
    MACHSTATE2(3,"node %d nodesize %d",i,nodes[i].nodesize);
    nodes[i].mach_id = ChMessageInt(d[i].mach_id);

    nodes[i].IP=d[i].IP;
    if (i==_Cmi_mynode) {
      Cmi_nodestart=nodes[i].nodestart;
      _Cmi_mynodesize=nodes[i].nodesize;
      Cmi_self_IP=nodes[i].IP;
    }
    nodes[i].dataport = ChMessageInt(d[i].dataport);
    nodes[i].addr = skt_build_addr(nodes[i].IP,nodes[i].dataport);

#if CMK_USE_TCP
    nodes[i].sock = INVALID_SOCKET;
#endif
    nodestart+=nodes[i].nodesize;

  }
  _Cmi_numpes=nodestart;
  n = _Cmi_numpes;
#ifdef CMK_CPV_IS_SMP
  n += _Cmi_numnodes;
#endif
  nodes_by_pe = (OtherNode*)malloc(n * sizeof(OtherNode));
  _MEMCHECK(nodes_by_pe);
  for (i=0; i<_Cmi_numnodes; i++) {
    OtherNode node = nodes + i;
    OtherNode_init(node);
    for (j=0; j<node->nodesize; j++) {
      nodes_by_pe[j + node->nodestart] = node;
    }
  }
#ifdef CMK_CPV_IS_SMP
  /* index for communication threads */
  for (i=_Cmi_numpes; i<_Cmi_numpes+_Cmi_numnodes; i++) {
    OtherNode node = nodes + i-_Cmi_numpes;
    nodes_by_pe[i] = node;
  }
#endif
  MACHSTATE(1,"} node_addresses_store");
}
Пример #7
0
CcsDelayedReply CcsDelayReply(void)
{
  CcsDelayedReply ret;
  int len = sizeof(CcsImplHeader);
  if (ChMessageInt(CpvAccess(ccsReq)->pe) < -1)
    len += ChMessageInt(CpvAccess(ccsReq)->pe) * sizeof(int);
  ret.hdr = (CcsImplHeader*)malloc(len);
  memcpy(ret.hdr, CpvAccess(ccsReq), len);
  CpvAccess(ccsReq)=NULL;
  return ret;
}
Пример #8
0
/**
 * Decide if the reply is ready to be forwarded to the waiting client,
 * or if combination is required (for broadcast/multicast CCS requests.
 */
extern "C" int CcsReply(CcsImplHeader *rep,int repLen,const void *repData) {
  int repPE = (int)ChMessageInt(rep->pe);
  if (repPE <= -1) {
    /* Reduce the message to get the final reply */
    CcsHandlerRec *fn;
    int len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+repLen;
    char *msg=(char*)CmiAlloc(len);
    char *r=msg+CmiReservedHeaderSize;
    char *handlerStr;
    rep->len = ChMessageInt_new(repLen);
    *(CcsImplHeader *)r=*rep; r+=sizeof(CcsImplHeader);
    memcpy(r,repData,repLen);
    CmiSetHandler(msg,rep_fw_handler_idx);
    handlerStr=rep->handler;
    fn=(CcsHandlerRec *)CcsGetHandler(handlerStr);
    if (fn->mergeFn == NULL) CmiAbort("Called CCS broadcast with NULL merge function!\n");
    if (repPE == -1) {
      /* CCS Broadcast */
      CkReduce(msg, len, fn->mergeFn);
    } else {
      /* CCS Multicast */
      CmiListReduce(-repPE, (int*)(rep+1), msg, len, fn->mergeFn, fn->redID);
    }
  } else {
    if (_conditionalDelivery == 0) CcsImpl_reply(rep, repLen, repData);
    else {
      /* We are the child of a conditional delivery, write to the parent the reply */
      write(conditionalPipe[1], &repLen, 4);
      write(conditionalPipe[1], repData, repLen);
    }
  }
  return 0;
}
Пример #9
0
/***********************************************
Send the given data as a CCS reply on the given socket.
Goes to some effort to minimize the number of "sends"
(and hence outgoing TCP packets) by assembling the 
header and data in-place.
*/
static void CcsServer_writeReply(SOCKET fd,
			 CcsSecMan *security,
			 CcsSecAttr *attr,
			 int replyLen,char *reply)
{
  const void *bufs[3]; int lens[3]; int nBuffers=0;
  struct { /*Authentication header*/
    SHA1_hash_t hash;
  } aheader;
  struct { /*Reply header*/
    ChMessageInt_t len;
  } header;
  if (attr->auth==1) 
  { /*Compose a reply SHA-1 hash header*/
    CCS_AUTH_hash(security->getKey(security,attr),
		  ChMessageInt(attr->replySalt),NULL,&aheader.hash);
    bufs[nBuffers]=&aheader; lens[nBuffers]=sizeof(aheader); nBuffers++;
  }
  /*Compose a simple reply header*/
  header.len=ChMessageInt_new(replyLen);
  bufs[nBuffers]=&header; lens[nBuffers]=sizeof(header); nBuffers++;
  bufs[nBuffers]=reply; lens[nBuffers]=replyLen; nBuffers++;
  if (-1==skt_sendV(fd,nBuffers,bufs,lens)) return;
  skt_close(fd);
#undef n
}
Пример #10
0
/*Send a Ccs reply down the given socket.
Closes the socket afterwards.
A CcsImplHeader len field equal to 0 means do not send any reply.
*/
void CcsServer_sendReply(CcsImplHeader *hdr,int repBytes,const void *repData)
{
  int fd=ChMessageInt(hdr->replyFd);
  skt_abortFn old;
  if (ChMessageInt(hdr->len)==0) {
    CCSDBG(("CCS Closing reply socket without a reply.\n"));
    skt_close(fd);
    return;
  }
  old=skt_set_abort(reply_abortFn);
  CCSDBG(("CCS   Sending %d bytes of reply data\n",repBytes));
  CcsServer_writeReply(fd,security,&hdr->attr,repBytes,(char *)repData);
  skt_close(fd);
  CCSDBG(("CCS Reply socket closed.\n"));
  skt_set_abort(old);
}
Пример #11
0
/*******************
Grab an ordinary authenticated message off this socket.
The format is:
-4 byte client ID number (returned by createSalt earlier)
-4 byte client challenge (used to by client to authenticate reply)
-20 byte authentication hash code
-Regular CcsMessageHeader
*/
static const char *CcsServer_SHA1_message(SOCKET fd,CCS_AUTH_clients *cl,
					CcsSecMan *security,CcsSecAttr *attr,
					CcsMessageHeader *hdr)
{
  ChMessageInt_t clientNo_net;
  int clientNo;
  unsigned int salt;
  SHA1_hash_t hash;

  /* An ordinary authenticated message */      
  if (-1==skt_recvN(fd,&clientNo_net,sizeof(clientNo_net)))
    return "ERROR> During recv. client number";
  if (-1==skt_recvN(fd,&attr->replySalt,sizeof(attr->replySalt)))
    return "ERROR> During recv. reply salt";
  if (-1==skt_recvN(fd,&hash,sizeof(hash)))
    return "ERROR> During recv. authentication hash";
  if (-1==skt_recvN(fd,hdr,sizeof(CcsMessageHeader)))
    return "ERROR> During recv. message header";
  clientNo=ChMessageInt(clientNo_net);
  
  if (clientNo<0 || clientNo>=CCS_AUTH_numClients(cl))
    return "ERROR> Bad client number in SHA-1 request!";
  salt=CCS_AUTH_clientSalt(cl,clientNo);
  
  /*Check the client's hash*/
  if (CCS_AUTH_differ(security->getKey(security,attr),salt,
		      hdr,&hash))
    return "ERROR> Authentication hash code MISMATCH-- bad or faked key";

  CCS_AUTH_advanceSalt(cl,clientNo);
  return NULL; /*It's a good message*/
}
Пример #12
0
//Read a list contents request header:
//  first item to send, 4-byte network integer
//  last item+1 to send, 4-byte network integer
//  extra data length, 4-byte network integer
//  extra data, list-defined bytes
//  list path length, 4-byte network integer (character count)
//  list path name, null-terminated ASCII
static CpdListAccessor *CpdListHeader_ccs_list_items(char *msg,
	     CpdListItemsRequest &h)
{
  int msgLen=CmiSize((void *)msg)-CmiReservedHeaderSize;
  CpdListAccessor *ret=NULL;
  const ChMessageInt_t *req=(const ChMessageInt_t *)(msg+CmiReservedHeaderSize);
  h.lo=ChMessageInt(req[0]); // first item to send
  h.hi=ChMessageInt(req[1]); // last item to send+1
  h.extraLen=ChMessageInt(req[2]); // extra data length
  if (h.extraLen>=0 
  && ((int)(3*sizeof(ChMessageInt_t)+h.extraLen))<msgLen) {
    h.extra=(void *)(req+3);  // extra data
    ret=CpdListLookup((ChMessageInt_t *)(h.extraLen+(char *)h.extra));
    if (ret!=NULL) CpdListBoundsCheck(ret,h.lo,h.hi);
  }
  return ret;
}
Пример #13
0
int ChMessageHeader_recv(SOCKET fd,ChMessage *dst)
{
  /*Get the binary header*/
  if (0!=skt_recvN(fd,(char *)&dst->header,sizeof(dst->header))) return -1;
  /*Allocate a recieve buffer*/
  dst->len=ChMessageInt(dst->header.len);
  dst->data=0;
  return 0;
}
Пример #14
0
/*Receives reply messages passed up from
converse to node 0.*/
static void rep_fw_handler(char *msg)
{
  int len;
  char *r=msg+CmiReservedHeaderSize;
  CcsImplHeader *hdr=(CcsImplHeader *)r; 
  r+=sizeof(CcsImplHeader);
  len=ChMessageInt(hdr->len);
  CcsImpl_reply(hdr,len,r);
  CmiFree(msg);
}
Пример #15
0
static void ccs_killport(char *msg)
{
  killPortStruct *oldList=killList;
  int port=ChMessageInt(*(ChMessageInt_t *)(msg+CmiReservedHeaderSize));
  skt_ip_t ip;
  unsigned int connPort;
  CcsCallerId(&ip,&connPort);
  killList=(killPortStruct *)malloc(sizeof(killPortStruct));
  killList->ip=ip;
  killList->port=port;
  killList->next=oldList;
  CmiFree(msg);
}
Пример #16
0
/**
  Return a CpdListAccessor, given a network string containing the 
  list path.  A network string is a big-endian 32-bit "length" 
  field, followed by a null-terminated ASCII string of that length.
*/
static CpdListAccessor *CpdListLookup(const ChMessageInt_t *lenAndPath)
{
  static const int CpdListMaxLen=80;
  int len=ChMessageInt(lenAndPath[0]);
  const char *path=(const char *)(lenAndPath+1);
  char pathBuf[CpdListMaxLen+1]; //Temporary null-termination buffer
  if ((len<0) || (len>CpdListMaxLen)) {
    CmiError("CpdListAccessor> Invalid list path length %d!\n",len);
    return NULL; //Character count is invalid
  }
  strncpy(pathBuf,path,len);
  pathBuf[len]=0; //Ensure string is null-terminated
  return CpdListLookup(pathBuf);
}
Пример #17
0
void * CcsMerge_concat(int *size,void *local,void **remote,int n) {
  CcsImplHeader *hdr;
  int total = *size;
  void *reply;
  char *ptr;
  int i;
  for (i=0; i<n; ++i) {
    hdr = (CcsImplHeader*)(((char*)remote[i])+CmiReservedHeaderSize);
    total += ChMessageInt(hdr->len);
  }
  reply = CmiAlloc(total);
  memcpy(reply, local, *size);
  ((CcsImplHeader*)(((char*)reply)+CmiReservedHeaderSize))->len = ChMessageInt_new(total-CmiReservedHeaderSize-sizeof(CcsImplHeader));
  CmiFree(local);
  ptr = ((char*)reply)+*size;
  for (i=0; i<n; ++i) {
    int len = ChMessageInt(((CcsImplHeader*)(((char*)remote[i])+CmiReservedHeaderSize))->len);
    memcpy(ptr, ((char*)remote[i])+CmiReservedHeaderSize+sizeof(CcsImplHeader), len);
    ptr += len;
  }
  *size = total;
  return reply;
}
Пример #18
0
/*Convert CCS header & message data into a converse message 
 addressed to handler*/
char *CcsImpl_ccs2converse(const CcsImplHeader *hdr,const void *data,int *ret_len)
{
  int reqLen=ChMessageInt(hdr->len);
  int destPE = ChMessageInt(hdr->pe);
  int len;
  char *msg;
  if (destPE < -1) reqLen -= destPE*sizeof(int);
  len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+reqLen;
  msg=(char *)CmiAlloc(len);
  memcpy(msg+CmiReservedHeaderSize,hdr,sizeof(CcsImplHeader));
  memcpy(msg+CmiReservedHeaderSize+sizeof(CcsImplHeader),data,reqLen);
  if (ret_len!=NULL) *ret_len=len;
  if (_ccsHandlerIdx != 0) {
    CmiSetHandler(msg, _ccsHandlerIdx);
    return msg;
  } else {
#if NODE_0_IS_CONVHOST
    CmiAbort("Why do we need to buffer messages when node 0 is Convhost?");
#else
    CcsBufferMessage(msg);
    return NULL;
#endif
  }
}
Пример #19
0
/*CCS Bottleneck:
  Deliver the given message data to the given
CCS handler.
*/
void CcsHandleRequest(CcsImplHeader *hdr,const char *reqData)
{
  char *cmsg;
  int reqLen=ChMessageInt(hdr->len);
/*Look up handler's converse ID*/
  char *handlerStr=hdr->handler;
  CcsHandlerRec *fn=(CcsHandlerRec *)CkHashtableGet(CpvAccess(ccsTab),(void *)&handlerStr);
  if (fn==NULL) {
    CmiPrintf("CCS: Unknown CCS handler name '%s' requested. Ignoring...\n",
	      hdr->handler);
    CpvAccess(ccsReq)=hdr;
    CcsSendReply(0,NULL); /*Send an empty reply to the possibly waiting client*/
    return;
 /*   CmiAbort("CCS: Unknown CCS handler name.\n");*/
  }

/* Call the handler */
  CpvAccess(ccsReq)=hdr;
#if CMK_CHARMDEBUG
  if (conditionalPipe[1]!=0 && _conditionalDelivery==0) {
    /* We are conditionally delivering, the message has been sent to the child, wait for its response */
    int bytes;
    if (4==read(conditionalPipe[0], &bytes, 4)) {
      char *buf = malloc(bytes);
      read(conditionalPipe[0], buf, bytes);
      CcsSendReply(bytes,buf);
      free(buf);
    } else {
      /* the pipe has been closed */
      CpdEndConditionalDeliver_master();
   }
  }
  else
#endif
  {
    callHandlerRec(fn,reqLen,reqData);
  
/*Check if a reply was sent*/
    if (CpvAccess(ccsReq)!=NULL)
      CcsSendReply(0,NULL);/*Send an empty reply if not*/
  }
}
Пример #20
0
void CcsCallerId(skt_ip_t *pip, unsigned int *pport)
{
  *pip = CpvAccess(ccsReq)->attr.ip;
  *pport = ChMessageInt(CpvAccess(ccsReq)->attr.port);
}