PRInt32 _MD_closesocket(PRInt32 osfd) { OSStatus err; EndpointRef endpoint = (EndpointRef) osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); if (endpoint == NULL) { err = kEBADFErr; goto ErrorExit; } if (me->io_pending && me->io_fd == osfd) me->io_pending = PR_FALSE; #if 0 { OTResult state; state = OTGetEndpointState(endpoint); err = OTSndOrderlyDisconnect(endpoint); if (err != kOTNoError && err != kOTOutStateErr) goto ErrorExit; state = OTGetEndpointState(endpoint); err = OTUnbind(endpoint); if (err != kOTNoError && err != kOTOutStateErr) goto ErrorExit; state = OTGetEndpointState(endpoint); err = OTSetSynchronous(endpoint); if (err != kOTNoError) goto ErrorExit; err = OTSetBlocking(endpoint); if (err != kOTNoError) goto ErrorExit; } #endif (void) OTSndOrderlyDisconnect(endpoint); err = OTCloseProvider(endpoint); if (err != kOTNoError) goto ErrorExit; return kOTNoError; ErrorExit: macsock_map_error(err); return -1; }
/* _GSocket_Output_Timeout: * For blocking sockets, wait until data can be sent without * blocking or until timeout ellapses. */ GSocketError _GSocket_Output_Timeout(GSocket *socket) { if ( !socket->m_non_blocking ) { UnsignedWide now , start ; short formerTakesEvents = socket->m_takesEvents ; Microseconds(&start); now = start ; socket->m_takesEvents = FALSE ; while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < socket->m_timeout * 1000.0 ) { OTResult state ; state = OTGetEndpointState(socket->m_endpoint); if ( state == T_DATAXFER || state == T_INREL ) { socket->m_takesEvents = formerTakesEvents ; return GSOCK_NOERROR; } Microseconds(&now); } socket->m_takesEvents = formerTakesEvents ; socket->m_error = GSOCK_TIMEDOUT; return GSOCK_TIMEDOUT; } return GSOCK_NOERROR; }
void _GSocket_Enable_Events(GSocket *socket) { if ( socket->m_takesEvents ) return ; { OTResult state ; socket->m_takesEvents = TRUE ; state = OTGetEndpointState(socket->m_endpoint); { OTByteCount sz = 0 ; OTCountDataBytes( socket->m_endpoint , &sz ) ; if ( state == T_INCON || sz > 0 ) { socket->m_detected |= GSOCK_INPUT_FLAG ; (socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]); } } { if ( state == T_DATAXFER || state == T_INREL ) { socket->m_detected |=GSOCK_OUTPUT_FLAG ; (socket->m_cbacks[GSOCK_OUTPUT])(socket, GSOCK_OUTPUT, socket->m_data[GSOCK_OUTPUT]); } } } }
NMErr OTIPEnumerator::EndEnumeration(void) { OSStatus status; if (! bActive) return kNMNoError; if (mEP == kOTInvalidEndpointRef) return kNMNoError; status = OTUnbind(mEP); if (status == kNMNoError) { for (NMSInt32 i = 0; i < 1000; i++) { if (OTGetEndpointState(mEP) == T_UNBND) break; } } status = OTCloseProvider(mEP); InterruptSafe_free(mIncomingData.udata.buf); return kNMNoError; }
static PRBool GetState(EndpointRef endpoint, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady) { OSStatus err; OTResult resultOT; TDiscon discon; PRBool result = PR_FALSE; *readReady = *writeReady = *exceptReady = PR_FALSE; resultOT = OTLook(endpoint); switch (resultOT) { case T_DATA: case T_LISTEN: *readReady = PR_TRUE; break; case T_CONNECT: err = OTRcvConnect(endpoint, NULL); PR_ASSERT(err == kOTNoError); break; case T_DISCONNECT: memset(&discon, 0 , sizeof(discon)); err = OTRcvDisconnect(endpoint, &discon); PR_ASSERT(err == kOTNoError); macsock_map_error(discon.reason); *exceptReady = PR_TRUE; break; case T_ORDREL: *readReady = PR_TRUE; err = OTRcvOrderlyDisconnect(endpoint); PR_ASSERT(err == kOTNoError); break; } resultOT = OTGetEndpointState(endpoint); switch (resultOT) { case T_DATAXFER: case T_INREL: *writeReady = PR_TRUE; break; default: *writeReady = PR_FALSE; } if ((*readReady == PR_TRUE) || (*writeReady==PR_TRUE) || (*exceptReady==PR_TRUE)) result = PR_TRUE; return result; }
int _MD_mac_get_nonblocking_connect_error(PRInt32 osfd) { OTResult resultOT; EndpointRef endpoint = (EndpointRef) osfd; resultOT = OTGetEndpointState(endpoint); switch (resultOT) { case T_OUTCON: macsock_map_error(kEINPROGRESSErr); return -1; case T_DATAXFER: return 0; case T_IDLE: return -1; default: PR_ASSERT(0); return -1; } }
static void change_connection(OTTCP *x) { // This sets in motion the following sequence of events: // - Disconnect the endpoint // - Unbind the endpoint // - If (x->o_inetHost != 0), bind the endpoint again // - connect the endpoint // Each of these events is triggered in the notifier function when the previous // event completes, so the job of this procedure is just to see what state we're // in and start the process. OTResult r; OSStatus s; ChangeState(x, SETTING_UP); r = OTGetEndpointState(x->o_tcp_ep); if (r == T_UNINIT) { // This shouldn't happen ouchstring("OTTCP: Connect: didn't expect endpoint state to be T_UNINIT!"); } else if (r == T_UNBND) { // Endpoint is already unbound, so we're completely disconnected. // If we have a new inetHost, try to bind it if (x->o_inetHost != 0) { BindTheEndpoint(x); // Now we expect T_BINDCOMPLETE } // Now we expect T_BINDCOMPLETE } else if (r == T_IDLE) { // Endpoint is bound, but not connected. s = OTUnbind(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTUnbind returned %ld", s); } // Now we expect T_UNBINDCOMPLETE } else if (r == T_OUTCON || r == T_DATAXFER) { // We're either starting a connection or the connection is currently established, // so send an orderly disconnect post ("** Sending orderly disconnect "); s = OTSndOrderlyDisconnect(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTSndOrderlyDisconnect returned %ld", s); } // I guess now we expect T_DISCONNECTCOMPLETE } else if (r == T_INCON) { ouchstring("OTTCP: Connect: didn't expect endpoint state to be T_INCON!"); } else if (r == T_OUTREL) { // We already tried an orderly disconnect, but it still hasn't been acknowledged, // so screw orderliness and try a regular diconnect TCall call; call.addr.len = 0; call.opt.len = 0; call.udata.len = 0; call.addr.maxlen = 0; call.opt.maxlen = 0; call.udata.maxlen = 0; s = OTSndDisconnect(x->o_tcp_ep, &call); if (s != kOTNoError) { post("OTTCP: warning: OTSndDisconnect returned %ld", s); } // Now we expect T_DISCONNECTCOMPLETE } else if (r == T_INREL) { // Our peer wants an orderly disonnect, so let's acknowlegde it! } else { post(" еее Unrecognized endpoint state %ld!", r); } }
pascal void OTTCPNotifier(void* vobj, OTEventCode code, OTResult result, void* cookie) { OTTCP *x = (OTTCP *) vobj; long oldA5; OSStatus s; EnterCallback(); oldA5 = SetA5(x->o_a5); post("*** OTTCPNotifier(code %x, result %ld)", (long) code, (long) result); if (code == T_OPENCOMPLETE) { if (result != noErr) { post("OTTCPNotifier got a T_OPENCOMPLETE code with error %ld", result); } // Even if we got an error, we'll use the endpoint. x->o_tcp_ep = (EndpointRef) cookie; if (x->o_inetHostName != 0) { BindTheEndpoint(x); // Now we expect a T_BINDCOMPLETE message. } } else if (code == T_BINDCOMPLETE) { TCall sndCall; InetAddress inAddr; // See what ephemeral port number OT gave us x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort; // Now the endpoint has been bound; next trick is connecting OTInitInetAddress(&inAddr, x->o_inetPort, x->o_inetHost); OTMemzero(&sndCall, sizeof(TCall)); sndCall.addr.buf = (void *) &inAddr; sndCall.addr.len = sizeof(InetAddress); post("** About to OTConnect"); s = OTConnect(x->o_tcp_ep, &sndCall, NULL); if (s == kOTNoDataErr) { // No problem; that means connection is in progress post("** OTConnect returned kOTNoDataErr - good"); } else { post("е OTTCP: error: OTConnect returned %ld; not connecting.", s); } // Now we expect T_CONNECT } else if (code == T_CONNECT) { if (result == kOTBadAddressErr) { post("е OTTCP: error: bad address. Disconnecting"); x->o_inetHost = 0; change_connection(x); } else { post("** Got T_CONNECT"); post("** Result passed to notifier: %ld", (long) result); post("** Endpoint state before OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep)); // We could pass in buffers to find out the actual address we connected to, etc. s = OTRcvConnect(x->o_tcp_ep, nil); if (s != kOTNoError) { post("е OTTCP: error: RcvConnect returned %ld", s); } post("** Endpoint state after OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep)); ChangeState(x, NO_REQUEST); x->o_connectionSymbol = ps_connected; clock_delay(x->o_connectedclock, 0); } } else if (code == T_UNBINDCOMPLETE) { // If we have a new inetHost, try to bind it if (x->o_inetHost != 0) { BindTheEndpoint(x); // Now we expect T_BINDCOMPLETE } else { // No inetHost, so we're disonnected x->o_connectionSymbol = ps_disconnected; clock_delay(x->o_connectedclock, 0); } } else if (code == T_DISCONNECTCOMPLETE) { // We always want to rebind when we reconnect, so after disconnecting we unbind s = OTUnbind(x->o_tcp_ep); if (s != kOTNoError) { post("OTTCP: warning: OTUnbind returned %ld", s); } } else if (code == T_DATA) { ottcp_handleIncomingData(x); } else if (code == T_UDERR) { if (x->o_errorreporting) { PostUDERR("OTTCPNotifier was called for a T_UDERR code", x->o_tcp_ep); } else { /* We still have to receive the error to clear the condition */ OTRcvUDErr(x->o_tcp_ep, 0); } } else if (code == T_GODATA) { // Flow control restriction has lifted; now it's OK to send more data. do_write(x, 0, 0); } else if (code == T_DISCONNECT) { // The other dude wants to disconnect post("OTTCP: peer wants to disconnect"); s = OTRcvDisconnect(x->o_tcp_ep, NULL); if (s == kOTNoError) { x->o_inetHost = 0; change_connection(x); } else if (s == kOTNoDisconnectErr) { // false alarm } else { post("е OTTCP: error: OTRcvDisconnect returned %ld", s); } } else if (code == T_ORDREL) { post("*** Got T_ORDREL"); s = OTRcvOrderlyDisconnect(x->o_tcp_ep); if (s == kOTNoReleaseErr) { post("...false alarm!"); } else if (s == kOTNoError) { x->o_inetHost = 0; change_connection(x); } else { post("е OTTCP: error: OTRcvOrderlyDisconnect returned %ld", s); } } else { if (x->o_errorreporting) { post("OTTCP: Unrecognized OTEventCode %ld in event handler. Oh well.", (long) code); } } done: SetA5(oldA5); ExitCallback(); }
void ottcp_tellmeeverything(OTTCP *x) { OTResult r; EnterCallback(); post("ottcp_tellmeeverything: You asked for it"); version(x); post(" This object error does %sreport errors", x->o_errorreporting ? "" : "not "); post(" state: %s", StateName(x->o_state)); if (x->o_state == OUTPUTTING) { post(" whatToOutput: %s", StateName(x->o_whatToOutput)); post(" nextRequest: %s", StateName(x->o_nextRequest)); } else if (x->o_state == GET_NBYTES) { post(" Getting %ld bytes.", x->o_numBytesWeWant); } else if (x->o_state == GET_DELIM) { post(" Looking for %ld-byte delimiterthat starts with \"%c\"", x->o_delimiterLen, x->o_delimiterBytes[0]); } if (x->o_datawaiting) { post(" There is data waiting in TCP's buffer"); } else { post(" There doesn't seem to be any data waiting in TCP's buffer"); } if (x->o_tcp_ep == 0) { post(" This object has not created an endpoint yet."); } else { post(" This object's endpoint reference is %p", x->o_tcp_ep); post(" Endpoint info: addr %ld, options %ld, tsdu %ld, etsdu %ld, connect %ld", x->epinfo.addr, x->epinfo.options, x->epinfo.tsdu, x->epinfo.etsdu, x->epinfo.connect); post(" discon %ld, servtype %lu, flags %lu", x->epinfo.discon, x->epinfo.servtype, x->epinfo.flags); } r = OTGetEndpointState(x->o_tcp_ep); if (r == T_UNINIT) { post(" Endpoint state: T_UNINIT"); } else if (r == T_UNBND) { post(" Endpoint state: T_UNBND"); } else if (r == T_IDLE) { post(" Endpoint state: T_IDLE"); } else if (r == T_OUTCON) { post(" Endpoint state: T_OUTCON"); } else if (r == T_INCON) { post(" Endpoint state: T_INCON"); } else if (r == T_DATAXFER) { post(" Endpoint state: T_DATAXFER"); } else if (r == T_OUTREL) { post(" Endpoint state: T_OUTREL"); } else if (r == T_INREL) { post(" Endpoint state: T_INREL"); } else { post(" еее Unrecognized endpoints state %ld!", r); } { char hostnameBuf[100]; post(" You asked to write to internet host \"%s\"", x->o_inetHostName); OTInetHostToString(x->o_inetHost, hostnameBuf); post(" Writing to internet host %s", hostnameBuf); post(" Writing to port %ld", (long)( x->o_inetPort)); } post(" This object reads from port %ld", (long) x->o_receiveInetPort); post(" Read buffers: size %ld, %ld bytes in current buffer, %ld bytes in next buffer", x->o_ReadBufSize, x->o_bytesRead, x->o_bytesReadForNextTime); post(" Write buffer: size %ld, read position %ld, write position %ld", x->o_WriteBufSize, x->o_WBReadPos, x->o_WBWritePos); ExitCallback(); }
void dprintf_oterr( EndpointRef ep, char *message, NMErr err, char *file, NMSInt32 line) { char *name; char error[256]; char state[256]; if (err) { switch (err) { PRINT_CASE(kOTOutOfMemoryErr); PRINT_CASE(kOTNotFoundErr); PRINT_CASE(kOTDuplicateFoundErr); PRINT_CASE(kOTBadAddressErr); PRINT_CASE(kOTBadOptionErr); PRINT_CASE(kOTAccessErr); PRINT_CASE(kOTBadReferenceErr); PRINT_CASE(kOTNoAddressErr); PRINT_CASE(kOTOutStateErr); PRINT_CASE(kOTBadSequenceErr); PRINT_CASE(kOTSysErrorErr); PRINT_CASE(kOTLookErr); PRINT_CASE(kOTBadDataErr); PRINT_CASE(kOTBufferOverflowErr); PRINT_CASE(kOTFlowErr); PRINT_CASE(kOTNoDataErr); PRINT_CASE(kOTNoDisconnectErr); PRINT_CASE(kOTNoUDErrErr); PRINT_CASE(kOTBadFlagErr); PRINT_CASE(kOTNoReleaseErr); PRINT_CASE(kOTNotSupportedErr); PRINT_CASE(kOTStateChangeErr); PRINT_CASE(kOTNoStructureTypeErr); PRINT_CASE(kOTBadNameErr); PRINT_CASE(kOTBadQLenErr); PRINT_CASE(kOTAddressBusyErr); PRINT_CASE(kOTIndOutErr); PRINT_CASE(kOTProviderMismatchErr); PRINT_CASE(kOTResQLenErr); PRINT_CASE(kOTResAddressErr); PRINT_CASE(kOTQFullErr); PRINT_CASE(kOTProtocolErr); PRINT_CASE(kOTBadSyncErr); PRINT_CASE(kOTCanceledErr); PRINT_CASE(kEPERMErr); // PRINT_CASE(kENOENTErr); PRINT_CASE(kENORSRCErr); PRINT_CASE(kEINTRErr); PRINT_CASE(kEIOErr); PRINT_CASE(kENXIOErr); PRINT_CASE(kEBADFErr); PRINT_CASE(kEAGAINErr); // PRINT_CASE(kENOMEMErr); PRINT_CASE(kEACCESErr); PRINT_CASE(kEFAULTErr); PRINT_CASE(kEBUSYErr); // PRINT_CASE(kEEXISTErr); PRINT_CASE(kENODEVErr); PRINT_CASE(kEINVALErr); PRINT_CASE(kENOTTYErr); PRINT_CASE(kEPIPEErr); PRINT_CASE(kERANGEErr); PRINT_CASE(kEWOULDBLOCKErr); // PRINT_CASE(kEDEADLKErr); PRINT_CASE(kEALREADYErr); PRINT_CASE(kENOTSOCKErr); PRINT_CASE(kEDESTADDRREQErr); PRINT_CASE(kEMSGSIZEErr); PRINT_CASE(kEPROTOTYPEErr); PRINT_CASE(kENOPROTOOPTErr); PRINT_CASE(kEPROTONOSUPPORTErr); PRINT_CASE(kESOCKTNOSUPPORTErr); PRINT_CASE(kEOPNOTSUPPErr); PRINT_CASE(kEADDRINUSEErr); PRINT_CASE(kEADDRNOTAVAILErr); PRINT_CASE(kENETDOWNErr); PRINT_CASE(kENETUNREACHErr); PRINT_CASE(kENETRESETErr); PRINT_CASE(kECONNABORTEDErr); PRINT_CASE(kECONNRESETErr); PRINT_CASE(kENOBUFSErr); PRINT_CASE(kEISCONNErr); PRINT_CASE(kENOTCONNErr); PRINT_CASE(kESHUTDOWNErr); PRINT_CASE(kETOOMANYREFSErr); PRINT_CASE(kETIMEDOUTErr); PRINT_CASE(kECONNREFUSEDErr); PRINT_CASE(kEHOSTDOWNErr); PRINT_CASE(kEHOSTUNREACHErr); PRINT_CASE(kEPROTOErr); PRINT_CASE(kETIMEErr); PRINT_CASE(kENOSRErr); PRINT_CASE(kEBADMSGErr); PRINT_CASE(kECANCELErr); PRINT_CASE(kENOSTRErr); PRINT_CASE(kENODATAErr); PRINT_CASE(kEINPROGRESSErr); PRINT_CASE(kESRCHErr); PRINT_CASE(kENOMSGErr); PRINT_CASE(kOTClientNotInittedErr); PRINT_CASE(kOTPortHasDiedErr); PRINT_CASE(kOTPortWasEjectedErr); PRINT_CASE(kOTBadConfigurationErr); PRINT_CASE(kOTConfigurationChangedErr); PRINT_CASE(kOTUserRequestedErr); PRINT_CASE(kOTPortLostConnection); default: name = "< unknown >"; break; } strcpy(error,name); if (ep) { switch (OTGetEndpointState(ep)) { PRINT_CASE(T_UNINIT); PRINT_CASE(T_UNBND); PRINT_CASE(T_IDLE); PRINT_CASE(T_OUTCON); PRINT_CASE(T_INCON); PRINT_CASE(T_DATAXFER); PRINT_CASE(T_OUTREL); PRINT_CASE(T_INREL); default: name = "< unknown >"; break; } } else name = "<unknown>"; strcpy(state,name); DEBUG_PRINT("EP: %p (state: %s), OTError for %s: %s (%d). File: %s, %d",ep, state, message, error, err, file, line); } }
/* Open a TCP network socket If 'remote' is NULL, this creates a local server socket on the given port, otherwise a TCP connection to the remote host and port is attempted. The newly created socket is returned, or NULL if there was an error. ( re-written by masahiro minami<*****@*****.**> Now endpoint is created in Async mode. 01/02/20 ) */ TCPsocket SDLNet_TCP_Open(IPaddress *ip) { EndpointRef dummy = NULL; TCPsocket sock = AsyncTCPNewSocket(); if( ! sock) return NULL; // Determin whether bind locally, or connect to remote if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) ) { // ######## Connect to remote OTResult stat; InetAddress inAddr; TBind bindReq; // Open endpoint sock->error = OTAsyncOpenEndpoint( OTCreateConfiguration(kTCPName), NULL, &(sock->info), (OTNotifyProcPtr)(AsyncTCPNotifier), sock ); AsyncTCPPopEvent( sock ); while( !sock->error && !( sock->completion & CompleteMask(T_OPENCOMPLETE))) { //SetThreadState( kCurrentThreadID, kReadyThreadState, kNoThreadID ); //YieldToAnyThread(); //WaitNextEvent(everyEvent, &macEvent, 1, NULL); AsyncTCPPopEvent( sock ); } if( !sock->channel ) { SDLNet_SetError("OTAsyncOpenEndpoint failed --- client socket could not be opened"); goto error_return; } // Set blocking mode // I'm not sure if this is a good solution.... // Check out Apple's sample code, OT Virtual Server // ( 010314 masahiro minami<*****@*****.**>) sock->error = OTSetBlocking( sock->channel ); if( sock->error != kOTNoError ) { SDLNet_SetError("OTSetBlocking() returned an error"); goto error_return; } // Bind the socket OTInitInetAddress(&inAddr, 0, 0 ); bindReq.addr.len = sizeof( InetAddress ); bindReq.addr.buf = (unsigned char*)&inAddr; bindReq.qlen = 0; sock->error = OTBind( sock->channel, &bindReq, NULL ); AsyncTCPPopEvent(sock); while( !sock->error && !( sock->completion & CompleteMask(T_BINDCOMPLETE))) { //YieldToAnyThread(); //WaitNextEvent(everyEvent, &macEvent, 1, NULL); AsyncTCPPopEvent(sock); } switch( stat = OTGetEndpointState( sock->channel )) { InetAddress inAddr; TCall sndCall; OTResult res; case T_OUTCON: SDLNet_SetError("SDLNet_Open() failed -- T_OUTCON"); goto error_return; break; case T_IDLE: sock->readShutdown = false; sock->writeShutdown = false; sock->event &=~T_CONNECT; OTMemzero(&sndCall, sizeof(TCall)); OTInitInetAddress(&inAddr, ip->port, ip->host ); sndCall.addr.len = sizeof(InetAddress); sndCall.addr.buf = (unsigned char*)&inAddr; sock->connected = 0; res = OTConnect( sock->channel, &sndCall, NULL ); AsyncTCPPopEvent(sock); while( sock->error == kOTNoDataErr || !sock->connected ) AsyncTCPPopEvent(sock); break; default: // What's to be done ? (TODO) SDLNet_SetError("SDLNet_TCP_Open() failed -- EndpointState not good"); goto error_return; } if( !(sock->event & (T_CONNECT|T_DISCONNECT))) goto error_return; AsyncTCPPopEvent( sock ); while( !(sock->event & (T_CONNECT|T_DISCONNECT))) { AsyncTCPPopEvent( sock ); } // OTConnect successfull if( sock->event & T_CONNECT) { sock->remoteAddress.host = inAddr.fHost; sock->remoteAddress.port = inAddr.fPort; sock->sflag = false; } else { // OTConnect failed sock->event &= ~T_DISCONNECT; goto error_return; } } else { // ######## Bind locally TBind bindReq; InetAddress inAddr; // First, get InetInterfaceInfo. // I don't search for all of them. // Does that matter ? sock->error = OTAsyncOpenEndpoint( OTCreateConfiguration("tilisten, tcp"), NULL, &(sock->info), (OTNotifyProcPtr)(AsyncTCPNotifier), sock); AsyncTCPPopEvent( sock ); while( !sock->error && !( sock->completion & CompleteMask( T_OPENCOMPLETE))) { AsyncTCPPopEvent( sock ); } if( ! sock->channel ) { SDLNet_SetError("OTAsyncOpenEndpoint failed --- server socket could not be opened"); goto error_return; } // Create a master OTConfiguration sock->config = OTCreateConfiguration(kTCPName); if( ! sock->config ) { SDLNet_SetError("Could not create master OTConfiguration"); goto error_return; } // Bind the socket OTInitInetAddress(&inAddr, ip->port, 0 ); inAddr.fAddressType = AF_INET; bindReq.addr.len = sizeof( InetAddress ); bindReq.addr.buf = (unsigned char*)&inAddr; bindReq.qlen = 35; // This number is NOT well considered. (TODO) sock->localAddress.host = inAddr.fHost; sock->localAddress.port = inAddr.fPort; sock->sflag = true; sock->error = OTBind( sock->channel, &bindReq, NULL ); AsyncTCPPopEvent(sock); while( !sock->error && !( sock->completion & CompleteMask(T_BINDCOMPLETE))) { AsyncTCPPopEvent(sock); } if( sock->error != kOTNoError ) { SDLNet_SetError("Could not bind server socket"); goto error_return; } if( dummy ) OTCloseProvider( dummy ); } sock->ready = 0; return sock; error_return: if( dummy ) OTCloseProvider( dummy ); SDLNet_TCP_Close( sock ); return NULL; }