// : vi ts=4 sw=4 noet : /* ================================================================================== Copyright (c) 2019 Nokia Copyright (c) 2018-2019 AT&T Intellectual Property. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================================================== */ /* Mnemonic: rmr_agnostic.h Abstract: Header file for things that are agnostic to the underlying transport mechanism. Author: E. Scott Daniels Date: 28 February 2018 */ #ifndef _rmr_agnostic_h #define _rmr_agnostic_h typedef struct endpoint endpoint_t; // place holder for structs defined in nano/nng private.h typedef struct uta_ctx uta_ctx_t; // allow testing to override without changing this #ifndef DEBUG #define DEBUG 0 #endif #define FALSE 0 #define TRUE 1 #define QUOTE(a) #a // allow a constant to be quoted #define QUOTE_DEF(a) QUOTE(a) // allow a #define value to be quoted (e.g. QUOTE(MAJOR_VERSION) ) #define RMR_MSG_VER 1 // potental to treat messages differently if from backlevel version // environment variable names we'll suss out #define ENV_BIND_IF "RMR_BIND_IF" // the interface to bind to for both normal comma and RTG (0.0.0.0 if missing) #define ENV_RTG_PORT "RMR_RTG_SVC" // the port we'll listen on for rtg connections #define ENV_SEED_RT "RMR_SEED_RT" // where we expect to find the name of the seed route table #define ENV_RTG_RAW "RMR_RTG_ISRAW" // if > 0 we expect route table gen messages as raw (not sent from an RMr application) #define ENV_VERBOSE_FILE "RMR_VCTL_FILE" // file where vlevel may be managed for some (non-time critical) functions #define NO_FLAGS 0 // no flags to pass to a function #define FL_NOTHREAD 0x01 // do not start an additional thread (must be 'user land' to support rtg #define UFL_MASK 0xff // mask applied to some flag parms passed by the user to remove any internal flags // internal flags, must be > than UFLAG_MASK //#define IFL_.... // msg buffer flags #define MFL_ZEROCOPY 0x01 // the message is an allocated zero copy message and can be sent. #define MFL_NOALLOC 0x02 // send should NOT allocate a new buffer before returning #define MFL_ADDSRC 0x04 // source must be added on send #define MFL_RAW 0x08 // message is 'raw' and not from an RMr based sender (no header) #define MAX_EP_GROUP 32 // max number of endpoints in a group #define MAX_RTG_MSG_SZ 2048 // max expected message size from route generator //#define DEF_RTG_MSGID "" // default to pick up all messages from rtg #define DEF_RTG_PORT "tcp:4561" // default port that we accept rtg connections on #define DEF_COMM_PORT "tcp:4560" // default port we use for normal communications /* Message header; interpreted by the other side, but never seen by the user application. DANGER: Add new fields AT THE END of the struct. Adding them any where else will break any code that is currently running. */ typedef struct { int32_t mtype; // message type ("long" network integer) int32_t plen; // payload length int32_t rmr_ver; // our internal message version number unsigned char xid[RMR_MAX_XID]; // space for user transaction id or somesuch unsigned char sid[RMR_MAX_SID]; // sender ID for return to sender needs unsigned char src[RMR_MAX_SRC]; // name of the sender (source) unsigned char meid[RMR_MAX_MEID]; // managed element id. struct timespec ts; // timestamp ??? } uta_mhdr_t; /* Round robin group. */ typedef struct { int ep_idx; // next endpoint to send to int nused; // number of endpoints in the list int nendpts; // number allocated endpoint_t **epts; // the list of endpoints that we RR over } rrgroup_t; /* Routing table entry. This is a list of endpoints that can be sent messages of the given mtype. If there is more than one, we will round robin messags across the list. */ typedef struct { int mtype; // the message type for this list int nrrgroups; // number of rr groups to send to rrgroup_t** rrgroups; // one or more set of endpoints to round robin messages to } rtable_ent_t; /* The route table. */ typedef struct { void* hash; // hash table. } route_table_t; /* A wormhole is a direct connection between two endpoints that the user app can send to without message type based routing. */ typedef struct { int nalloc; // number of ep pointers allocated endpoint_t** eps; // end points directly referenced } wh_mgt_t; /* This manages an array of pointers to IP addresses that are associated with one of our interfaces. For now, we don't need to map the addr to a specific interface, just know that it is one of ours. */ typedef struct { char** addrs; // all ip addresses we found int naddrs; // num actually used } if_addrs_t; // --------------- ring things ------------------------------------------------- typedef struct ring { uint16_t head; // index of the head of the ring (insert point) uint16_t tail; // index of the tail (extract point) uint16_t nelements; // number of elements in the ring void** data; // the ring data (pointers to blobs of stuff) } ring_t; // -------------- common static prototypes -------------------------------------- //---- tools ---------------------------------- static int has_myip( char const* buf, if_addrs_t* list, char sep, int max ); static int uta_tokenise( char* buf, char** tokens, int max, char sep ); static char* uta_h2ip( char const* hname ); static int uta_lookup_rtg( uta_ctx_t* ctx ); static int uta_has_str( char const* buf, char const* str, char sep, int max ); // --- message ring -------------------------- static void* uta_mk_ring( int size ); static void uta_ring_free( void* vr ); static inline void* uta_ring_extract( void* vr ); static inline int uta_ring_insert( void* vr, void* new_data ); // --- message and context management -------- static int ie_test( void* r, int i_factor, long inserts ); // ----- route table generic static things --------- static void collect_things( void* st, void* entry, char const* name, void* thing, void* vthing_list ); static void del_rte( void* st, void* entry, char const* name, void* thing, void* data ); static char* uta_fib( char* fname ); static route_table_t* uta_rt_init( ); static route_table_t* uta_rt_clone( route_table_t* srt ); static void uta_rt_drop( route_table_t* rt ); static endpoint_t* uta_add_ep( route_table_t* rt, rtable_ent_t* rte, char* ep_name, int group ); static rtable_ent_t* uta_add_rte( route_table_t* rt, int mtype, int nrrgroups ); static endpoint_t* uta_get_ep( route_table_t* rt, char const* ep_name ); static void read_static_rt( uta_ctx_t* ctx, int vlevel ); static void parse_rt_rec( uta_ctx_t* ctx, char* buf, int vlevel ); static void* rtc( void* vctx ); static endpoint_t* rt_ensure_ep( route_table_t* rt, char const* ep_name ); #endif