xref: /minix3/crypto/external/bsd/openssl/dist/MacOS/GetHTTPS.src/MacSocket.cpp (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
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 
93 extern int errno;
94 
95 
96 #define kMaxNumSockets			4
97 
98 
99 struct 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 
141 typedef struct SocketStruct	SocketStruct;
142 
143 
144 static SocketStruct			sSockets[kMaxNumSockets];
145 static Boolean				sSocketsSetup = false;
146 
147 
148 
149 
150 static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag);
151 
152 static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie);
153 
154 static Boolean	SocketIndexIsValid(const int inSocketNum);
155 
156 static void InitSocket(SocketStruct *ioSocket);
157 
158 static void PrepareForAsyncOperation(SocketStruct *ioSocket,const OTEventCode inExpectedCode);
159 
160 static Boolean TimeoutElapsed(const SocketStruct *inSocket);
161 
162 static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP);
163 
164 
165 
MacSocket_GetSocketErrorInfo(const int inSocketNum,int * outSocketErrCode,char * outSocketErrString,const int inSocketErrStringMaxLength)166 void 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 
MacSocket_SetUserRefPtr(const int inSocketNum,void * inNewRefPtr)197 void 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 
MacSocket_GetLocalIPAndPort(const int inSocketNum,char * outIPAndPort,const int inIPAndPortLength)209 void 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 
MacSocket_GetRemoteIPAndPort(const int inSocketNum,char * outIPAndPort,const int inIPAndPortLength)246 void 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 
MacSocket_RemoteEndIsClosing(const int inSocketNum)283 Boolean MacSocket_RemoteEndIsClosing(const int inSocketNum)
284 {
285 Boolean		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 
MacSocket_ListenCompleted(const int inSocketNum)299 Boolean MacSocket_ListenCompleted(const int inSocketNum)
300 {
301 Boolean		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 
MacSocket_RemoteEndIsOpen(const int inSocketNum)315 Boolean 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 
MacSocket_LocalEndIsOpen(const int inSocketNum)332 Boolean 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 
TimeoutElapsed(const SocketStruct * inSocket)349 static Boolean TimeoutElapsed(const SocketStruct *inSocket)
350 {
351 Boolean		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 
SocketIndexIsValid(const int inSocketNum)364 static 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 
InitSocket(SocketStruct * ioSocket)379 static 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 
PrepareForAsyncOperation(SocketStruct * ioSocket,const OTEventCode inExpectedCode)424 static 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 
MyBusyWait(SocketStruct * ioSocket,Boolean returnImmediatelyOnError,OTResult * outOTResult,Boolean * inAsyncOperationCompleteFlag)436 static OSErr MyBusyWait(SocketStruct *ioSocket,Boolean returnImmediatelyOnError,OTResult *outOTResult,Boolean *inAsyncOperationCompleteFlag)
437 {
438 OSErr 		errCode = noErr;
439 OTResult	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 
473 EXITPOINT:
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 
OTNonYieldingNotifier(void * contextPtr,OTEventCode code,OTResult result,void * cookie)487 static pascal void OTNonYieldingNotifier(void *contextPtr,OTEventCode code,OTResult result,void *cookie)
488 {
489 SocketStruct *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 /*
604 T_LISTEN OTListen
605 T_CONNECT OTRcvConnect
606 T_DATA OTRcv, OTRcvUData
607 T_DISCONNECT OTRcvDisconnect
608 T_ORDREL OTRcvOrderlyDisconnect
609 T_GODATA OTSnd, OTSndUData, OTLook
610 T_PASSCON none
611 
612 T_EXDATA OTRcv
613 T_GOEXDATA OTSnd, OTLook
614 T_UDERR OTRcvUDErr
615 */
616 }
617 
618 
619 
620 //	Initialize the main socket data structure
621 
MacSocket_Startup(void)622 OSErr 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 
MacSocket_Shutdown(void)644 OSErr 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 
MacSocket_socket(int * outSocketNum,const Boolean inDoThreadSwitching,const long inTimeoutTicks,MacSocket_IdleWaitCallback inIdleWaitCallback,void * inUserRefPtr)720 OSErr 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 
727 OSErr	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 
782 EXITPOINT:
783 
784 	errno = errCode;
785 
786 	return(errCode);
787 }
788 
789 
790 
791 
MacSocket_listen(const int inSocketNum,const int inPortNum)792 OSErr MacSocket_listen(const int inSocketNum,const int inPortNum)
793 {
794 OSErr			errCode = noErr;
795 SocketStruct	*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 
807 OTResult		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 
916 EXITPOINT:
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 
MacSocket_connect(const int inSocketNum,char * inTargetAddressAndPort)940 OSErr MacSocket_connect(const int inSocketNum,char *inTargetAddressAndPort)
941 {
942 OSErr			errCode = noErr;
943 SocketStruct	*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 
959 OTResult		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 
992 TCall		sndCall;
993 DNSAddress 	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 
1042 EXITPOINT:
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 
MacSocket_close(const int inSocketNum)1068 OSErr MacSocket_close(const int inSocketNum)
1069 {
1070 OSErr			errCode = noErr;
1071 SocketStruct	*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 
1133 EXITPOINT:
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 
MacSocket_recv(const int inSocketNum,void * outBuff,int outBuffLength,const Boolean inBlock)1159 int MacSocket_recv(const int inSocketNum,void *outBuff,int outBuffLength,const Boolean inBlock)
1160 {
1161 OSErr			errCode = noErr;
1162 int				totalBytesRead = 0;
1163 SocketStruct	*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 
1265 EXITPOINT:
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 
MacSocket_send(const int inSocketNum,const void * inBuff,int inBuffLength)1290 int MacSocket_send(const int inSocketNum,const void *inBuff,int inBuffLength)
1291 {
1292 OSErr			errCode = noErr;
1293 int				bytesSent = 0;
1294 SocketStruct	*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 
1318 OTResult		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 
1367 EXITPOINT:
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 
NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)1397 static OSStatus NegotiateIPReuseAddrOption(EndpointRef inEndpoint,const Boolean inEnableReuseIP)
1398 {
1399 OSStatus	errCode;
1400 UInt8		buf[kOTFourByteOptionSize];
1401 TOption*	theOTOption;
1402 TOptMgmt	theOTRequest;
1403 TOptMgmt	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 
1443 EXITPOINT:
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 /*
1472 struct 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 };
1488 typedef struct InetInterfaceInfo InetInterfaceInfo;
1489 
1490 
1491 
1492 ((InetAddress *) addr.buf)->fHost
1493 
1494 struct TBind
1495 {
1496 	TNetbuf	addr;
1497 	OTQLen	qlen;
1498 };
1499 
1500 typedef struct TBind	TBind;
1501 
1502 struct TNetbuf
1503 {
1504 	size_t	maxlen;
1505 	size_t	len;
1506 	UInt8*	buf;
1507 };
1508 
1509 typedef 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 };
1519 typedef struct InetAddress InetAddress;
1520 */
1521 
1522 
1523 
1524 /*
1525 static pascal void Notifier(void* context, OTEventCode event, OTResult result, void* cookie)
1526 {
1527 EPInfo* 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