1/*
2 *	A simple socket-like package.
3 *	This could undoubtedly be improved, since it does polling and busy-waiting.
4 *	At least it uses asynch I/O and implements timeouts!
5 *
6 *	Other funkiness includes the use of my own (possibly brain-damaged) error-handling infrastructure.
7 *
8 *	-Roy Wood (roy@centricsystems.ca)
9 *
10 */
11
12
13/* ====================================================================
14 * Copyright (c) 1998-1999 The OpenSSL Project.  All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 *
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 *
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in
25 *    the documentation and/or other materials provided with the
26 *    distribution.
27 *
28 * 3. All advertising materials mentioning features or use of this
29 *    software must display the following acknowledgment:
30 *    "This product includes software developed by the OpenSSL Project
31 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
32 *
33 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
34 *    endorse or promote products derived from this software without
35 *    prior written permission. For written permission, please contact
36 *    openssl-core@openssl.org.
37 *
38 * 5. Products derived from this software may not be called "OpenSSL"
39 *    nor may "OpenSSL" appear in their names without prior written
40 *    permission of the OpenSSL Project.
41 *
42 * 6. Redistributions of any form whatsoever must retain the following
43 *    acknowledgment:
44 *    "This product includes software developed by the OpenSSL Project
45 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
48 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
51 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
58 * OF THE POSSIBILITY OF SUCH DAMAGE.
59 * ====================================================================
60 *
61 * This product includes cryptographic software written by Eric Young
62 * (eay@cryptsoft.com).  This product includes software written by Tim
63 * Hudson (tjh@cryptsoft.com).
64 *
65 */
66
67
68
69
70
71#include "MacSocket.h"
72
73#include <Threads.h>
74
75#include <OpenTransport.h>
76#include <OpenTpTInternet.h>
77#include <OpenTptClient.h>
78
79
80
81#include "CPStringUtils.hpp"
82#include "ErrorHandling.hpp"
83
84
85//	#define MACSOCKET_DEBUG		1
86
87#ifdef MACSOCKET_DEBUG
88	#include <stdio.h>
89#endif
90
91
92
93extern int errno;
94
95
96#define kMaxNumSockets			4
97
98
99struct SocketStruct
100{
101	Boolean						mIsInUse;
102
103	Boolean						mEndpointIsBound;
104
105	Boolean						mLocalEndIsConnected;
106	Boolean						mRemoteEndIsConnected;
107
108	Boolean						mReceivedTOpenComplete;
109	Boolean						mReceivedTBindComplete;
110	Boolean						mReceivedTConnect;
111	Boolean						mReceivedTListen;
112	Boolean						mReceivedTPassCon;
113	Boolean						mReceivedTDisconnect;
114	Boolean						mReceivedTOrdRel;
115	Boolean						mReceivedTDisconnectComplete;
116
117	long						mTimeoutTicks;
118	long						mOperationStartTicks;
119
120	MacSocket_IdleWaitCallback	mIdleWaitCallback;
121	void						*mUserRefPtr;
122
123	OTEventCode					mExpectedCode;
124	OTResult					mAsyncOperationResult;
125
126	EndpointRef		 			mEndPointRef;
127	TBind						*mBindRequestedAddrInfo;
128	TBind						*mAssignedAddrInfo;
129	TCall						*mRemoteAddrInfo;
130
131	Boolean						mReadyToReadData;
132	Boolean						mReadyToWriteData;
133
134	Ptr							mReadBuffer;
135	Ptr							mWriteBuffer;
136
137	int							mLastError;
138	char						mErrMessage[256];
139};
140
141typedef struct SocketStruct	SocketStruct;
142
143
144static SocketStruct			sSockets[kMaxNumSockets];
145static Boolean				sSocketsSetup = false;
146
147
148
149
150static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag);
151
152static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie);
153
154static Boolean	SocketIndexIsValid(const int inSocketNum);
155
156static void InitSocket(SocketStruct *ioSocket);
157
158static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode);
159
160static Boolean TimeoutElapsed(const SocketStruct *inSocket);
161
162static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP);
163
164
165
166void MacSocket_GetSocketErrorInfo(const int inSocketNum,int *outSocketErrCode,char *outSocketErrString,const int inSocketErrStringMaxLength)
167{
168	if (outSocketErrCode != nil)
169	{
170		*outSocketErrCode = -1;
171	}
172
173	if (outSocketErrString != nil)
174	{
175		CopyCStrToCStr("",outSocketErrString,inSocketErrStringMaxLength);
176	}
177
178
179	if (SocketIndexIsValid(inSocketNum))
180	{
181	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
182
183
184		if (outSocketErrCode != nil)
185		{
186			*outSocketErrCode = theSocketStruct->mLastError;
187		}
188
189		if (outSocketErrString != nil)
190		{
191			CopyCStrToCStr(theSocketStruct->mErrMessage,outSocketErrString,inSocketErrStringMaxLength);
192		}
193	}
194}
195
196
197void MacSocket_SetUserRefPtr(const int inSocketNum,void *inNewRefPtr)
198{
199	if (SocketIndexIsValid(inSocketNum))
200	{
201	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
202
203		theSocketStruct->mUserRefPtr = inNewRefPtr;
204	}
205}
206
207
208
209void MacSocket_GetLocalIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
210{
211	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
212	{
213	char			tempString[256];
214	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
215
216
217		CopyCStrToCStr("",tempString,sizeof(tempString));
218
219		if (theSocketStruct->mAssignedAddrInfo != nil)
220		{
221		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mAssignedAddrInfo->addr.buf;
222		InetHost		theInetHost = theInetAddress->fHost;
223
224			if (theInetHost == 0)
225			{
226			InetInterfaceInfo	theInetInterfaceInfo;
227
228				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
229				{
230					theInetHost = theInetInterfaceInfo.fAddress;
231				}
232			}
233
234			::OTInetHostToString(theInetHost,tempString);
235
236			ConcatCStrToCStr(":",tempString,sizeof(tempString));
237			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
238		}
239
240		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
241	}
242}
243
244
245
246void MacSocket_GetRemoteIPAndPort(const int inSocketNum,char *outIPAndPort,const int inIPAndPortLength)
247{
248	if (outIPAndPort != nil && SocketIndexIsValid(inSocketNum))
249	{
250	char			tempString[256];
251	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
252
253
254		CopyCStrToCStr("",tempString,sizeof(tempString));
255
256		if (theSocketStruct->mRemoteAddrInfo != nil)
257		{
258		InetAddress		*theInetAddress = (InetAddress *) theSocketStruct->mRemoteAddrInfo->addr.buf;
259		InetHost		theInetHost = theInetAddress->fHost;
260
261			if (theInetHost == 0)
262			{
263			InetInterfaceInfo	theInetInterfaceInfo;
264
265				if (::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface) == noErr)
266				{
267					theInetHost = theInetInterfaceInfo.fAddress;
268				}
269			}
270
271			::OTInetHostToString(theInetHost,tempString);
272
273			ConcatCStrToCStr(":",tempString,sizeof(tempString));
274			ConcatLongIntToCStr(theInetAddress->fPort,tempString,sizeof(tempString));
275		}
276
277		CopyCStrToCStr(tempString,outIPAndPort,inIPAndPortLength);
278	}
279}
280
281
282
283Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum)
284{
285Boolean		theResult = false;
286
287	if (SocketIndexIsValid(inSocketNum))
288	{
289	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
290
291		theResult = theSocketStruct->mReceivedTOrdRel;
292	}
293
294	return(theResult);
295}
296
297
298
299Boolean MacSocket_ListenCompleted(const int inSocketNum)
300{
301Boolean		theResult = false;
302
303	if (SocketIndexIsValid(inSocketNum))
304	{
305	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
306
307		theResult = theSocketStruct->mReceivedTPassCon;
308	}
309
310	return(theResult);
311}
312
313
314
315Boolean MacSocket_RemoteEndIsOpen(const int inSocketNum)
316{
317	if (SocketIndexIsValid(inSocketNum))
318	{
319	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
320
321		return(theSocketStruct->mRemoteEndIsConnected);
322	}
323
324	else
325	{
326		return(false);
327	}
328}
329
330
331
332Boolean MacSocket_LocalEndIsOpen(const int inSocketNum)
333{
334	if (SocketIndexIsValid(inSocketNum))
335	{
336	SocketStruct	*theSocketStruct = &(sSockets[inSocketNum]);
337
338		return(theSocketStruct->mLocalEndIsConnected);
339	}
340
341	else
342	{
343		return(false);
344	}
345}
346
347
348
349static Boolean TimeoutElapsed(const SocketStruct *inSocket)
350{
351Boolean		timeIsUp = false;
352
353	if (inSocket != nil && inSocket->mTimeoutTicks > 0 && ::TickCount() > inSocket->mOperationStartTicks + inSocket->mTimeoutTicks)
354	{
355		timeIsUp = true;
356	}
357
358
359	return(timeIsUp);
360}
361
362
363
364static Boolean SocketIndexIsValid(const int inSocketNum)
365{
366	if (inSocketNum >= 0 && inSocketNum < kMaxNumSockets && sSockets[inSocketNum].mEndPointRef != kOTInvalidEndpointRef)
367	{
368		return(true);
369	}
370
371	else
372	{
373		return(false);
374	}
375}
376
377
378
379static void InitSocket(SocketStruct *ioSocket)
380{
381	ioSocket->mIsInUse = false;
382
383	ioSocket->mEndpointIsBound = false;
384
385	ioSocket->mLocalEndIsConnected = false;
386	ioSocket->mRemoteEndIsConnected = false;
387
388	ioSocket->mReceivedTOpenComplete = false;
389	ioSocket->mReceivedTBindComplete = false;
390	ioSocket->mReceivedTConnect = false;
391	ioSocket->mReceivedTListen = false;
392	ioSocket->mReceivedTPassCon = false;
393	ioSocket->mReceivedTDisconnect = false;
394	ioSocket->mReceivedTOrdRel = false;
395	ioSocket->mReceivedTDisconnectComplete = false;
396
397	ioSocket->mTimeoutTicks = 30 * 60;
398	ioSocket->mOperationStartTicks = -1;
399
400	ioSocket->mIdleWaitCallback = nil;
401	ioSocket->mUserRefPtr = nil;
402
403	ioSocket->mExpectedCode = 0;
404	ioSocket->mAsyncOperationResult = noErr;
405
406	ioSocket->mEndPointRef = kOTInvalidEndpointRef;
407
408	ioSocket->mBindRequestedAddrInfo = nil;
409	ioSocket->mAssignedAddrInfo = nil;
410	ioSocket->mRemoteAddrInfo = nil;
411
412	ioSocket->mReadyToReadData = false;
413	ioSocket->mReadyToWriteData = true;
414
415	ioSocket->mReadBuffer = nil;
416	ioSocket->mWriteBuffer = nil;
417
418	ioSocket->mLastError = noErr;
419	CopyCStrToCStr("",ioSocket->mErrMessage,sizeof(ioSocket->mErrMessage));
420}
421
422
423
424static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode)
425{
426	ioSocket->mOperationStartTicks = ::TickCount();
427
428	ioSocket->mAsyncOperationResult = noErr;
429
430	ioSocket->mExpectedCode = inExpectedCode;
431}
432
433
434//	The wait function....
435
436static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag)
437{
438OSErr 		errCode = noErr;
439OTResult	theOTResult = noErr;
440
441
442	SetErrorMessageAndBailIfNil(ioSocket,"MyBusyWait: Bad parameter, ioSocket = nil");
443	SetErrorMessageAndBailIfNil(inAsyncOperationCompleteFlag,"MyBusyWait: Bad parameter, inAsyncOperationCompleteFlag = nil");
444
445	for (;;)
446	{
447		if (*inAsyncOperationCompleteFlag)
448		{
449			theOTResult = ioSocket->mAsyncOperationResult;
450
451			break;
452		}
453
454		if (ioSocket->mIdleWaitCallback != nil)
455		{
456			theOTResult = (*(ioSocket->mIdleWaitCallback))(ioSocket->mUserRefPtr);
457
458			if (theOTResult != noErr && returnImmediatelyOnError)
459			{
460				break;
461			}
462		}
463
464		if (TimeoutElapsed(ioSocket))
465		{
466			theOTResult = kMacSocket_TimeoutErr;
467
468			break;
469		}
470	}
471
472
473EXITPOINT:
474
475	if (outOTResult != nil)
476	{
477		*outOTResult = theOTResult;
478	}
479
480	return(errCode);
481}
482
483
484
485//	I used to do thread switching, but stopped.  It could easily be rolled back in though....
486
487static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie)
488{
489SocketStruct *theSocketStruct = (SocketStruct *) contextPtr;
490
491	if (theSocketStruct != nil)
492	{
493		if (theSocketStruct->mExpectedCode != 0 && code == theSocketStruct->mExpectedCode)
494		{
495			theSocketStruct->mAsyncOperationResult = result;
496
497			theSocketStruct->mExpectedCode = 0;
498		}
499
500
501		switch (code)
502		{
503			case T_OPENCOMPLETE:
504			{
505				theSocketStruct->mReceivedTOpenComplete = true;
506
507				theSocketStruct->mEndPointRef = (EndpointRef) cookie;
508
509				break;
510			}
511
512
513			case T_BINDCOMPLETE:
514			{
515				theSocketStruct->mReceivedTBindComplete = true;
516
517				break;
518			}
519
520
521			case T_CONNECT:
522			{
523				theSocketStruct->mReceivedTConnect = true;
524
525				theSocketStruct->mLocalEndIsConnected = true;
526
527				theSocketStruct->mRemoteEndIsConnected = true;
528
529				break;
530			}
531
532
533			case T_LISTEN:
534			{
535				theSocketStruct->mReceivedTListen = true;
536
537				break;
538			}
539
540
541			case T_PASSCON:
542			{
543				theSocketStruct->mReceivedTPassCon = true;
544
545				theSocketStruct->mLocalEndIsConnected = true;
546
547				theSocketStruct->mRemoteEndIsConnected = true;
548
549				break;
550			}
551
552
553			case T_DATA:
554			{
555				theSocketStruct->mReadyToReadData = true;
556
557				break;
558			}
559
560			case T_GODATA:
561			{
562				theSocketStruct->mReadyToWriteData = true;
563
564				break;
565			}
566
567			case T_DISCONNECT:
568			{
569				theSocketStruct->mReceivedTDisconnect = true;
570
571				theSocketStruct->mRemoteEndIsConnected = false;
572
573				theSocketStruct->mLocalEndIsConnected = false;
574
575				::OTRcvDisconnect(theSocketStruct->mEndPointRef,nil);
576
577				break;
578			}
579
580			case T_ORDREL:
581			{
582				theSocketStruct->mReceivedTOrdRel = true;
583
584				//	We can still write data, so don't clear mRemoteEndIsConnected
585
586				::OTRcvOrderlyDisconnect(theSocketStruct->mEndPointRef);
587
588				break;
589			}
590
591			case T_DISCONNECTCOMPLETE:
592			{
593				theSocketStruct->mReceivedTDisconnectComplete = true;
594
595				theSocketStruct->mRemoteEndIsConnected = false;
596
597				theSocketStruct->mLocalEndIsConnected = false;
598
599				break;
600			}
601		}
602	}
603/*
604T_LISTEN OTListen
605T_CONNECT OTRcvConnect
606T_DATA OTRcv, OTRcvUData
607T_DISCONNECT OTRcvDisconnect
608T_ORDREL OTRcvOrderlyDisconnect
609T_GODATA OTSnd, OTSndUData, OTLook
610T_PASSCON none
611
612T_EXDATA OTRcv
613T_GOEXDATA OTSnd, OTLook
614T_UDERR OTRcvUDErr
615*/
616}
617
618
619
620//	Initialize the main socket data structure
621
622OSErr MacSocket_Startup(void)
623{
624	if (!sSocketsSetup)
625	{
626		for (int i = 0;i < kMaxNumSockets;i++)
627		{
628			InitSocket(&(sSockets[i]));
629		}
630
631		::InitOpenTransport();
632
633		sSocketsSetup = true;
634	}
635
636
637	return(noErr);
638}
639
640
641
642//	Cleanup before exiting
643
644OSErr MacSocket_Shutdown(void)
645{
646	if (sSocketsSetup)
647	{
648		for (int i = 0;i < kMaxNumSockets;i++)
649		{
650		SocketStruct *theSocketStruct = &(sSockets[i]);
651
652			if (theSocketStruct->mIsInUse)
653			{
654				if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
655				{
656				OTResult	theOTResult;
657
658
659					//	Since we're killing the endpoint, I don't bother to send the disconnect (sorry!)
660
661/*
662					if (theSocketStruct->mLocalEndIsConnected)
663					{
664						//	This is an abortive action, so we do a hard disconnect instead of an OTSndOrderlyDisconnect
665
666						theOTResult = ::OTSndDisconnect(theSocketStruct->mEndPointRef, nil);
667
668						//	Now we have to watch for T_DISCONNECTCOMPLETE event
669
670						theSocketStruct->mLocalEndIsConnected = false;
671					}
672*/
673
674					theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
675
676
677					theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
678				}
679
680				if (theSocketStruct->mBindRequestedAddrInfo != nil)
681				{
682					::OTFree((void *) theSocketStruct->mBindRequestedAddrInfo,T_BIND);
683
684					theSocketStruct->mBindRequestedAddrInfo = nil;
685				}
686
687				if (theSocketStruct->mAssignedAddrInfo != nil)
688				{
689					::OTFree((void *) theSocketStruct->mAssignedAddrInfo,T_BIND);
690
691					theSocketStruct->mAssignedAddrInfo = nil;
692				}
693
694				if (theSocketStruct->mRemoteAddrInfo != nil)
695				{
696					::OTFree((void *) theSocketStruct->mRemoteAddrInfo,T_CALL);
697
698					theSocketStruct->mRemoteAddrInfo = nil;
699				}
700
701
702			}
703		}
704
705		::CloseOpenTransport();
706
707		sSocketsSetup = false;
708	}
709
710	return(noErr);
711}
712
713
714
715
716
717
718//	Allocate a socket
719
720OSErr MacSocket_socket(int *outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void *inUserRefPtr)
721{
722//	Gotta roll support back in for threads eventually.....
723
724#pragma unused(inDoThreadSwitching)
725
726
727OSErr	errCode = noErr;
728
729
730	SetErrorMessageAndBailIfNil(outSocketNum,"MacSocket_socket: Bad parameter, outSocketNum == nil");
731
732	*outSocketNum = -1;
733
734
735	//	Find an unused socket
736
737	for (int i = 0;i < kMaxNumSockets;i++)
738	{
739		if (sSockets[i].mIsInUse == false)
740		{
741		OTResult		theOTResult;
742		SocketStruct	*theSocketStruct = &(sSockets[i]);
743
744
745			InitSocket(theSocketStruct);
746
747			theSocketStruct->mIdleWaitCallback = inIdleWaitCallback;
748			theSocketStruct->mUserRefPtr = inUserRefPtr;
749
750			theSocketStruct->mTimeoutTicks = inTimeoutTicks;
751
752
753			//	Set up OT endpoint
754
755			PrepareForAsyncOperation(theSocketStruct,T_OPENCOMPLETE);
756
757			theOTResult = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),0,nil,OTNonYieldingNotifier,(void *) theSocketStruct);
758
759			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
760
761			BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOpenComplete)));
762
763			SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_socket: Can't create OT endpoint, OTAsyncOpenEndpoint() = ",theOTResult);
764
765
766			*outSocketNum = i;
767
768			errCode = noErr;
769
770			theSocketStruct->mIsInUse = true;
771
772			break;
773		}
774
775		else if (i == kMaxNumSockets - 1)
776		{
777			SetErrorMessageAndBail("MacSocket_socket: No sockets available");
778		}
779	}
780
781
782EXITPOINT:
783
784	errno = errCode;
785
786	return(errCode);
787}
788
789
790
791
792OSErr MacSocket_listen(const int inSocketNum,const int inPortNum)
793{
794OSErr			errCode = noErr;
795SocketStruct	*theSocketStruct = nil;
796
797
798	if (!SocketIndexIsValid(inSocketNum))
799	{
800		SetErrorMessageAndBail("MacSocket_listen: Invalid socket number specified");
801	}
802
803
804	theSocketStruct = &(sSockets[inSocketNum]);
805
806
807OTResult		theOTResult;
808
809
810	if (theSocketStruct->mBindRequestedAddrInfo == nil)
811	{
812		theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
813
814		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
815		SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
816	}
817
818	if (theSocketStruct->mAssignedAddrInfo == nil)
819	{
820		theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
821
822		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
823		SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_listen: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
824	}
825
826	if (theSocketStruct->mRemoteAddrInfo == nil)
827	{
828		theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
829
830		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
831		SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_listen: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
832	}
833
834
835	if (!theSocketStruct->mEndpointIsBound)
836	{
837	InetInterfaceInfo	theInetInterfaceInfo;
838
839		theOTResult = ::OTInetGetInterfaceInfo(&theInetInterfaceInfo,kDefaultInetInterface);
840
841		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't determine OT interface info, OTInetGetInterfaceInfo() = ",theOTResult);
842
843
844	InetAddress	*theInetAddress = (InetAddress *) theSocketStruct->mBindRequestedAddrInfo->addr.buf;
845
846//		theInetAddress->fAddressType = AF_INET;
847//		theInetAddress->fPort = inPortNum;
848//		theInetAddress->fHost = theInetInterfaceInfo.fAddress;
849
850		::OTInitInetAddress(theInetAddress,inPortNum,theInetInterfaceInfo.fAddress);
851
852		theSocketStruct->mBindRequestedAddrInfo->addr.len = sizeof(InetAddress);
853
854		theSocketStruct->mBindRequestedAddrInfo->qlen = 1;
855
856
857		theOTResult = ::OTSetSynchronous(theSocketStruct->mEndPointRef);
858
859		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetSynchronous() = ",theOTResult);
860
861		theOTResult = NegotiateIPReuseAddrOption(theSocketStruct->mEndPointRef,true);
862
863		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT IP address reuse flag, NegotiateIPReuseAddrOption() = ",theOTResult);
864
865		theOTResult = ::OTSetAsynchronous(theSocketStruct->mEndPointRef);
866
867		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't set OT endpoint mode, OTSetAsynchronous() = ",theOTResult);
868
869
870		PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
871
872		theOTResult = ::OTBind(theSocketStruct->mEndPointRef,theSocketStruct->mBindRequestedAddrInfo,theSocketStruct->mAssignedAddrInfo);
873
874		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
875
876		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
877
878		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't bind OT endpoint, OTBind() = ",theOTResult);
879
880
881		theSocketStruct->mEndpointIsBound = true;
882	}
883
884
885	PrepareForAsyncOperation(theSocketStruct,T_LISTEN);
886
887	theOTResult = ::OTListen(theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
888
889	if (theOTResult == noErr)
890	{
891		PrepareForAsyncOperation(theSocketStruct,T_PASSCON);
892
893		theOTResult = ::OTAccept(theSocketStruct->mEndPointRef,theSocketStruct->mEndPointRef,theSocketStruct->mRemoteAddrInfo);
894
895		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't begin OT accept, OTAccept() = ",theOTResult);
896
897		BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTPassCon)));
898
899		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_listen: Can't accept OT connection, OTAccept() = ",theOTResult);
900	}
901
902	else if (theOTResult == kOTNoDataErr)
903	{
904		theOTResult = noErr;
905	}
906
907	else
908	{
909		SetErrorMessageAndLongIntAndBail("MacSocket_listen: Can't begin OT listen, OTListen() = ",theOTResult);
910	}
911
912
913	errCode = noErr;
914
915
916EXITPOINT:
917
918	if (theSocketStruct != nil)
919	{
920		theSocketStruct->mLastError = noErr;
921
922		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
923
924		if (errCode != noErr)
925		{
926			theSocketStruct->mLastError = errCode;
927
928			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
929		}
930	}
931
932	errno = errCode;
933
934	return(errCode);
935}
936
937
938
939
940OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort)
941{
942OSErr			errCode = noErr;
943SocketStruct	*theSocketStruct = nil;
944
945
946	if (!SocketIndexIsValid(inSocketNum))
947	{
948		SetErrorMessageAndBail("MacSocket_connect: Invalid socket number specified");
949	}
950
951	theSocketStruct = &(sSockets[inSocketNum]);
952
953	if (theSocketStruct->mEndpointIsBound)
954	{
955		SetErrorMessageAndBail("MacSocket_connect: Socket previously bound");
956	}
957
958
959OTResult		theOTResult;
960
961	theSocketStruct->mBindRequestedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
962
963	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
964	SetErrorMessageAndBailIfNil(theSocketStruct->mBindRequestedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
965
966
967	theSocketStruct->mAssignedAddrInfo = (TBind *) ::OTAlloc(theSocketStruct->mEndPointRef,T_BIND,T_ADDR,&theOTResult);
968
969	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() = ",theOTResult);
970	SetErrorMessageAndBailIfNil(theSocketStruct->mAssignedAddrInfo,"MacSocket_connect: Can't allocate OT T_BIND structure, OTAlloc() returned nil");
971
972
973	theSocketStruct->mRemoteAddrInfo = (TCall *) ::OTAlloc(theSocketStruct->mEndPointRef,T_CALL,T_ADDR,&theOTResult);
974
975	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() = ",theOTResult);
976	SetErrorMessageAndBailIfNil(theSocketStruct->mRemoteAddrInfo,"MacSocket_connect: Can't allocate OT T_CALL structure, OTAlloc() returned nil");
977
978
979	PrepareForAsyncOperation(theSocketStruct,T_BINDCOMPLETE);
980
981	theOTResult = ::OTBind(theSocketStruct->mEndPointRef,nil,theSocketStruct->mAssignedAddrInfo);
982
983	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
984
985	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTBindComplete)));
986
987	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't bind OT endpoint, OTBind() = ",theOTResult);
988
989	theSocketStruct->mEndpointIsBound = true;
990
991
992TCall		sndCall;
993DNSAddress 	hostDNSAddress;
994
995	//	Set up target address
996
997	sndCall.addr.buf = (UInt8 *) &hostDNSAddress;
998	sndCall.addr.len = ::OTInitDNSAddress(&hostDNSAddress,inTargetAddressAndPort);
999	sndCall.opt.buf = nil;
1000	sndCall.opt.len = 0;
1001	sndCall.udata.buf = nil;
1002	sndCall.udata.len = 0;
1003	sndCall.sequence = 0;
1004
1005	//	Connect!
1006
1007	PrepareForAsyncOperation(theSocketStruct,T_CONNECT);
1008
1009	theOTResult = ::OTConnect(theSocketStruct->mEndPointRef,&sndCall,nil);
1010
1011	if (theOTResult == kOTNoDataErr)
1012	{
1013		theOTResult = noErr;
1014	}
1015
1016	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
1017
1018	BailIfError(MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTConnect)));
1019
1020	if (theOTResult == kMacSocket_TimeoutErr)
1021	{
1022		SetErrorMessageAndBail("MacSocket_connect: Can't connect OT endpoint, OTConnect() = kMacSocket_TimeoutErr");
1023	}
1024
1025	else
1026	{
1027		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't connect OT endpoint, OTConnect() = ",theOTResult);
1028	}
1029
1030	theOTResult = ::OTRcvConnect(theSocketStruct->mEndPointRef,nil);
1031
1032	SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_connect: Can't complete connect on OT endpoint, OTRcvConnect() = ",theOTResult);
1033
1034
1035	errCode = noErr;
1036
1037
1038#ifdef MACSOCKET_DEBUG
1039	printf("MacSocket_connect: connect completed\n");
1040#endif
1041
1042EXITPOINT:
1043
1044	if (theSocketStruct != nil)
1045	{
1046		theSocketStruct->mLastError = noErr;
1047
1048		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1049
1050		if (errCode != noErr)
1051		{
1052			theSocketStruct->mLastError = errCode;
1053
1054			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1055		}
1056	}
1057
1058	errno = errCode;
1059
1060	return(errCode);
1061}
1062
1063
1064
1065
1066//	Close a connection
1067
1068OSErr MacSocket_close(const int inSocketNum)
1069{
1070OSErr			errCode = noErr;
1071SocketStruct	*theSocketStruct = nil;
1072
1073
1074	if (!SocketIndexIsValid(inSocketNum))
1075	{
1076		SetErrorMessageAndBail("MacSocket_close: Invalid socket number specified");
1077	}
1078
1079
1080	theSocketStruct = &(sSockets[inSocketNum]);
1081
1082	if (theSocketStruct->mEndPointRef != kOTInvalidEndpointRef)
1083	{
1084	OTResult		theOTResult = noErr;
1085
1086		//	Try to play nice
1087
1088		if (theSocketStruct->mReceivedTOrdRel)
1089		{
1090			//	Already did an OTRcvOrderlyDisconnect() in the notifier
1091
1092			if (theSocketStruct->mLocalEndIsConnected)
1093			{
1094				theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
1095
1096				theSocketStruct->mLocalEndIsConnected = false;
1097			}
1098		}
1099
1100		else if (theSocketStruct->mLocalEndIsConnected)
1101		{
1102			theOTResult = ::OTSndOrderlyDisconnect(theSocketStruct->mEndPointRef);
1103
1104			theSocketStruct->mLocalEndIsConnected = false;
1105
1106			//	Wait for other end to hang up too!
1107
1108//			PrepareForAsyncOperation(theSocketStruct,T_ORDREL);
1109//
1110//			errCode = MyBusyWait(theSocketStruct,false,&theOTResult,&(theSocketStruct->mReceivedTOrdRel));
1111		}
1112
1113
1114		if (theOTResult != noErr)
1115		{
1116			::OTCloseProvider(theSocketStruct->mEndPointRef);
1117		}
1118
1119		else
1120		{
1121			theOTResult = ::OTCloseProvider(theSocketStruct->mEndPointRef);
1122		}
1123
1124		theSocketStruct->mEndPointRef = kOTInvalidEndpointRef;
1125
1126		errCode = theOTResult;
1127	}
1128
1129
1130	theSocketStruct->mIsInUse = false;
1131
1132
1133EXITPOINT:
1134
1135	if (theSocketStruct != nil)
1136	{
1137		theSocketStruct->mLastError = noErr;
1138
1139		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1140
1141		if (errCode != noErr)
1142		{
1143			theSocketStruct->mLastError = errCode;
1144
1145			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1146		}
1147	}
1148
1149	errno = errCode;
1150
1151	return(errCode);
1152}
1153
1154
1155
1156
1157//	Receive some bytes
1158
1159int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock)
1160{
1161OSErr			errCode = noErr;
1162int				totalBytesRead = 0;
1163SocketStruct	*theSocketStruct = nil;
1164
1165
1166	SetErrorMessageAndBailIfNil(outBuff,"MacSocket_recv: Bad parameter, outBuff = nil");
1167
1168	if (outBuffLength <= 0)
1169	{
1170		SetErrorMessageAndBail("MacSocket_recv: Bad parameter, outBuffLength <= 0");
1171	}
1172
1173	if (!SocketIndexIsValid(inSocketNum))
1174	{
1175		SetErrorMessageAndBail("MacSocket_recv: Invalid socket number specified");
1176	}
1177
1178	theSocketStruct = &(sSockets[inSocketNum]);
1179
1180	if (!theSocketStruct->mLocalEndIsConnected)
1181	{
1182		SetErrorMessageAndBail("MacSocket_recv: Socket not connected");
1183	}
1184
1185	if (theSocketStruct->mReceivedTOrdRel)
1186	{
1187		totalBytesRead = 0;
1188
1189		goto EXITPOINT;
1190	}
1191
1192
1193	PrepareForAsyncOperation(theSocketStruct,0);
1194
1195	for (;;)
1196	{
1197	int			bytesRead;
1198	OTResult	theOTResult;
1199
1200
1201		theOTResult = ::OTRcv(theSocketStruct->mEndPointRef,(void *) ((unsigned long) outBuff + (unsigned long) totalBytesRead),outBuffLength - totalBytesRead,nil);
1202
1203		if (theOTResult >= 0)
1204		{
1205			bytesRead = theOTResult;
1206
1207#ifdef MACSOCKET_DEBUG
1208	printf("MacSocket_recv: read %d bytes in part\n",bytesRead);
1209#endif
1210		}
1211
1212		else if (theOTResult == kOTNoDataErr)
1213		{
1214			bytesRead = 0;
1215		}
1216
1217		else
1218		{
1219			SetErrorMessageAndLongIntAndBail("MacSocket_recv: Can't receive OT data, OTRcv() = ",theOTResult);
1220		}
1221
1222
1223		totalBytesRead += bytesRead;
1224
1225
1226		if (totalBytesRead <= 0)
1227		{
1228			if (theSocketStruct->mReceivedTOrdRel)
1229			{
1230				break;
1231			}
1232
1233			//	This seems pretty stupid to me now.  Maybe I'll delete this blocking garbage.
1234
1235			if (inBlock)
1236			{
1237				if (TimeoutElapsed(theSocketStruct))
1238				{
1239					SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_recv: Receive operation timed-out");
1240				}
1241
1242				if (theSocketStruct->mIdleWaitCallback != nil)
1243				{
1244					theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
1245
1246					SetErrorMessageAndBailIfError(theOTResult,"MacSocket_recv: User cancelled operation");
1247				}
1248
1249				continue;
1250			}
1251		}
1252
1253
1254		break;
1255	}
1256
1257	errCode = noErr;
1258
1259
1260#ifdef MACSOCKET_DEBUG
1261	printf("MacSocket_recv: read %d bytes in total\n",totalBytesRead);
1262#endif
1263
1264
1265EXITPOINT:
1266
1267	if (theSocketStruct != nil)
1268	{
1269		theSocketStruct->mLastError = noErr;
1270
1271		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1272
1273		if (errCode != noErr)
1274		{
1275			theSocketStruct->mLastError = errCode;
1276
1277			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1278		}
1279	}
1280
1281	errno = errCode;
1282
1283	return(totalBytesRead);
1284}
1285
1286
1287
1288//	Send some bytes
1289
1290int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength)
1291{
1292OSErr			errCode = noErr;
1293int				bytesSent = 0;
1294SocketStruct	*theSocketStruct = nil;
1295
1296
1297	SetErrorMessageAndBailIfNil(inBuff,"MacSocket_send: Bad parameter, inBuff = nil");
1298
1299	if (inBuffLength <= 0)
1300	{
1301		SetErrorMessageAndBail("MacSocket_send: Bad parameter, inBuffLength <= 0");
1302	}
1303
1304	if (!SocketIndexIsValid(inSocketNum))
1305	{
1306		SetErrorMessageAndBail("MacSocket_send: Invalid socket number specified");
1307	}
1308
1309
1310	theSocketStruct = &(sSockets[inSocketNum]);
1311
1312	if (!theSocketStruct->mLocalEndIsConnected)
1313	{
1314		SetErrorMessageAndBail("MacSocket_send: Socket not connected");
1315	}
1316
1317
1318OTResult		theOTResult;
1319
1320
1321	PrepareForAsyncOperation(theSocketStruct,0);
1322
1323	while (bytesSent < inBuffLength)
1324	{
1325		if (theSocketStruct->mIdleWaitCallback != nil)
1326		{
1327			theOTResult = (*(theSocketStruct->mIdleWaitCallback))(theSocketStruct->mUserRefPtr);
1328
1329			SetErrorMessageAndBailIfError(theOTResult,"MacSocket_send: User cancelled");
1330		}
1331
1332
1333		theOTResult = ::OTSnd(theSocketStruct->mEndPointRef,(void *) ((unsigned long) inBuff + bytesSent),inBuffLength - bytesSent,0);
1334
1335		if (theOTResult >= 0)
1336		{
1337			bytesSent += theOTResult;
1338
1339			theOTResult = noErr;
1340
1341			//	Reset timer....
1342
1343			PrepareForAsyncOperation(theSocketStruct,0);
1344		}
1345
1346		if (theOTResult == kOTFlowErr)
1347		{
1348			if (TimeoutElapsed(theSocketStruct))
1349			{
1350				SetErrorCodeAndMessageAndBail(kMacSocket_TimeoutErr,"MacSocket_send: Send timed-out")
1351			}
1352
1353			theOTResult = noErr;
1354		}
1355
1356		SetErrorMessageAndLongIntAndBailIfError(theOTResult,"MacSocket_send: Can't send OT data, OTSnd() = ",theOTResult);
1357	}
1358
1359
1360	errCode = noErr;
1361
1362#ifdef MACSOCKET_DEBUG
1363	printf("MacSocket_send: sent %d bytes\n",bytesSent);
1364#endif
1365
1366
1367EXITPOINT:
1368
1369	if (theSocketStruct != nil)
1370	{
1371		theSocketStruct->mLastError = noErr;
1372
1373		CopyCStrToCStr("",theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1374
1375		if (errCode != noErr)
1376		{
1377			theSocketStruct->mLastError = errCode;
1378
1379			CopyCStrToCStr(GetErrorMessage(),theSocketStruct->mErrMessage,sizeof(theSocketStruct->mErrMessage));
1380		}
1381	}
1382
1383	if (errCode != noErr)
1384	{
1385		::SysBeep(1);
1386	}
1387
1388	errno = errCode;
1389
1390	return(bytesSent);
1391}
1392
1393
1394
1395
1396
1397static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)
1398{
1399OSStatus	errCode;
1400UInt8		buf[kOTFourByteOptionSize];
1401TOption*	theOTOption;
1402TOptMgmt	theOTRequest;
1403TOptMgmt	theOTResult;
1404
1405
1406	if (!OTIsSynchronous(inEndpoint))
1407	{
1408		SetErrorMessageAndBail("NegotiateIPReuseAddrOption: Open Transport endpoint is not synchronous");
1409	}
1410
1411	theOTRequest.opt.buf = buf;
1412	theOTRequest.opt.len = sizeof(buf);
1413	theOTRequest.flags = T_NEGOTIATE;
1414
1415	theOTResult.opt.buf = buf;
1416	theOTResult.opt.maxlen = kOTFourByteOptionSize;
1417
1418
1419	theOTOption = (TOption *) buf;
1420
1421	theOTOption->level = INET_IP;
1422	theOTOption->name = IP_REUSEADDR;
1423	theOTOption->len = kOTFourByteOptionSize;
1424	theOTOption->status = 0;
1425	*((UInt32 *) (theOTOption->value)) = inEnableReuseIP;
1426
1427	errCode = ::OTOptionManagement(inEndpoint,&theOTRequest,&theOTResult);
1428
1429	if (errCode == kOTNoError)
1430	{
1431		if (theOTOption->status != T_SUCCESS)
1432		{
1433			errCode = theOTOption->status;
1434		}
1435
1436		else
1437		{
1438			errCode = kOTNoError;
1439		}
1440	}
1441
1442
1443EXITPOINT:
1444
1445	errno = errCode;
1446
1447	return(errCode);
1448}
1449
1450
1451
1452
1453
1454//	Some rough notes....
1455
1456
1457
1458//	OTAckSends(ep);
1459//	OTAckSends(ep) // enable AckSend option
1460//	......
1461//	buf = OTAllocMem( nbytes); // Allocate nbytes of memory from OT
1462//	OTSnd(ep, buf, nbytes, 0); // send a packet
1463//	......
1464//	NotifyProc( .... void* theParam) // Notifier Proc
1465//	case T_MEMORYRELEASED: // process event
1466//	OTFreeMem( theParam); // free up memory
1467//	break;
1468
1469
1470
1471/*
1472struct InetInterfaceInfo
1473{
1474	InetHost		fAddress;
1475	InetHost		fNetmask;
1476	InetHost		fBroadcastAddr;
1477	InetHost		fDefaultGatewayAddr;
1478	InetHost		fDNSAddr;
1479	UInt16			fVersion;
1480	UInt16			fHWAddrLen;
1481	UInt8*			fHWAddr;
1482	UInt32			fIfMTU;
1483	UInt8*			fReservedPtrs[2];
1484	InetDomainName	fDomainName;
1485	UInt32			fIPSecondaryCount;
1486	UInt8			fReserved[252];
1487};
1488typedef struct InetInterfaceInfo InetInterfaceInfo;
1489
1490
1491
1492((InetAddress *) addr.buf)->fHost
1493
1494struct TBind
1495{
1496	TNetbuf	addr;
1497	OTQLen	qlen;
1498};
1499
1500typedef struct TBind	TBind;
1501
1502struct TNetbuf
1503{
1504	size_t	maxlen;
1505	size_t	len;
1506	UInt8*	buf;
1507};
1508
1509typedef struct TNetbuf	TNetbuf;
1510
1511
1512	struct InetAddress
1513{
1514		OTAddressType	fAddressType;	// always AF_INET
1515		InetPort		fPort;			// Port number
1516		InetHost		fHost;			// Host address in net byte order
1517		UInt8			fUnused[8];		// Traditional unused bytes
1518};
1519typedef struct InetAddress InetAddress;
1520*/
1521
1522
1523
1524/*
1525static pascal void Notifier(void* context, OTEventCode event, OTResult result, void* cookie)
1526{
1527EPInfo* epi = (EPInfo*) context;
1528
1529	switch (event)
1530	{
1531		case T_LISTEN:
1532		{
1533			DoListenAccept();
1534			return;
1535		}
1536
1537		case T_ACCEPTCOMPLETE:
1538		{
1539			if (result != kOTNoError)
1540				DBAlert1("Notifier: T_ACCEPTCOMPLETE - result %d",result);
1541			return;
1542		}
1543
1544		case T_PASSCON:
1545		{
1546			if (result != kOTNoError)
1547			{
1548				DBAlert1("Notifier: T_PASSCON result %d", result);
1549				return;
1550			}
1551
1552			OTAtomicAdd32(1, &gCntrConnections);
1553			OTAtomicAdd32(1, &gCntrTotalConnections);
1554			OTAtomicAdd32(1, &gCntrIntervalConnects);
1555
1556			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
1557			{
1558				ReadData(epi);
1559			}
1560
1561			return;
1562		}
1563
1564		case T_DATA:
1565		{
1566			if ( OTAtomicSetBit(&epi->stateFlags, kPassconBit) != 0 )
1567			{
1568				ReadData(epi);
1569			}
1570
1571			return;
1572		}
1573
1574		case T_GODATA:
1575		{
1576			SendData(epi);
1577			return;
1578		}
1579
1580		case T_DISCONNECT:
1581		{
1582			DoRcvDisconnect(epi);
1583			return;
1584		}
1585
1586		case T_DISCONNECTCOMPLETE:
1587		{
1588			if (result != kOTNoError)
1589				DBAlert1("Notifier: T_DISCONNECT_COMPLETE result %d",result);
1590
1591			return;
1592		}
1593
1594		case T_MEMORYRELEASED:
1595		{
1596			OTAtomicAdd32(-1, &epi->outstandingSends);
1597			return;
1598		}
1599
1600		default:
1601		{
1602			DBAlert1("Notifier: unknown event <%x>", event);
1603			return;
1604		}
1605	}
1606}
1607*/
1608