AmendHub

Download:

jcs

/

wallops

/

amendments

/

51

tcp: Sync with upstream, add atexit destroyer


jcs made amendment 51 about 1 month ago
--- AddressXlation.h Tue Sep 6 12:23:44 2022 +++ AddressXlation.h Thu May 19 14:10:57 2022 @@ -1,74 +0,0 @@ -/* - AddressXlation.h - MacTCP name to address translation routines. - - Copyright Apple Computer, Inc. 1988 - All rights reserved - -*/ - -#ifndef __ADDRESSXLATION__ -#define __ADDRESSXLATION__ - -#include "MacTCP.h" - -#define NUM_ALT_ADDRS 4 - -typedef struct hostInfo { - int _pad; /* XXX: i don't know why this is needed, but without it, - * StrToAddrProcPtr() returns everything shifted 2 bytes */ - int rtnCode; - char cname[255]; - unsigned long addr[NUM_ALT_ADDRS]; -}; - -typedef enum AddrClasses { - A = 1, - NS, - CNAME = 5, - lastClass = 65535 -}; - -typedef struct cacheEntryRecord { - char *cname; - unsigned short type; - enum AddrClasses class; - unsigned long ttl; - union { - char *name; - ip_addr addr; - } rdata; -}; - -typedef pascal void (*EnumResultProcPtr)(struct cacheEntryRecord *cacheEntryRecordPtr, - char *userDataPtr); -typedef pascal void (*ResultProcPtr)(struct hostInfo *hostInfoPtr, - char *userDataPtr); - -extern OSErr OpenResolver(char *fileName); -extern OSErr StrToAddr(char *hostName, struct hostInfo *hostInfoPtr, - ResultProcPtr resultProc, char *userDataPtr); -extern OSErr AddrToStr(unsigned long addr, char *addrStr); -extern OSErr EnumCache(EnumResultProcPtr enumResultProc, char *userDataPtr); -extern OSErr AddrToName(ip_addr addr, struct hostInfo *hostInfoPtr, - ResultProcPtr resultProc, char *userDataPtr); -extern OSErr CloseResolver(void); - -/* - * The above functions call into the dnr resource and pass the function id - * and function-specific arguments, so the compiler needs to know the types - */ -typedef OSErr (*OpenResolverProcPtr)(UInt32, char *); -typedef OSErr (*CloseResolverProcPtr)(UInt32); -typedef OSErr (*StrToAddrProcPtr)(UInt32, char *hostName, - struct hostInfo *hostInfoPtr, ResultProcPtr resultProc, - char *userDataPtr); -typedef OSErr (*AddrToStrProcPtr)(UInt32, unsigned long addr, - char *addrStr); -typedef OSErr (*EnumCacheProcPtr)(UInt32, EnumResultProcPtr enumResultProc, - char *userDataPtr); -typedef OSErr (*AddrToNameProcPtr)(UInt32, ip_addr addr, - struct hostInfo *hostInfoPtr, ResultProcPtr resultProc, - char *userDataPtr); - -#endif \ No newline at end of file --- dnr.c Tue Sep 6 12:23:52 2022 +++ dnr.c Fri Aug 30 09:54:55 2024 @@ -6,14 +6,11 @@ * Modifications by Jim Matthews, Dartmouth College, 5/91 */ -#include <OSUtils.h> -#include <Files.h> #include <Folders.h> -#include <GestaltEqu.h> -#include <Traps.h> +#include "dnr.h" +#include "tcp.h" +#include "util.h" -#include "AddressXlation.h" - #define OPENRESOLVER 1 #define CLOSERESOLVER 2 #define STRTOADDR 3 @@ -23,83 +20,12 @@ #define HINFO 7 #define MXINFO 8 -TrapType GetTrapType(unsigned long theTrap); -Boolean TrapAvailable(unsigned long trap); -void GetSystemFolder(short *vRefNumP, long *dirIDP); -void GetCPanelFolder(short *vRefNumP, long *dirIDP); short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID); short OpenOurRF(void); Handle dnr = nil; -TrapType -GetTrapType(unsigned long theTrap) -{ - if (BitAnd(theTrap, 0x0800) > 0) - return (ToolTrap); - - return (OSTrap); -} - -Boolean -TrapAvailable(unsigned long trap) -{ - TrapType trapType = ToolTrap; - unsigned long numToolBoxTraps; - - if (NGetTrapAddress(_InitGraf, ToolTrap) == - NGetTrapAddress(0xAA6E, ToolTrap)) - numToolBoxTraps = 0x200; - else - numToolBoxTraps = 0x400; - - trapType = GetTrapType(trap); - if (trapType == ToolTrap) { - trap = BitAnd(trap, 0x07FF); - if (trap >= numToolBoxTraps) - trap = _Unimplemented; - } - - return (NGetTrapAddress(trap, trapType) != - NGetTrapAddress(_Unimplemented, ToolTrap)); -} - -void -GetSystemFolder(short *vRefNumP, long *dirIDP) -{ - SysEnvRec info; - long wdProcID; - - SysEnvirons(1, &info); - if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) { - *vRefNumP = 0; - *dirIDP = 0; - } -} - -void -GetCPanelFolder(short *vRefNumP, long *dirIDP) -{ - Boolean hasFolderMgr = false; - long feature; - - if (TrapAvailable(_GestaltDispatch) && - Gestalt(gestaltFindFolderAttr, &feature) == noErr) - hasFolderMgr = true; - - if (!hasFolderMgr) { - GetSystemFolder(vRefNumP, dirIDP); - return; - } - - if (FindFolder(kOnSystemDisk, kControlPanelFolderType, - kDontCreateFolder, vRefNumP, dirIDP) != noErr) { - *vRefNumP = 0; - *dirIDP = 0; - } -} - /* * SearchFolderForDNRP is called to search a folder for files that might * contain the 'dnrp' resource @@ -113,7 +39,7 @@ SearchFolderForDNRP(long targetType, long targetCreato short refnum; fi.fileParam.ioCompletion = nil; - fi.fileParam.ioNamePtr = filename; + fi.fileParam.ioNamePtr = (StringPtr)&filename; fi.fileParam.ioVRefNum = vRefNum; fi.fileParam.ioDirID = dirID; fi.fileParam.ioFDirIndex = 1; @@ -145,7 +71,7 @@ OpenOurRF(void) long dirID; /* first search Control Panels for MacTCP 1.1 */ - GetCPanelFolder(&vRefNum, &dirID); + GetSystemSubfolder(kControlPanelFolderType, false, &vRefNum, &dirID); refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID); if (refnum != -1) return (refnum); @@ -157,7 +83,7 @@ OpenOurRF(void) return (refnum); /* finally, search Control Panels for MacTCP 1.0.x */ - GetCPanelFolder(&vRefNum, &dirID); + GetSystemSubfolder(kControlPanelFolderType, false, &vRefNum, &dirID); refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID); if (refnum != -1) return (refnum); @@ -305,4 +231,40 @@ MXInfo(char *hostName, struct returnRec *returnRecPtr, return ((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr)); } -#endif \ No newline at end of file +#endif + +OSErr +DNSResolveName(char *name, unsigned long *ipAddress, void (*yielder)(void)) +{ + OSErr osErr; + struct hostInfo aHostInfo; + volatile int done = 0; + + osErr = OpenResolver(nil); + if (osErr) + return osErr; + + osErr = StrToAddr(name, &aHostInfo, (ResultProcPtr)StrToAddrMarkDone, + (char *)&done); + + if (osErr == cacheFault) { + /* StrToAddrMarkDone will set done when DNS resolution finishes */ + while (!done) { + if (yielder) + yielder(); + else + SystemTask(); + } + } + + if ((aHostInfo.rtnCode == noErr) || (aHostInfo.rtnCode == cacheFault)) { + /* use the first IP address for this host */ + *ipAddress = aHostInfo.addr[0]; + osErr = noErr; + } else + osErr = aHostInfo.rtnCode; + + /* leave resolver open for faster lookups in the future */ + + return osErr; +} \ No newline at end of file --- dnr.h Fri Aug 30 09:55:34 2024 +++ dnr.h Fri Aug 30 09:55:34 2024 @@ -0,0 +1,74 @@ +/* + AddressXlation.h + MacTCP name to address translation routines. + + Copyright Apple Computer, Inc. 1988 + All rights reserved + +*/ + +#ifndef __ADDRESSXLATION__ +#define __ADDRESSXLATION__ + +#include "MacTCP.h" + +#define NUM_ALT_ADDRS 4 + +struct hostInfo { + int _pad; /* XXX: i don't know why this is needed, but without it, + * StrToAddrProcPtr() returns everything shifted 2 bytes */ + int rtnCode; + char cname[255]; + unsigned long addr[NUM_ALT_ADDRS]; +}; + +enum AddrClasses { + A = 1, + NS, + CNAME = 5, + lastClass = 65535 +}; + +struct cacheEntryRecord { + char *cname; + unsigned short type; + enum AddrClasses class; + unsigned long ttl; + union { + char *name; + ip_addr addr; + } rdata; +}; + +typedef pascal void (*EnumResultProcPtr)(struct cacheEntryRecord *cacheEntryRecordPtr, + char *userDataPtr); +typedef pascal void (*ResultProcPtr)(struct hostInfo *hostInfoPtr, + char *userDataPtr); + +extern OSErr OpenResolver(char *fileName); +extern OSErr StrToAddr(char *hostName, struct hostInfo *hostInfoPtr, + ResultProcPtr resultProc, char *userDataPtr); +extern OSErr AddrToStr(unsigned long addr, char *addrStr); +extern OSErr EnumCache(EnumResultProcPtr enumResultProc, char *userDataPtr); +extern OSErr AddrToName(ip_addr addr, struct hostInfo *hostInfoPtr, + ResultProcPtr resultProc, char *userDataPtr); +extern OSErr CloseResolver(void); + +/* + * The above functions call into the dnr resource and pass the function id + * and function-specific arguments, so the compiler needs to know the types + */ +typedef OSErr (*OpenResolverProcPtr)(UInt32, char *); +typedef OSErr (*CloseResolverProcPtr)(UInt32); +typedef OSErr (*StrToAddrProcPtr)(UInt32, char *hostName, + struct hostInfo *hostInfoPtr, ResultProcPtr resultProc, + char *userDataPtr); +typedef OSErr (*AddrToStrProcPtr)(UInt32, unsigned long addr, + char *addrStr); +typedef OSErr (*EnumCacheProcPtr)(UInt32, EnumResultProcPtr enumResultProc, + char *userDataPtr); +typedef OSErr (*AddrToNameProcPtr)(UInt32, ip_addr addr, + struct hostInfo *hostInfoPtr, ResultProcPtr resultProc, + char *userDataPtr); + +#endif \ No newline at end of file --- tcp.c Fri Dec 2 16:05:38 2022 +++ tcp.c Fri Aug 30 09:49:55 2024 @@ -1,4 +1,22 @@ +/* + * Copyright (c) 2020 joshua stein <jcs@jcs.org> + * Copyright (c) 1990-1992 by the University of Illinois Board of Trustees + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "tcp.h" @@ -8,9 +26,10 @@ short gIPPDriverRefNum; -pascal void StrToAddrMarkDone(struct hostInfo *hi, char *data); +static short _TCPAtexitInstalled = 0; +static StreamPtr _TCPStreams[10] = { 0 }; -unsigned long resolved_ip; +void _TCPAtexit(void); OSErr _TCPInit(void) @@ -29,10 +48,30 @@ _TCPInit(void) osErr = PBOpen(&pb, false); if (noErr == osErr) gIPPDriverRefNum = pb.ioParam.ioRefNum; - + + if (!_TCPAtexitInstalled) { + _atexit(_TCPAtexit); + _TCPAtexitInstalled = 1; + } + return osErr; } +void +_TCPAtexit(void) +{ + short n; + TCPiopb pb = { 0 }; + + for (n = 0; n < (sizeof(_TCPStreams) / sizeof(_TCPStreams[0])); n++) { + if (_TCPStreams[n] != 0) { + _TCPAbort(&pb, _TCPStreams[n], nil, nil, false); + _TCPRelease(&pb, _TCPStreams[n], nil, nil, false); + _TCPStreams[n] = 0; + } + } +} + OSErr _TCPGetOurIP(ip_addr *ip, long *netMask) { @@ -66,6 +105,7 @@ _TCPCreate(TCPiopb *pb, StreamPtr *stream, Ptr rcvBufP TCPIOCompletionProc ioCompletion, Boolean async) { OSErr osErr; + short n; memset(pb, 0, sizeof(*pb)); @@ -82,6 +122,13 @@ _TCPCreate(TCPiopb *pb, StreamPtr *stream, Ptr rcvBufP osErr = PBControl((ParmBlkPtr)pb, async); if (!async && (noErr == osErr)) { *stream = pb->tcpStream; + + for (n = 0; n < (sizeof(_TCPStreams) / sizeof(_TCPStreams[0])); n++) { + if (_TCPStreams[n] == 0) { + _TCPStreams[n] = pb->tcpStream; + break; + } + } } return osErr; @@ -94,7 +141,6 @@ _TCPPassiveOpen(TCPiopb *pb, StreamPtr stream, ip_addr Ptr userData, TCPIOCompletionProc ioCompletion, Boolean async) { OSErr osErr; - short index; memset(pb, 0, sizeof(*pb)); @@ -112,14 +158,12 @@ _TCPPassiveOpen(TCPiopb *pb, StreamPtr stream, ip_addr pb->csParam.open.remotePort = 0; pb->csParam.open.localHost = 0; pb->csParam.open.localPort = *localPort; - pb->csParam.open.tosFlags = 0; + pb->csParam.open.tosFlags = 0x1; /* low delay */ pb->csParam.open.precedence = 0; pb->csParam.open.dontFrag = 0; pb->csParam.open.timeToLive = 0; pb->csParam.open.security = 0; pb->csParam.open.optionCnt = 0; - for (index = 0; index < sizeof(pb->csParam.open.options); ++index) - pb->csParam.open.options[index] = 0; pb->csParam.open.userDataPtr = userData; osErr = PBControl((ParmBlkPtr) pb, async); @@ -175,11 +219,11 @@ _TCPActiveOpen(TCPiopb *pb, StreamPtr stream, ip_addr pb->csParam.open.userDataPtr = userData; osErr = PBControl((ParmBlkPtr) pb, async); - if (!async && (noErr == osErr)) { + if (!async && (osErr == noErr)) { *localIP = pb->csParam.open.localHost; *localPort = pb->csParam.open.localPort; } - + return osErr; } @@ -213,8 +257,6 @@ _TCPNoCopyRcv(TCPiopb *pb, StreamPtr stream, Ptr rdsPt unsigned short rdsLength, Ptr userData, TCPIOCompletionProc ioCompletion, Boolean async) { - OSErr osErr; - memset(pb, 0, sizeof(*pb)); pb->csCode = TCPNoCopyRcv; @@ -323,14 +365,14 @@ _TCPStatus(TCPiopb *pb, StreamPtr stream, struct TCPSt { OSErr osErr; - memset(pb, 0, sizeof(*pb)); - - pb->csCode = TCPStatus; pb->ioCompletion = ioCompletion; + pb->ioResult = 1; + pb->ioNamePtr = 0; + pb->ioVRefNum = 0; pb->ioCRefNum = gIPPDriverRefNum; + pb->csCode = TCPStatus; pb->tcpStream = stream; pb->csParam.status.userDataPtr = userData; - pb->ioResult = 1; osErr = PBControl((ParmBlkPtr)pb, async); if (!async && (noErr == osErr)) { @@ -345,7 +387,8 @@ _TCPRelease(TCPiopb *pb, StreamPtr stream, Ptr userDat TCPIOCompletionProc ioCompletion, Boolean async) { OSErr osErr; - + short n; + memset(pb, 0, sizeof(*pb)); pb->csCode = TCPRelease; @@ -358,6 +401,13 @@ _TCPRelease(TCPiopb *pb, StreamPtr stream, Ptr userDat osErr = PBControl((ParmBlkPtr)pb, async); + for (n = 0; n < (sizeof(_TCPStreams) / sizeof(_TCPStreams[0])); n++) { + if (_TCPStreams[n] == stream) { + _TCPStreams[n] = 0; + break; + } + } + return osErr; } @@ -382,52 +432,93 @@ _UDPMaxMTUSize(UDPiopb *pb, short *mtu) return osErr; } -/* convenience functions */ - -static pascal void -StrToAddrMarkDone(struct hostInfo *hi, char *data) +OSErr +_UDPCreate(UDPiopb *pb, StreamPtr *stream, Ptr rcvBufPtr, long rcvBufLen, + UDPNotifyProc aNotifyProc, Ptr userDataPtr, + UDPIOCompletionProc ioCompletion, Boolean async) { - volatile int *done = (int *)data; - *done = 1; + OSErr osErr; + + memset(pb, 0, sizeof(*pb)); + + pb->csCode = UDPCreate; + pb->ioCompletion = ioCompletion; + pb->ioCRefNum = gIPPDriverRefNum; + pb->ioResult = 1; + + pb->csParam.create.rcvBuff = rcvBufPtr; + pb->csParam.create.rcvBuffLen = rcvBufLen; + pb->csParam.create.notifyProc = aNotifyProc; + pb->csParam.create.userDataPtr = userDataPtr; + + osErr = PBControl((ParmBlkPtr)pb, async); + if (!async && (noErr == osErr)) { + *stream = pb->udpStream; + } + + return osErr; } + +OSErr +_UDPSend(UDPiopb *pb, StreamPtr stream, wdsEntry *wdsPtr, ip_addr remoteIP, + udp_port remotePort, Ptr userData, UDPIOCompletionProc ioCompletion, + Boolean async) +{ + memset(pb, 0, sizeof(*pb)); + + pb->csCode = UDPWrite; + pb->ioCompletion = ioCompletion; + pb->ioCRefNum = gIPPDriverRefNum; + pb->udpStream = stream; + pb->ioResult = 1; + pb->csParam.send.remoteHost = remoteIP; + pb->csParam.send.remotePort = remotePort; + pb->csParam.send.wdsPtr = (Ptr)wdsPtr; + pb->csParam.send.checkSum = 0; + pb->csParam.send.sendLength = 0; + pb->csParam.send.userDataPtr = userData; + + return PBControl((ParmBlkPtr)pb, async); +} + OSErr -TCPResolveName(char *name, unsigned long *ipAddress) +_UDPRelease(UDPiopb *pb, StreamPtr stream, Ptr userData, + UDPIOCompletionProc ioCompletion, Boolean async) { OSErr osErr; - struct hostInfo aHostInfo; - volatile int done = 0; - - osErr = OpenResolver(nil); - if (osErr) - return osErr; - osErr = StrToAddr(name, &aHostInfo, (ResultProcPtr)StrToAddrMarkDone, - (char *)&done); + memset(pb, 0, sizeof(*pb)); - if (osErr == cacheFault) { - /* StrToAddrMarkDone will set done when DNS resolution finishes */ - while (!done) - ; - } + pb->csCode = UDPRelease; + pb->ioCompletion = ioCompletion; + pb->ioCRefNum = gIPPDriverRefNum; + pb->udpStream = stream; + pb->ioResult = 1; - if ((aHostInfo.rtnCode == noErr) || (aHostInfo.rtnCode == cacheFault)) { - /* use the first IP address for this host */ - *ipAddress = aHostInfo.addr[0]; - osErr = noErr; - } else - osErr = aHostInfo.rtnCode; + //pb->csParam.status.userDataPtr = userData; + + osErr = PBControl((ParmBlkPtr)pb, async); - CloseResolver(); return osErr; } -long + +/* convenience functions */ + +pascal void +StrToAddrMarkDone(struct hostInfo *hi, char *data) +{ + volatile int *done = (int *)data; + *done = 1; +} + +unsigned long ip2long(char *ip) { - long address = 0; - int dotcount = 0, i; - unsigned int b = 0; + unsigned long address = 0; + short dotcount = 0, i; + unsigned short b = 0; for (i = 0; ip[i] != 0; i++) { if (ip[i] == '.') { @@ -456,7 +547,7 @@ void long2ip(unsigned long num, char *ip) { unsigned char *tmp = (unsigned char *)&num; - (void)sprintf(ip, (const char *)"%d.%d.%d.%d", tmp[0], tmp[1], tmp[2], tmp[3]); + sprintf(ip, "%d.%d.%d.%d", tmp[0], tmp[1], tmp[2], tmp[3]); } #define SOCKS_VERSION_SOCKS5 0x5 @@ -558,4 +649,4 @@ SOCKS5TCPActiveOpen(TCPiopb *pb, StreamPtr stream, ip_ fail: _TCPClose(pb, stream, nil, nil, false); return err; -} \ No newline at end of file +} --- tcp.h Fri Dec 2 16:06:56 2022 +++ tcp.h Fri Aug 30 09:56:02 2024 @@ -3,7 +3,7 @@ */ #include "MacTCP.h" -#include "AddressXlation.h" +#include "dnr.h" #ifndef __TCP_H__ #define __TCP_H__ @@ -15,7 +15,9 @@ typedef struct } HostInfoQ, *HostInfoQPtr, **HostInfoQHandle; typedef ProcPtr TCPNotifyProc; +typedef ProcPtr UDPNotifyProc; typedef void (*TCPIOCompletionProc)(struct TCPiopb *iopb); +typedef void (*UDPIOCompletionProc)(struct UDPiopb *iopb); OSErr _TCPInit(void); OSErr _TCPGetOurIP(ip_addr *ip, long *netMask); @@ -48,10 +50,20 @@ OSErr _TCPRelease(TCPiopb *pb, StreamPtr stream, Ptr u TCPIOCompletionProc ioCompletion, Boolean async); OSErr _UDPMaxMTUSize(UDPiopb *pb, short *mtu); +OSErr _UDPCreate(UDPiopb *pb, StreamPtr *stream, Ptr rcvBufPtr, + long rcvBufLen, UDPNotifyProc aNotifyProc, Ptr userDataPtr, + UDPIOCompletionProc ioCompletion, Boolean async); +OSErr _UDPSend(UDPiopb *pb, StreamPtr stream, wdsEntry *wdsPtr, + ip_addr remoteIP, udp_port remotePort, Ptr userData, + UDPIOCompletionProc ioCompletion, Boolean async); +OSErr _UDPRelease(UDPiopb *pb, StreamPtr stream, Ptr userData, + UDPIOCompletionProc ioCompletion, Boolean async); -OSErr TCPResolveName(char *name, unsigned long *ipAddress); +OSErr DNSResolveName(char *name, unsigned long *ipAddress, + void (*yielder)(void)); +pascal void StrToAddrMarkDone(struct hostInfo *hi, char *data); -long ip2long(char *ip); +unsigned long ip2long(char *ip); void long2ip(unsigned long num, char *ip); OSErr SOCKS5TCPActiveOpen(TCPiopb *pb, StreamPtr stream, ip_addr socks_ip,