/* * Create a proxy structure for listening or connecting. * * Buffers are not allocated until a connection is established. */ nbProxy *nbProxyConstruct(nbCELL context,int client,nbCELL tlsContext,void *handle, int (*producer)(nbCELL context,nbProxy *proxy,void *handle), int (*consumer)(nbCELL context,nbProxy *proxy,void *handle), void (*shutdown)(nbCELL context,nbProxy *proxy,void *handle,int code)){ nbProxy *proxy; nbTLSX *tlsx=NULL; char *uri; if(proxyTrace) nbLogMsg(context,0,'T',"nbProxyConstruct: called"); // allocate a proxy structure proxy=(nbProxy *)nbAlloc(sizeof(nbProxy)); memset(proxy,0,sizeof(nbProxy)); proxy->handle=handle; proxy->producer=producer; proxy->consumer=consumer; proxy->shutdown=shutdown; if(!client){ // for a server go ahead and uri=nbTermOptionString(tlsContext,"uri",""); if(!*uri){ nbLogMsg(context,0,'E',"nbProxyConstruct: uri not defined in %s",nbTermGetName(context,tlsContext)); nbFree(proxy,sizeof(nbProxy)); return(NULL); } nbLogMsg(context,0,'T',"nbProxyConstruct: uri=%s",uri); if(strncmp(uri,"tls:",4)==0 || strncmp(uri,"https:",6)==0) tlsx=nbTlsLoadContext(context,tlsContext,proxy,client); proxy->tls=nbTlsCreate(tlsx,uri); if(!proxy->tls){ nbLogMsg(context,0,'E',"nbProxyConstruct: unable to create tls for uri=%s",uri); nbFree(proxy,sizeof(nbProxy)); return(NULL); } } return(proxy); }
extern void *baselineBind(nbCELL context,void *moduleHandle,nbCELL skill,nbCELL arglist,char *text){ BTreeSkill *skillHandle; char *cursor=text; skillHandle=(BTreeSkill *)nbAlloc(sizeof(BTreeSkill)); skillHandle->trace=0; while(*cursor==' ') cursor++; while(*cursor!=0 && *cursor!=';'){ if(strncmp(cursor,"trace",5)==0){ skillHandle->trace=1; cursor+=5; } else{ nbLogMsg(context,0,'T',"Option not recognized at \"%s\".",cursor); nbFree(skillHandle,sizeof(BTreeSkill)); return(NULL); } while(*cursor==' ' || *cursor==',') cursor++; } /* Still trying to figure out if we want to require method binding */ nbSkillSetMethod(context,skill,NB_NODE_CONSTRUCT,baselineConstruct); nbSkillSetMethod(context,skill,NB_NODE_ENABLE,baselineEnable); nbSkillSetMethod(context,skill,NB_NODE_ASSERT,baselineAssert); nbSkillSetMethod(context,skill,NB_NODE_EVALUATE,baselineEvaluate); nbSkillSetMethod(context,skill,NB_NODE_SHOW,baselineShow); nbSkillSetMethod(context,skill,NB_NODE_COMMAND,baselineCommand); return(skillHandle); }
/* * Internal function to remove a node from a tree - used by assert() method * * Returns: * 0 - don't remove the parent node * 1 - consider removing the parent node (if no value or root) * 2 - remove the parent node (even if it has a value and/or root) */ static int removeNode(nbCELL context,BTree *tree,BTreeNode **nodeP,nbSET *argSetP){ NB_TreePath path; BTreeNode *node=*nodeP; nbCELL argCell; int code=1; argCell=nbListGetCellValue(context,argSetP); if(argCell==NULL){ if(node==NULL) return(3); // the perfect match - nothing to nothing code=2; return(2); // } else{ if(node==NULL) return(0); // can't match to empty tree if(tree->options&BTREE_OPTION_ORDER) node=(BTreeNode *)nbTreeLocateValue(&path,argCell,(NB_TreeNode **)nodeP,treeCompare,context); else node=nbTreeLocate(&path,argCell,(NB_TreeNode **)nodeP); nbCellDrop(context,argCell); if(node==NULL) return(0); // didn't find argument switch(removeNode(context,tree,&node->root,argSetP)){ case 0: return(0); case 1: if(node->root!=NULL) return(0); // still need this node break; // For case 2 we just fall thru to unlink the node } } if(node->root!=NULL) return(0); nbTreeRemove(&path); // Remove node from binary search tree if(node->bnode.key!=NULL) node->bnode.key=nbCellDrop(context,(nbCELL)node->bnode.key); // release key //if(node->root!=NULL) node->root =removeTree(context,tree,node->root); nbFree(node,sizeof(BTreeNode)); return(code); }
// // Recursively remove all nodes in a binary tree // static void *removeTree(nbCELL context,BTree *tree,BTreeNode *node){ node->bnode.key=nbCellDrop(context,node->bnode.key); if(node->bnode.left!=NULL) node->bnode.left=removeTree(context,tree,(BTreeNode *)node->bnode.left); if(node->bnode.right!=NULL) node->bnode.right=removeTree(context,tree,(BTreeNode *)node->bnode.right); if(node->root!=NULL) node->root=removeTree(context,tree,node->root); nbFree(node,sizeof(BTreeNode)); return(NULL); }
int nbProxyDestroy(nbCELL context,nbProxy *proxy){ if(proxyTrace) nbLogMsg(context,0,'T',"nbProxyDestroy: called"); if(proxy->tls) nbLogMsg(context,0,'T',"nbProxyDestroy: uri=%s",proxy->tls->uriMap[0].uri); if(proxy->tls) nbTlsFree(proxy->tls); nbProxyBookClose(context,&proxy->ibook); nbProxyBookClose(context,&proxy->obook); nbFree(proxy,sizeof(nbProxy)); return(0); }
/* * destroy() method * * undefine <node> * */ static int auditDestroy(nbCELL context,void *skillHandle,nbAudit *audit){ if(audit->trace) nbLogMsg(context,0,'T',"auditDestroy called"); auditDisable(context,skillHandle,audit); nbCellDrop(context,audit->fileNameCell); nbCellDrop(context,audit->scheduleCell); nbCellDrop(context,audit->translatorCell); nbCellDrop(context,audit->translatorNameCell); nbFree(audit,sizeof(struct NB_MOD_AUDIT)); return(0); }
static void nbSentenceDestroy(NB_Sentence *cell) { NB_Sentence *sentence,**sentenceP; NB_Hash *hash=cell->cell.object.type->hash; dropObject((NB_Object *)cell->term); if(cell->args) dropObject((NB_Object *)cell->args); sentenceP=(NB_Sentence **)&(hash->vect[cell->cell.object.hashcode&hash->mask]); for(sentence=*sentenceP; sentence!=NULL && sentence!=cell; sentence=*sentenceP) sentenceP=(NB_Sentence **)&sentence->cell.object.next; if(sentence==cell) *sentenceP=(NB_Sentence *)sentence->cell.object.next; hash->objects--; nbFree(cell,sizeof(NB_Sentence)); }
/* * Establish a connection with a server * * This is a prototype. Not totally keen on the need for this function * to build the nbTLSX and nbTLS structures. Would be better if we * could just clone an nbTLS structure build in advance. However, this * requires some thought to get the TLS/SSL context and handle right. * Will look at this more later. * * Returns: * * NULL on error * Pointer to proxy on success * */ nbProxy *nbProxyConnect(nbCELL context,nbTLSX *tlsx,char *uri,void *handle, int (*producer)(nbCELL context,nbProxy *proxy,void *handle), int (*consumer)(nbCELL context,nbProxy *proxy,void *handle), void (*shutdown)(nbCELL context,nbProxy *proxy,void *handle,int code)){ int rc; nbProxy *proxy; proxy=(nbProxy *)nbAlloc(sizeof(nbProxy)); memset(proxy,0,sizeof(nbProxy)); proxy->tls=nbTlsCreate(tlsx,uri); if(!proxy->tls){ nbLogMsg(context,0,'E',"nbProxyConnect: unable to create tls handle"); //nbTlsFreeContext(tlsx); nbFree(proxy,sizeof(nbProxy)); return(NULL); } nbLogMsg(context,0,'I',"Attempting proxy connection with %s",nbTlsGetUri(proxy->tls)); proxy->handle=handle; proxy->producer=producer; proxy->consumer=consumer; proxy->shutdown=shutdown; proxy->flags|=NB_PROXY_FLAG_CLIENT; // flag as client for failover retries rc=nbTlsConnectNonBlocking(proxy->tls); switch(rc){ case 0: nbLogMsg(context,0,'I',"Proxy connection established with %s",nbTlsGetUri(proxy->tls)); nbListenerAddWrite(context,proxy->tls->socket,proxy,nbProxyConnecter); proxy->flags|=NB_PROXY_FLAG_WRITE_WAIT; break; case 1: nbListenerAddWrite(context,proxy->tls->socket,proxy,nbProxyConnectHandshaker); proxy->flags|=NB_PROXY_FLAG_WRITE_WAIT; // fall thru to also wait for read to get notification on errors case 2: nbListenerAdd(context,proxy->tls->socket,proxy,nbProxyConnectHandshaker); proxy->flags|=NB_PROXY_FLAG_READ_WAIT; if(proxyTrace) nbLogMsg(context,0,'T',"nbProxyConnect: waiting on %s",nbTlsGetUri(proxy->tls)); break; default: nbLogMsg(context,0,'W',"nbProxyConnect: Unable to connect to %s - %s",nbTlsGetUri(proxy->tls),strerror(errno)); while((rc=nbProxyConnectNext(context,proxy))==-1); if(rc==1){ nbProxyShutdown(context,proxy,-1); return(NULL); } } return(proxy); }
/* * Load text object from file */ NB_Text *nbTextLoad(char *fileName){ NB_Text *text; FILE *fp; long len; short size; char *buf; fp=fopen(fileName,"r"); // 2013-01-01 eat - VID 5420-0.8.13-1 Intentional if(fp==NULL){ outMsg(0,'E', "Can't open text file %s",fileName); return(NULL); } outMsg(0,'T', "input file %s opened",fileName); if(fseek(fp,0,SEEK_END)!=0){ outMsg(0,'E', "fseek end of %s failed, errno= %d (%s)",fileName,errno,strerror(errno)); fclose(fp); return(NULL); } len=ftell(fp); if(fseek(fp,0,SEEK_SET)!=0) { outMsg(0,'E', "fseek begin of %s failed, errno= %d (%s)",fileName,errno,strerror(errno)); fclose(fp); return(NULL); } if(len>0x8000-sizeof(NB_Text)){ outMsg(0,'E', "fseek begin of %s failed, errno= %d (%s)",fileName,errno,strerror(errno)); fclose(fp); return(NULL); } size=sizeof(NB_Text)+len; text=(NB_Text *)newObject(textType,NULL,size); buf=text->value; if(fread(buf,len,1,fp)<1){ outMsg(0,'E', "fread of %s failed, errno= %d (%s)",fileName,errno,strerror(errno)); nbFree(text,size); fclose(fp); // 2012-12-18 eat - CID 751609 return(NULL); } fclose(fp); *(buf+len)=0; return(text); }
/* * Shutdown proxy connection * * Note: We may need to define a set of values for the code * parameter. Currently we assume the caller to this function * and the proxy shutdown handler have a common understanding. * It isn't clear that is always possible unless we provide * a definition to be used by all shutdown handlers and callers * of this function. */ int nbProxyShutdown(nbCELL context,nbProxy *proxy,int code){ if(proxyTrace) nbLogMsg(context,0,'T',"nbProxyShutdown: %s code=%d proxy=%p proxy->handle=%p",proxy->tls->uriMap[proxy->tls->uriIndex].uri,code,proxy,proxy->handle); if(proxy->shutdown) (*proxy->shutdown)(context,proxy,proxy->handle,code); if(proxy->flags&NB_PROXY_FLAG_WRITE_WAIT){ nbListenerRemoveWrite(context,proxy->tls->socket); proxy->flags&=0xff-NB_PROXY_FLAG_WRITE_WAIT; } if(proxy->flags&NB_PROXY_FLAG_READ_WAIT){ nbListenerRemove(context,proxy->tls->socket); proxy->flags&=0xff-NB_PROXY_FLAG_READ_WAIT; } if(proxy->tls){ nbTlsClose(proxy->tls); // do this after the removes because it clears the socket nbTlsFree(proxy->tls); } proxy->flags=0; nbProxyBookClose(context,&proxy->ibook); nbProxyBookClose(context,&proxy->obook); nbFree(proxy,sizeof(nbProxy)); return(0); }
void *servantDestroy(nbCELL context,void *skillHandle,nbServant *servant,int option){ nbFree(servant,sizeof(nbServant)); return(NULL); }
void destroyText(NB_Text *text){ nbFree(text,sizeof(NB_Text)+strlen(text->value)); }
/* * destroy() method * * undefine <node> */ static int serverDestroy(nbCELL context,void *skillHandle,NB_MOD_Snmptrap *snmptrap){ nbLogMsg(context,0,'T',"serverDestroy called"); if(snmptrap->socket!=0) serverDisable(context,skillHandle,snmptrap); nbFree(snmptrap,sizeof(NB_MOD_Snmptrap)); return(0); }
/* * destroy() method * * undefine <node> */ static int loggerDestroy(nbCELL context,void *skillHandle,NB_MOD_Logger *logger){ nbFree(logger,sizeof(NB_MOD_Logger)); return(0); }
/* * destroy() method * * undefine <node> */ static int clientDestroy(nbCELL context,void *skillHandle,NB_MOD_Client *client){ nbLogMsg(context,0,'T',"clientDestroy called"); nbFree(client,sizeof(NB_MOD_Client)); return(0); }