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