Copyright (C) Kevin Larke 2009-2020
This file is part of libcm.
libcm is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
libcm is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
See the GNU General Public License distributed with the libcm
package or look here:
// // Nodes and Endpoints: // --------------------- // A node corresponds to a process and owns a socket. It also has a label which is // unique among all other nodes on the network. A node also has a set of application // defined 'endpoints'. Each endpoint has a label and id that is unique among all // other endpoints on the same node. Endpoints on different nodes however may share // the same label and id. Endpoints are used by remote senders to identify // a particular receiver which is sharing the node with other receivers. Endpoints // are therefore analogous to port numbers on sockets. // // See gt/doc/notes.txt for more discussion of cmRtNet. // // // enum { kOkNetRC = cmOkRC, kUdpPortFailNetRC, kInvalidLabelNetRC, kDuplLabelNetRC, kDuplEndNetRC, kDuplLocalNetRC, kThreadFailNetRC, kBufToSmallNetRC, kNodeNotFoundNetRC, kEndNotFoundNetRC, kLocalNodeNetRC, kInvalidArgNetRC, kSyncFailNetRC, kNodeEndCntErrNetRC }; typedef cmRC_t cmRtNetRC_t; typedef cmHandle_t cmRtNetH_t; typedef cmHandle_t cmRtNetEndptH_t; extern cmRtNetH_t cmRtNetNullHandle; extern cmRtNetEndptH_t cmRtNetEndptNullHandle; // selector id's for cmRtNetSyncMsg_t.selId. typedef enum { kHelloSelNetId, // 0 broadcast msg (label=node label, id=endpt cnt) kNodeSelNetId, // 1 define remote node (label=remote node label, id=endpt cnt) kEndpointSelNetId, // 2 define remote endpt (label=remote endpt label, id=endpt id) kDoneSelNetId, // 3 declare all endpts sent kInvalidSelNetId // 4 } cmRtNetSelId_t; // Network synchronization message format. // cmRtNetRC_t.hdr.selId == kNetSyncSelRtid. typedef struct { cmRtSysMsgHdr_t hdr; // standard cmRtSys msg header cmRtNetSelId_t selId; // message selector id (See kXXXSelNetId above) unsigned hdrByteCnt; // size of the header record at transmission (used to locate the serialzed label) unsigned rtSubIdx; // cmInvalidIdx or rtSubIdx unsigned id; // endptCnt or endpoint id const cmChar_t* label; // node or endpoint label } cmRtNetSyncMsg_t; const cmChar_t* cmRtNetSyncMsgLabel( const cmRtNetSyncMsg_t* m ); // NOTE: Messages passed between cmRtNet nodes during the synchronization // process use the cmRtNetSyncMsg_t format (w/ the body of label following // the record. All other messages use cmRtNetMsg_t (cmRtSysMsg.h) format. // 'cbFunc' will be called within the context of cmRtNetReceive() to receive // incoming network messages. // rtSubIdx is the rtSubIdx of the cmRtSys which owns this cmRtNet. cmRtNetRC_t cmRtNetAlloc( cmCtx_t* ctx, cmRtNetH_t* hp, unsigned rtSubIdx, cmUdpCallback_t cbFunc, void* cbArg ); cmRtNetRC_t cmRtNetFree( cmRtNetH_t* hp ); bool cmRtNetIsValid( cmRtNetH_t h ); // Get the local host name for this machine. This function // is synonomous with gethostname(). const cmChar_t* cmRtNetLocalHostName( cmRtNetH_t h ); // Initialize the local network node. // 'bcastAddr' is the network broadcast address (e.g. 192.168.15.255). // 'nodeLabel' is the local network node label // 'ipAddr' may be set to NULL to use any available IP address. // 'ipPort' refers to the socket port (which may need to be made available // by the machine firewall cfg.) cmRtNetRC_t cmRtNetInitialize( cmRtNetH_t h, const cmChar_t* bcastAddr, const cmChar_t* nodeLabel, const cmChar_t* ipAddr, cmUdpPort_t ipPort ); bool cmRtNetIsInitialized( cmRtNetH_t h ); // Register the local endpoints. // Endpoints may only be registered once the network is initialized via // cmRtNetInitialize(). // Remote nodes will be able to send messages to these endpoints by // referring to (nodeLabel/endPtLabel) cmRtNetRC_t cmRtNetRegisterEndPoint( cmRtNetH_t h, const cmChar_t* endPtLabel, unsigned endPtId ); // Delete all nodes and endpoints. cmRtNetRC_t cmRtNetFinalize( cmRtNetH_t h ); // Broadcast the 'hello' to all machines listening on the // broadcast addresss. This starts the synchronization sequence cmRtNetRC_t cmRtNetDoSync( cmRtNetH_t h ); // This function must be polled to receive incoming network messages // via the callback funcion 'cbFunc' as passed to cmRtNetAlloc(). // Note that all messages received via 'cbFunc' will be prefixed with // an cmRtSysMsgHdr_t header (See cmRtSysMsg.h). cmRtNetRC_t cmRtNetReceive( cmRtNetH_t h ); // Get a remote end point handle for use with cmRtNetSend. cmRtNetRC_t cmRtNetEndpointHandle( cmRtNetH_t h, const cmChar_t* nodeLabel, const cmChar_t* endptLabel, cmRtNetEndptH_t* hp ); bool cmRtNetEndpointIsValid( cmRtNetEndptH_t endPtH ); // Given an endpoint handle return the id/label of the associated endpoint. unsigned cmRtNetEndpointId( cmRtNetEndptH_t endPtH ); const cmChar_t* cmRtNetEndpointLabel( cmRtNetEndptH_t endPtH ); // Send a message to a remote endpoint. // Note that srcEndPtId is used only to inform the receiver of the endpoint // of the transmitter. It is not used in any part of the transmit or receive // process. cmRtNetRC_t cmRtNetSend( cmRtNetH_t h, unsigned srcEndPtId, cmRtNetEndptH_t epH, const void* msg, unsigned msgByteCnt ); // Send a message to a remote endpoint. This function is a composite // of cmRtNetEndpointHandle() and cmRtNetSend(). cmRtNetRC_t cmRtNetSendByLabels( cmRtNetH_t h, unsigned srcEndPtId, const cmChar_t* nodeLabel, const cmChar_t* endptLabel, const void* msg, unsigned msgByteCnt ); cmRtNetRC_t cmRtNetSendByIndex( cmRtNetH_t h, unsigned srcEndPtId, unsigned dstNodeIdx, unsigned dstEndptIdx, const void* msg, unsigned msgByteCnt ); // Enable/disable synchronization protocol reporting. // Return the previous state of the report sync. flag. bool cmRtNetReportSyncEnable( cmRtNetH_t h, bool enableFl ); bool cmRtNetReportSyncIsEnabled( cmRtNetH_t h ); // Query network configuration. Returns true on success or false if // {nodeIdx, epIdx} does not identify a valid endpoint. const cmChar_t* cmRtNetLocalNodeLabel( cmRtNetH_t h ); unsigned cmRtNetRemoteNodeCount( cmRtNetH_t h ); unsigned cmRtNetAddrToNodeIndex( cmRtNetH_t h, const struct sockaddr_in* a ); unsigned cmRtNetRemoteNodeIndex( cmRtNetH_t h, const cmChar_t* label ); const cmChar_t* cmRtNetRemoteNodeLabel( cmRtNetH_t h, unsigned idx ); unsigned cmRtNetRemoteNodeEndPointCount( cmRtNetH_t h, unsigned nodeIdx ); cmRtNetRC_t cmRtNetRemoteNodeEndPoint( cmRtNetH_t h, unsigned nodeIdx, unsigned epIdx, const cmChar_t** labelRef, unsigned* idRef, unsigned* rsiRef ); void cmRtNetReport( cmRtNetH_t h ); void cmRtNetTest( cmCtx_t* ctx, bool mstrFl ); // // // Synchronization Protocol: // // Machine A Machine B // ================================== ==================================== // broadcast 'hello' ------------------=-&gt create node-A w/ ei=0 -------+ // | // +&lt-- create node-B w/ ei=0 &lt--------=-- send 'node' &lt----------------+ // | // +--&gt switch(ei,m_t) // | ei &lt en : send endpt[ei++] -=--&gt create endpt[] on node-A --&gt+ // | | // | ei == en : ++ei,send 'done' -=-------------------------------&gt+ | // | | // | m_t!='done': send 'done' -=-------------------------------&gt+ | // | | // | (stop) : | // | | // | v // | switch(ei,m_t) // +&lt-- create endpt[] on node-B &lt---=----- send endpt[ei++] : ei &lt en // | // +&lt---------------------------------=----- send 'done',++ei : ei == en // | // +&lt---------------------------------=----- send 'done' : m_t!= 'done' // // : (stop) // // Notes: // 1) 'ei' is the index of the next local end point to transmit. // 2) 'en' is the count of local endpoints. // 3) 'm_t' is the msg type (i.e.'hello','node','endpoint','done') // of the incoming message. // 4) The symbol -=- in the flow chart implies a network transmission. // // //