Exemple #1
0
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;
}                               
Exemple #2
0
/* _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;
}
Exemple #3
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
	}
}
Exemple #7
0
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);
	}	
}
Exemple #8
0
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();
}
Exemple #9
0
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();
}
Exemple #10
0
		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);
			}
		}
Exemple #11
0
/* 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;	
}