5359edc160de518d8e43fdd3448365c15b912c3c galt Mon Jul 22 11:48:10 2019 -0700 Added ipv6 support. Listening processes us hybrid dual stack feature of OS to simplify implementation and use a single listening socket. Works with both TCP and UDP. Parasol working. geoIp also updated and ready for IPv6. Should be invisible to most users, while providing connections via ipv6 where available. Supports both ipv4 and ipv6. diff --git src/gfServer/gfServer.c src/gfServer/gfServer.c index 1976389..36f8e01 100644 --- src/gfServer/gfServer.c +++ src/gfServer/gfServer.c @@ -58,66 +58,66 @@ int maxDnaHits = 100; /* Can be overridden from command line. */ int maxTransHits = 200; /* Can be overridden from command line. */ int maxGap = gfMaxGap; boolean seqLog = FALSE; boolean ipLog = FALSE; boolean doMask = FALSE; boolean canStop = FALSE; void usage() /* Explain usage and exit. */ { errAbort( "gfServer v %s - Make a server to quickly find where DNA occurs in genome\n" " To set up a server:\n" " gfServer start host port file(s)\n" - " where the files are .nib or .2bit format files specified relative to the current directory\n" + " where the files are .2bit or .nib format files specified relative to the current directory\n" " To remove a server:\n" " gfServer stop host port\n" " To query a server with DNA sequence:\n" " gfServer query host port probe.fa\n" " To query a server with protein sequence:\n" " gfServer protQuery host port probe.fa\n" " To query a server with translated DNA sequence:\n" " gfServer transQuery host port probe.fa\n" " To query server with PCR primers:\n" " gfServer pcr host port fPrimer rPrimer maxDistance\n" - " To process one probe fa file against a .nib format genome (not starting server):\n" - " gfServer direct probe.fa file(s).nib\n" + " To process one probe fa file against a .2bit format genome (not starting server):\n" + " gfServer direct probe.fa file(s).2bit\n" " To test PCR without starting server:\n" - " gfServer pcrDirect fPrimer rPrimer file(s).nib\n" + " gfServer pcrDirect fPrimer rPrimer file(s).2bit\n" " To figure out usage level:\n" " gfServer status host port\n" " To get input file list:\n" " gfServer files host port\n" "options:\n" " -tileSize=N Size of n-mers to index. Default is 11 for nucleotides, 4 for\n" " proteins (or translated nucleotides).\n" " -stepSize=N Spacing between tiles. Default is tileSize.\n" " -minMatch=N Number of n-mer matches that trigger detailed alignment.\n" " Default is 2 for nucleotides, 3 for proteins.\n" " -maxGap=N Number of insertions or deletions allowed between n-mers.\n" " Default is 2 for nucleotides, 0 for proteins.\n" " -trans Translate database to protein in 6 frames. Note: it is best\n" " to run this on RepeatMasked data in this case.\n" " -log=logFile Keep a log file that records server requests.\n" " -seqLog Include sequences in log file (not logged with -syslog).\n" " -ipLog Include user's IP in log file (not logged with -syslog).\n" " -debugLog Include debugging info in log file.\n" " -syslog Log to syslog.\n" " -logFacility=facility Log to the specified syslog facility - default local0.\n" - " -mask Use masking from nib file.\n" + " -mask Use masking from .2bit file.\n" " -repMatch=N Number of occurrences of a tile (n-mer) that triggers repeat masking the\n" " tile. Default is %d.\n" " -maxDnaHits=N Maximum number of hits for a DNA query that are sent from the server.\n" " Default is %d.\n" " -maxTransHits=N Maximum number of hits for a translated query that are sent from the server.\n" " Default is %d.\n" " -maxNtSize=N Maximum size of untranslated DNA query sequence.\n" " Default is %d.\n" " -maxAaSize=N Maximum size of protein or translated DNA queries.\n" " Default is %d.\n" " -canStop If set, a quit message will actually take down the server.\n" , gfVersion, repMatch, maxDnaHits, maxTransHits, maxNtSize, maxAaSize ); } @@ -211,31 +211,30 @@ clump->tEnd += clump->target->start; gfClumpDump(gf, clump, stdout); } genoFindFree(&gf); } int getPortIx(char *portName) /* Convert from ascii to integer. */ { if (!isdigit(portName[0])) errAbort("Expecting a port number got %s", portName); return atoi(portName); } -struct sockaddr_in sai; /* Some system socket info. */ /* Some variables to gather statistics on usage. */ long baseCount = 0, blatCount = 0, aaCount = 0, pcrCount = 0; int warnCount = 0; int noSigCount = 0; int missCount = 0; int trimCount = 0; void dnaQuery(struct genoFind *gf, struct dnaSeq *seq, int connectionHandle, char buf[256]) /* Handle a query for DNA/DNA match. */ { struct gfClump *clumpList = NULL, *clump; int limit = 1000; int clumpCount = 0, hitCount = -1; @@ -496,31 +495,31 @@ { if (ntVal[c] < 0) return TRUE; } return FALSE; } void startServer(char *hostName, char *portName, int fileCount, char *seqFiles[]) /* Load up index and hang out in RAM. */ { struct genoFind *gf = NULL; static struct genoFind *transGf[2][3]; char buf[256]; char *line, *command; -struct sockaddr_in fromAddr; +struct sockaddr_in6 fromAddr; socklen_t fromLen; int readSize; int socketHandle = 0, connectionHandle = 0; int port = atoi(portName); time_t curtime; struct tm *loctime; char timestr[256]; netBlockBrokenPipes(); curtime = time (NULL); /* Get the current time. */ loctime = localtime (&curtime); /* Convert it to local time representation. */ strftime (timestr, sizeof(timestr), "%Y-%m-%d %H:%M", loctime); /* formate datetime as string */ logInfo("gfServer version %s on host %s, port %s (%s)", gfVersion, @@ -558,37 +557,37 @@ if (connectionHandle < 0) { warn("Error accepting the connection"); ++warnCount; ++connectFailCount; if (connectFailCount >= 100) errAbort("100 continuous connection failures, no point in filling up the log in an infinite loop."); continue; } else { connectFailCount = 0; } if (ipLog) { - if (fromAddr.sin_family == AF_INET) - { - char dottedQuad[17]; - internetIpToDottedQuad(ntohl(fromAddr.sin_addr.s_addr), dottedQuad); + struct sockaddr_in6 clientAddr; + unsigned int addrlen=sizeof(clientAddr); + getpeername(connectionHandle, (struct sockaddr *)&clientAddr, &addrlen); + char ipStr[NI_MAXHOST]; + getAddrAsString6n4((struct sockaddr_storage *)&clientAddr, ipStr, sizeof ipStr); logInfo("gfServer version %s on host %s, port %s connection from %s", - gfVersion, hostName, portName, dottedQuad); - } + gfVersion, hostName, portName, ipStr); } readSize = read(connectionHandle, buf, sizeof(buf)-1); if (readSize < 0) { warn("Error reading from socket: %s", strerror(errno)); ++warnCount; close(connectionHandle); continue; } if (readSize == 0) { warn("Zero sized query"); ++warnCount; close(connectionHandle); continue;