// //protocol.c // // //-UserX 2001/11/13 #include #include #include "misc/compat.h" #include "net/protocol.h" #include "pipe/pipe.h" #include "pipeface/pipeface.h" #include "base/str.h" #include "base/strarray.h" #include "base/logger.h" #include "net/sock.h" #include "net/protocfg.h" #include "base/array.h" PipeProtocolEntry blankpipeprotocolentry = BLANKPIPEFACEPROTOCOLENTRY; PipeFaceProtocolEntry blankpipefaceprotocolentry = BLANKPIPEFACEPROTOCOLENTRY; PipeProtocolArrayHandle *pparray = NULL; PipeFaceProtocolArrayHandle *pfparray = NULL; void protocolInit(void) { if(pparray == NULL) { pparray = (PipeProtocolArrayHandle *)arrayMake(sizeof(PipeProtocolEntry), 0, &blankpipeprotocolentry, NULL, NULL); } if(pfparray == NULL) { pfparray = (PipeFaceProtocolArrayHandle *)arrayMake(sizeof(PipeFaceProtocolEntry), 0, &blankpipefaceprotocolentry, NULL, NULL); } } void protocolAddPipeList(PipeProtocolEntry *ppelist) { int i; int j; if(ppelist == NULL) { return; } protocolInit(); for(i = 0; ppelist[i].pipename != NULL; i++) { j = pparray->size; arrayInsert((ArrayHandle *)pparray, pparray->size, 1); pparray->data[j] = ppelist[i]; } } void protocolAddPipeFaceList(PipeFaceProtocolEntry *pfpelist) { int i; int j; if(pfpelist == NULL) { return; } protocolInit(); for(i = 0; pfpelist[i].pipename != NULL; i++) { j = pfparray->size; arrayInsert((ArrayHandle *)pfparray, pfparray->size, 1); pfparray->data[j] = pfpelist[i]; } } void protocolClearPipeList(void) { protocolInit(); arrayDelete((ArrayHandle *)pparray, 0, pparray->size); } void protocolClearPipeFaceList(void) { protocolInit(); arrayDelete((ArrayHandle *)pfparray, 0, pfparray->size); } Pipe *protocolGetPipe(char *pipename, char *options) { int i; protocolInit(); for(i = 0; i <= pparray->size; i++) { if(stringCaseCompare(pparray->data[i].pipename, pipename) == 0) { return (pparray->data[i].make)(pipename, options); } } LOGERROR(stringJoinMany("Pipe type \"", pipename, "\" not found.", NULL)); return NULL; /* switch(stringIntPairSearch(pipelist, pipename)) { case PL_CRYPT: return pipecryptMake(options); case PL_STEADY: return pipesteadyMake(options); case PL_SPURT: return pipespurtMake(options); case PL_DUMMY: return pipedummyMake(options); case PL_BACK: return pipebackwardMake(options); case -1: //todo: checking of available masquerading protocols if(stringIntPairSearch(pipemasqlist, pipename) != -1) { pipemasqMake(pipename); } LOGERROR(stringJoinMany("Pipe type \"", pipename, "\" not found.", NULL)); return NULL; default: LOGERROR(stringJoinMany("Internal error, pipe type \"", pipename, "\" found but unhandled by code.", NULL)); return NULL; } */ } PipeFace *protocolGetPipeFace(char *pipefacename, char *options) { int i; protocolInit(); for(i = 0; i <= pfparray->size; i++) { if(stringCaseCompare(pfparray->data[i].pipename, pipefacename) == 0) { return (pfparray->data[i].make)(pipefacename, options); } } LOGERROR(stringJoinMany("Pipeface type \"", pipefacename, "\" not found.", NULL)); return NULL; /* switch(stringIntPairSearch(pipefacelist, pipefacename)) { case PFL_CORE: case PFL_RAW: return pfcoreMake(options); case PFL_VIRC: return pfvircMake(options); case -1: LOGERROR(stringJoinMany("Pipeface type \"", pipefacename, "\" not found.", NULL)); return NULL; default: LOGERROR(stringJoinMany("Internal error pipeface type \"", pipefacename, "\" found but unhandled by code.", NULL)); return NULL; } */ } //builds a pipe chain attached to an existing socket PipeFace *protocolBuildPipe(SockHandle *sh, char *protocol) { char *s; char *p; Pipe *newpipe = NULL; Pipe *backpipe = &sh->IOPipe; PipeFace *pf = NULL; if(sh == NULL) { return NULL; } if(isStringBlank(protocol)) { LOGERROR("Missing protocol string (check for missing 'protocol' or 'networkprotocol' settings)."); return NULL; } //todo: validate protocol string s = stringCopy(protocol); for(p = stringSplit(s, ":"); !isStringBlank(s); p = stringSplit(s, ":")) { //todo:error checking newpipe = protocolGetPipe(p, ""); //todo: extract options if(newpipe == NULL) { newpipe = backpipe; while(newpipe != &sh->IOPipe) { backpipe = newpipe->backPipe; pipeDetach(newpipe); newpipe = backpipe; } return NULL; } pipeAttach(backpipe, newpipe); backpipe = newpipe; stringFree(p); } stringFree(s); //todo: error checking pf = protocolGetPipeFace(p, ""); //todo: extract options pipefaceInit(pf, backpipe); stringFree(p); return pf; }