コード例 #1
0
// CreateProxyRegistrationForRealService() checks to see if the given port is currently
// in use, and if so, advertises the specified service as present on that port.
// This is useful for advertising existing real services (Personal Web Sharing, Personal
// File Sharing, etc.) that currently don't register with mDNS Service Discovery themselves.
mDNSlocal OSStatus CreateProxyRegistrationForRealService(mDNS *m, UInt16 PortAsNumber, const char txtinfo[],
	const char *servicetype, ServiceRecordSet *recordset)
	{
	InetAddress ia;
	TBind bindReq;
	OSStatus err;
	TEndpointInfo endpointinfo;
	EndpointRef ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &endpointinfo, &err);
	if (!ep || err) { printf("OTOpenEndpoint (CreateProxyRegistrationForRealService) failed %d", err); return(err); }

	ia.fAddressType = AF_INET;
	ia.fPort        = mDNSOpaque16fromIntVal(PortAsNumber).NotAnInteger;
	ia.fHost        = 0;
	bindReq.addr.maxlen = sizeof(ia);
	bindReq.addr.len    = sizeof(ia);
	bindReq.addr.buf    = (UInt8*)&ia;
	bindReq.qlen        = 0;
	err = OTBind(ep, &bindReq, NULL);

	if (err == kOTBadAddressErr)
		RegisterService(m, recordset, PortAsNumber, txtinfo, &m->nicelabel, servicetype, "local.");
	else if (err)
		debugf("OTBind failed %d", err);

	OTCloseProvider(ep);
	return(noErr);
	}
コード例 #2
0
/*---------------------------------------------------------------------------*/
static AGSocket *AGNetSocketNew(AGNetCtx *ctx)
{
    AGSocket *soc;
    OSStatus err = noErr;    

    /* Note that in this implementation we don't actually need the
    AGNetCtx pointer. Left in for source-code compatibility. */
    
    soc = (AGSocket *)malloc(sizeof(AGSocket));
    if (NULL == soc)
        return NULL;
    bzero(soc, sizeof(AGSocket));

    soc->ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, NULL, &err);
    if (noErr == err) {
        err = OTBind(soc->ep, NULL, NULL);
        if (noErr == err) {
            /* Success.  Return newly created socket. */
            soc->bound = TRUE;
            return soc;
        }
        OTCloseProvider(soc->ep);
    }
    
    /* Didn't successfully bind, so return error. */
    free(soc);
    return NULL;
}
コード例 #3
0
// CreateProxyRegistrationForRealService() checks to see if the given port is currently
// in use, and if so, advertises the specified service as present on that port.
// This is useful for advertising existing real services (Personal Web Sharing, Personal
// File Sharing, etc.) that currently don't register with mDNS Service Discovery themselves.
static DNSServiceErrorType CreateProxyRegistrationForRealService(RegisteredService *rs,
	const char *servicetype, UInt16 PortAsNumber, const char txtinfo[])
	{
	mDNSOpaque16 OpaquePort = mDNSOpaque16fromIntVal(PortAsNumber);
	InetAddress ia;
	TBind bindReq;
	OSStatus err;
	TEndpointInfo endpointinfo;
	EndpointRef ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &endpointinfo, &err);
	if (!ep || err) { printf("OTOpenEndpoint (CreateProxyRegistrationForRealService) failed %d", err); return(err); }

	ia.fAddressType = AF_INET;
	ia.fPort        = OpaquePort.NotAnInteger;
	ia.fHost        = 0;
	bindReq.addr.maxlen = sizeof(ia);
	bindReq.addr.len    = sizeof(ia);
	bindReq.addr.buf    = (UInt8*)&ia;
	bindReq.qlen        = 0;
	err = OTBind(ep, &bindReq, NULL);

	if (err == kOTBadAddressErr)
		err = RegisterService(rs, OpaquePort, "", servicetype, "local.", txtinfo);
	else if (err)
		printf("OTBind failed %d", err);

	OTCloseProvider(ep);
	return(err);
	}
コード例 #4
0
ファイル: otudp.c プロジェクト: CNMAT/CNMAT-Externs
void BindTheEndpoint(OTUDP *x) {
	// This will be called from within our notifier function after the endpoint is created,
	// or, when changing hosts, to re-bind the endpoint after unbinding it.
	OSStatus err;

	
	/* Set up the data structure OTBind will use to say what port number we got */
	x->o_bindAddrWeActuallyGot.addr.maxlen = sizeof(struct InetAddress);
	x->o_bindAddrWeActuallyGot.addr.buf = (unsigned char *) &(x->o_addrWeActuallyGot);
	
	if (x->o_writer) {
		/* Let OTBind pick a return address port number for us */
  	    err = OTBind(x->o_udp_ep, nil, &(x->o_bindAddrWeActuallyGot));
		if (err != kOTNoError) {
			error("¥ otudp: Error %d from OTBind.  You may not be able to write.", err);
			return;
		}
	} else {
		/* Tell OTBind what port number we want to use */
		struct InetAddress desiredAddress;
		TBind bindDesiredAddress;

		OTInitInetAddress(&desiredAddress, x->o_receiveInetPort, (InetHost) 0);
		
		bindDesiredAddress.addr.maxlen = sizeof(struct InetAddress);
		bindDesiredAddress.addr.len = sizeof(struct InetAddress);
		bindDesiredAddress.addr.buf = (unsigned char *) &desiredAddress;

		err = OTBind(x->o_udp_ep, &bindDesiredAddress, &(x->o_bindAddrWeActuallyGot));

		if (err != kOTNoError) {
			error("¥ otudp: Error %d from OTBind.  You may not be able to read.", err);
			return;
		}
		
	}
	
	/* Could output something to let the Max programmer know that we're now re-bound... */

}
コード例 #5
0
ファイル: OTIPEndpoint.cpp プロジェクト: MaddTheSane/tntbasic
NMErr
OTIPEndpoint::DoBind(
	PrivateEndpoint	*inEP,
	TBind			*inRequest,
	TBind			*outReturned)
{
	NMErr	status = kNMNoError;
	NMBoolean	active;
	
	active = (inRequest->qlen == 0);
	
	if (inEP == mStreamEndpoint  && !active)
	{
		status = OTUtils::DoNegotiateIPReuseAddrOption(inEP->mEP, true);
		DEBUG_NETWORK_API(inEP->mEP, "Negotiate Reuse Option", status);	
		status = OTUtils::DoNegotiateTCPNoDelayOption(inEP->mEP, true);
		DEBUG_NETWORK_API(inEP->mEP, "Negotiate No Delay Option", status);
	}			
	
	if (inRequest->addr.buf)
	{
		long portNum = ((InetAddress *)inRequest->addr.buf)->fPort;
		status = OTBind(inEP->mEP, inRequest, outReturned);
		DEBUG_PRINT("binding; requesting port %d; result: %d; returned port %d",portNum,status,((InetAddress *)outReturned->addr.buf)->fPort);	
	}
	else{
		status = OTBind(inEP->mEP, NULL, outReturned);
		DEBUG_PRINT("binding to any port; result: %d; returned port %d",status,((InetAddress *)outReturned->addr.buf)->fPort);	
	}
	DEBUG_NETWORK_API(inEP->mEP, "OTBind", status);	

	if (status)
	{
		NMErr code = status;
		return code;
	}
	
	return status;
}
コード例 #6
0
ファイル: ottcp.c プロジェクト: CNMAT/CNMAT-Externs
void BindTheEndpoint(OTTCP *x) {
	OSStatus err;
	
	/* Set up the data structure OTBind will use to say what port number we get */
	x->o_bindAddrWeActuallyGot.addr.maxlen = sizeof(struct InetAddress);
	x->o_bindAddrWeActuallyGot.addr.buf = (unsigned char *) &(x->o_addrWeActuallyGot);
	
	/* Let OTBind pick a return address port number for us */
    err = OTBind(x->o_tcp_ep, nil, &(x->o_bindAddrWeActuallyGot));
	if (err != kOTNoError) {
		ouchstring("otudp: Error %d from OTBind", err);
		return;
	}
}
コード例 #7
0
PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
{
	PRInt32 osfd = fd->secret->md.osfd;
	OSStatus err;
	EndpointRef endpoint = (EndpointRef) osfd;
	PRThread *me = _PR_MD_CURRENT_THREAD();
	TCall sndCall;
	TBind bindReq;
	PRNetAddr bindAddr;

	if (endpoint == NULL) {
		err = kEBADFErr;
		goto ErrorExit;
	}
		
	if (addr == NULL) {
		err = kEFAULTErr;
		goto ErrorExit;
	}
		
	// Bind to a local port; let the system assign it.

	bindAddr.inet.port = bindAddr.inet.ip = 0;

	bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);
	bindReq.addr.len = 0;
	bindReq.addr.buf = (UInt8*) &bindAddr;
	bindReq.qlen = 0;
	
	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTBind(endpoint, &bindReq, NULL);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	memset(&sndCall, 0 , sizeof(sndCall));

	sndCall.addr.maxlen = addrlen;
	sndCall.addr.len = addrlen;
	sndCall.addr.buf = (UInt8*) addr;
	
	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTConnect (endpoint, &sndCall, NULL);
	if (err != kOTNoError && err != kOTNoDataErr)
		goto ErrorExit;
	if (err == kOTNoDataErr && fd->secret->nonblocking) {
		err = kEINPROGRESSErr;
    	me->io_pending = PR_FALSE;
		goto ErrorExit;
	}

	WaitOnThisThread(me, timeout);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	PR_ASSERT(me->md.cookie != NULL);

	err = OTRcvConnect(endpoint, NULL);
	PR_ASSERT(err == kOTNoError);

	return kOTNoError;

ErrorExit:
	macsock_map_error(err);
    return -1;
}
コード例 #8
0
PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
{
	PRInt32 osfd = fd->secret->md.osfd;
	OSStatus err;
	EndpointRef endpoint = (EndpointRef) osfd;
	PRThread *me = _PR_MD_CURRENT_THREAD();
	TBind bindReq;
	PRNetAddr bindAddr;
	PRInt32 newosfd = -1;
	EndpointRef newEndpoint;
	TCall call;
	PRNetAddr callAddr;

	if (endpoint == NULL) {
		err = kEBADFErr;
		goto ErrorExit;
	}
		
	memset(&call, 0 , sizeof(call));

	call.addr.maxlen = PR_NETADDR_SIZE(&callAddr);
	call.addr.len = PR_NETADDR_SIZE(&callAddr);
	call.addr.buf = (UInt8*) &callAddr;
	
	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTListen (endpoint, &call);
	if (err != kOTNoError && (err != kOTNoDataErr || fd->secret->nonblocking)) {
    	me->io_pending = PR_FALSE;
		goto ErrorExit;
	}

	while (err == kOTNoDataErr) {
		WaitOnThisThread(me, timeout);
		err = me->md.osErrCode;
		if (err != kOTNoError)
			goto ErrorExit;

		PrepareThreadForAsyncIO(me, endpoint, osfd);    

		err = OTListen (endpoint, &call);
		if (err == kOTNoError)
			break;

		PR_ASSERT(err == kOTNoDataErr);
	}		

	newosfd = _MD_socket(AF_INET, SOCK_STREAM, 0);
	if (newosfd == -1)
		return -1;

	newEndpoint = (EndpointRef)newosfd;
	
	// Bind to a local port; let the system assign it.

	bindAddr.inet.port = bindAddr.inet.ip = 0;

	bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);
	bindReq.addr.len = 0;
	bindReq.addr.buf = (UInt8*) &bindAddr;
	bindReq.qlen = 0;
	
	PrepareThreadForAsyncIO(me, newEndpoint, newosfd);    

	err = OTBind(newEndpoint, &bindReq, NULL);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, timeout);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	PrepareThreadForAsyncIO(me, endpoint, newosfd);    

	err = OTAccept (endpoint, newEndpoint, &call);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, timeout);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	PR_ASSERT(me->md.cookie != NULL);

	if (addr != NULL)
		*addr = callAddr;
	if (addrlen != NULL)
		*addrlen = call.addr.len;

	return newosfd;

ErrorExit:
	if (newosfd != -1)
		_MD_closesocket(newosfd);
	macsock_map_error(err);
    return -1;
}
コード例 #9
0
// Errors:
// EBADF -- bad socket id
PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog)
{
#if 0
	PRInt32 osfd = fd->secret->md.osfd;
	OSStatus err;
	EndpointRef endpoint = (EndpointRef) osfd;
	TBind bindReq;
	PRNetAddr addr;
	PRThread *me = _PR_MD_CURRENT_THREAD();

	if (backlog == 0)
		backlog = 1;

	if (endpoint == NULL) {
		err = EBADF;
		goto ErrorExit;
	}
		
	addr.inet.port = addr.inet.ip = 0;

	bindReq.addr.maxlen = PR_NETADDR_SIZE (&addr);
	bindReq.addr.len = 0;
	bindReq.addr.buf = (UInt8*) &addr;
	bindReq.qlen = 0;
	
	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTGetProtAddress(endpoint, &bindReq, NULL);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTUnbind(endpoint);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	bindReq.qlen = backlog;
	
	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTBind(endpoint, &bindReq, NULL);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	PR_ASSERT(me->md.cookie == NULL);

	return kOTNoError;

ErrorExit:
	macsock_map_error(err);
    return -1;
#endif

#pragma unused (fd, backlog)	
	return kOTNoError;

}
コード例 #10
0
// Errors:
// EBADF -- bad socket id
// EFAULT -- bad address format
PRInt32 _MD_bind(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen)
{
	PRInt32 osfd = fd->secret->md.osfd;
	OSStatus err;
	EndpointRef endpoint = (EndpointRef) osfd;
	TBind bindReq;
	PRThread *me = _PR_MD_CURRENT_THREAD();
	PRUint32 retryCount = 0;

	if (endpoint == NULL) {
		err = kEBADFErr;
		goto ErrorExit;
	}
		
	if (addr == NULL) {
		err = kEFAULTErr;
		goto ErrorExit;
	}
		
	// setup our request
#if 0
	if ((addr->inet.port == 0) || (addr->inet.ip == 0))
		bindReq.addr.len = 0;
	else
#endif
/*
 * There seems to be a bug with OT ralted to OTBind failing with kOTNoAddressErr eventhough
 * a proper legal address was supplied.  This happens very rarely and just retrying the
 * operation after a certain time (less than 1 sec. does not work) seems to succeed.
 */

TryAgain:
	bindReq.addr.len = addrlen;
		
	bindReq.addr.maxlen = addrlen;
	bindReq.addr.buf = (UInt8*) addr;
	bindReq.qlen = 1;
	
	PrepareThreadForAsyncIO(me, endpoint, osfd);    

	err = OTBind(endpoint, &bindReq, NULL);
	if (err != kOTNoError)
		goto ErrorExit;

	WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);

	err = me->md.osErrCode;
	if (err != kOTNoError)
		goto ErrorExit;

	PR_ASSERT(me->md.cookie == NULL);

	return kOTNoError;

ErrorExit:
	if ((err == kOTNoAddressErr) && (++retryCount <= 4)) {
		long finalTicks;
	
	    Delay(100,&finalTicks);
		goto TryAgain;
	}
	macsock_map_error(err);
    return -1;
}
コード例 #11
0
NMErr
OTIPEnumerator::StartEnumeration(void)
{
	TEndpointInfo	info;
	NMErr			status = kNMNoError;
	TBind			request;
	TOption			optBuf;
	//NMUInt8			optBuf[64];
	//NMUInt8			fooBuf[32];
	TOptMgmt		cmd;
	//NMUInt8 			*foo = fooBuf;

	
	//	If they don't want us to actively get the enumeration, there is nothing to do
	if (! bActive)
		return kNMNoError;
	
	//	first clear out any current items
	(mCallback)(mContext, kNMEnumClear, NULL);	// [Edmark/PBE] 11/16/99 added

	bFirstIdle = true;
	
	//	Create an OT endpoint
	mEP = OTOpenEndpoint(OTCreateConfiguration(kUDPName), 0, &info, &status);
	if (status)
		goto error;

	// fill in the option request
	cmd.flags = T_NEGOTIATE;
	cmd.opt.len = kOTFourByteOptionSize;
	cmd.opt.maxlen = kOTFourByteOptionSize;
	cmd.opt.buf = (NMUInt8*)&optBuf;

	// fill in the toption struct
	optBuf.len = sizeof(TOption);
	optBuf.level = INET_IP;
	optBuf.name = kIP_BROADCAST;
	optBuf.status = 0;
	optBuf.value[0] = 1;

/*
	cmd.opt.len = 0;
	cmd.opt.maxlen = 64;
	cmd.opt.buf = (NMUInt8*)optBuf;
	cmd.flags = T_NEGOTIATE;

	//	Option management kinda sucks
	strcpy((char *) fooBuf, "Broadcast = 1");
	status = OTCreateOptions(kRawIPName, (char **)&foo, &cmd.opt);
*/

	status = OTOptionManagement(mEP, &cmd, &cmd);
	if (status)
		goto error;
	
	//	Allocate the buffer for receiving the endpoint
	mIncomingData.udata.buf = (NMUInt8 *) InterruptSafe_alloc(info.tsdu);
	if (mIncomingData.udata.buf == NULL){
		status = kNSpMemAllocationErr;
		goto error;
	}
	
	mIncomingData.udata.maxlen = info.tsdu;
	
	//	Bind it
	request.addr.buf = NULL;
	request.addr.len = 0;
	request.addr.maxlen = 0;
	request.qlen = 0;
	
	status = OTBind(mEP, &request, NULL);
	if (status)
		goto error;

	OTSetNonBlocking(mEP);
	
	//	Get our interface info (for the broadcast address)
	//	Do this after we bind so that we know the interface is live
	if (! bGotInterfaceInfo)
	{
		status = OTInetGetInterfaceInfo(&mInterfaceInfo, kDefaultInetInterface);
		if (status)
			goto error;
		
		bGotInterfaceInfo = true;
	}
	
	//	Install notifier
	status = OTInstallNotifier(mEP, mNotifier.fUPP, this);
	if (status)
		goto error;
	
	//	Make is asynchronous
	status = OTSetAsynchronous(mEP);
	if (status)
		goto error;
	
	//	Send out the query
	mEnumPeriod = 250;
	status = SendQuery();

error:
	if (status)
	{
		if (mEP)
		{
			OTCloseProvider(mEP);			// ignore errors
			mEP = kOTInvalidEndpointRef;
		}
	}
	return status;
}
コード例 #12
0
ファイル: gsocket.c プロジェクト: EdgarTx/wx
/* GSocket_Connect:
 *  For stream (connection oriented) sockets, GSocket_Connect() tries
 *  to establish a client connection to a server using the peer address
 *  as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
 *  connection has been successfully established, or one of the error
 *  codes listed below. Note that for nonblocking sockets, a return
 *  value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
 *  request can be completed later; you should use GSocket_Select()
 *  to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
 *  corresponding asynchronous events.
 *
 *  For datagram (non connection oriented) sockets, GSocket_Connect()
 *  just sets the peer address established with GSocket_SetPeer() as
 *  default destination.
 *
 *  Error codes:
 *    GSOCK_INVSOCK    - the socket is in use or not valid.
 *    GSOCK_INVADDR    - the peer address has not been established.
 *    GSOCK_TIMEDOUT   - timeout, the connection failed.
 *    GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
 *    GSOCK_MEMERR     - couldn't allocate memory.
 *    GSOCK_IOERR      - low-level error.
 */
GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
{
  InetAddress addr ;
  TEndpointInfo	info;
   OSStatus		err = kOTNoError;
  TCall peer ;

  assert(sck != NULL);

  /* Enable CONNECTION events (needed for nonblocking connections) */
  sck->m_detected &= ~GSOCK_CONNECTION_FLAG;

  if (sck->m_endpoint != kOTInvalidEndpointRef )
  {
    sck->m_error = GSOCK_INVSOCK;
    return GSOCK_INVSOCK;
  }

  if (!sck->m_peer)
  {
    sck->m_error = GSOCK_INVADDR;
    return GSOCK_INVADDR;
  }

  /* Streamed or dgram socket? */
  sck->m_stream   = (stream == GSOCK_STREAMED);
  sck->m_oriented = TRUE;
  sck->m_server   = FALSE;

  /* Create the socket */
#if TARGET_CARBON
  sck->m_endpoint =
  	OTOpenEndpointInContext( OTCreateConfiguration( kTCPName) , 0 , &info , &err , NULL ) ;
#else
  sck->m_endpoint =
  	OTOpenEndpoint( OTCreateConfiguration( kTCPName) , 0 , &info , &err ) ;
#endif
  if ( sck->m_endpoint == kOTInvalidEndpointRef || err != kOTNoError )
  {
		sck->m_endpoint = kOTInvalidEndpointRef ;
    	sck->m_error = GSOCK_IOERR;
    	return GSOCK_IOERR;
  }
  err = OTBind( sck->m_endpoint , nil , nil ) ;
  if ( err != kOTNoError )
  {
    	return GSOCK_IOERR;
  }
  SetDefaultEndpointModes( sck->m_endpoint , sck ) ;
// TODO
#if 0
  ioctl(sck->m_endpoint, FIONBIO, &arg);
#endif
  _GSocket_Enable_Events(sck);

  _GAddress_translate_to( sck->m_peer , &addr ) ;
  memset( &peer , 0 , sizeof( TCall ) ) ;
  peer.addr.len = sizeof( InetAddress ) ;
  peer.addr.buf = (unsigned char*) &addr ;
  err = OTConnect( sck->m_endpoint , &peer , nil ) ;
  if ( err != noErr )
  {
    /* If connect failed with EINPROGRESS and the GSocket object
     * is in blocking mode, we select() for the specified timeout
     * checking for writability to see if the connection request
     * completes.
     */
	
    if ((err == kOTNoDataErr ) && (!sck->m_non_blocking))
    {
      if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
      {
      	OTSndOrderlyDisconnect( sck->m_endpoint ) ;
        sck->m_endpoint = kOTInvalidEndpointRef ;
        /* sck->m_error is set in _GSocket_Output_Timeout */
        return GSOCK_TIMEDOUT;
      }
      else
      {
/*
        int error;
        WX_SOCKLEN_T len = sizeof(error);

        getsockopt(sck->m_endpoint, SOL_SOCKET, SO_ERROR, (void*) &error, &len);

        if (!error)
*/
          return GSOCK_NOERROR;
      }
    }

    /* If connect failed with EINPROGRESS and the GSocket object
     * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
     * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
     * this way if the connection completes, a GSOCK_CONNECTION
     * event will be generated, if enabled.
     */
    if ((err == kOTNoDataErr) && (sck->m_non_blocking))
    {
      sck->m_error = GSOCK_WOULDBLOCK;
      return GSOCK_WOULDBLOCK;
    }

    /* If connect failed with an error other than EINPROGRESS,
     * then the call to GSocket_Connect has failed.
     */
    OTSndOrderlyDisconnect( sck->m_endpoint ) ;

    sck->m_endpoint = kOTInvalidEndpointRef ;
    sck->m_error = GSOCK_IOERR;
    return GSOCK_IOERR;
  }
//  OTInetEventHandler(sck, T_CONNECT , kOTNoError , NULL ) ;
  return GSOCK_NOERROR;
}
コード例 #13
0
ファイル: SDLnetTCP.c プロジェクト: 00wendi00/MyProject
/* 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;	
}
コード例 #14
0
pascal void
EndpointHander::Notifier(
	void		*contextPtr,
	OTEventCode code,
	OTResult	result,
	void		*cookie)
{
	NMErr status;
	DEBUG_ENTRY_EXIT("EndpointHander::Notifier");
	EndpointHander *epHander = (EndpointHander *) contextPtr;

	UNUSED_PARAMETER(result);

	switch (code)
	{
		case T_OPENCOMPLETE:		// one of our endpoints finished opening
		
			//if we were waiting on the stream ep, move on to the datagram ep if necessary
			if (!(epHander->mState & kGotStreamEP))
			{
				epHander->mNewEP->mStreamEndpoint->mEP = (EndpointRef)cookie;	
				epHander->mState |= kGotStreamEP;
				if (!(epHander->mState & kGotDatagramEP))
				{
					OTAsyncOpenEndpoint(OTCreateConfiguration(epHander->mListenerEP->GetDatagramProtocolName()), 0, NULL, epHander->mNotifier.fUPP, contextPtr);
				}
			}
			//it must be our datagram ep that's done
			else
			{
				epHander->mNewEP->mDatagramEndpoint->mEP = (EndpointRef)cookie;		
				epHander->mState |= kGotDatagramEP;				
			}
			
			//once both eps are done, we go ahead and bind
			if ((epHander->mState & kGotStreamEP) && (epHander->mState & kGotDatagramEP))
			{
				//	Bind the endpoint.  Execution continues in the notifier for T_BINDCOMPLETE
				epHander->mBindReq.addr.len = 0;
				epHander->mBindReq.addr.buf = NULL;
				epHander->mBindRet.addr = epHander->mNewEP->mDatagramEndpoint->mLocalAddress;

				//ECF011114 caused problems under MacOSX...
				status = OTBind(epHander->mNewEP->mDatagramEndpoint->mEP, NULL, &epHander->mBindRet);			
				//status = OTBind(epHander->mNewEP->mDatagramEndpoint->mEP, &epHander->mBindReq, &epHander->mBindRet);
				DEBUG_NETWORK_API(epHander->mNewEP->mDatagramEndpoint->mEP, "OTBind", status);								
			}
			break;
			
		case T_BINDCOMPLETE:		// The datagram endpoint has finished
			epHander->mState |= kDatagramDone;
			
			//	by this time, we should have both endpoints ready to go
			op_assert(epHander->mState & (kStreamDone | kDatagramDone) == (kStreamDone | kDatagramDone));
			
			//	we got the local address from the bind
			epHander->mState |= kDatagramLocalAddr;
			
			//	Now that everything is ready, accept the connection
			epHander->Finish();
			break;

		default:
			break;
	}
}
コード例 #15
0
NMErr
EndpointHander::GetDatagramEP(void)
{
	DEBUG_ENTRY_EXIT("EndpointHander::GetDatagramEP");

	CachedEP		*datagramEP = NULL;
	OTLink			*acceptorLink = NULL;
	NMErr		status = kNMNoError;

	//	if we're not in uber mode, there should be no datagram ep
	//	just jump to the notifier
	if (mNewEP->mMode != kNMNormalMode)
	{
		Notifier(this, T_BINDCOMPLETE, kNMNoError, NULL);
		return kNMNoError;
	}
		
	//Try_
	{
		//	Get a datagram endpoint from the cache
		acceptorLink = OTLIFODequeue(&OTEndpoint::sDatagramEPCache.Q);
		if (acceptorLink)
		{
			OTAtomicAdd32(-1, &OTEndpoint::sDatagramEPCache.readyCount);
			OTAtomicAdd32(-1, &OTEndpoint::sDatagramEPCache.totalCount);
			
			//jacked up and good to go
			mState |= kGotDatagramEP;
			
			//get the cache reloading itself
			OTEndpoint::ServiceEPCaches();
		}
		//if we couldn't get one off the cache, we'll make one after we have a stream endpoint
		// (one at a time for simplicity)
		else
		{
			if (mState & kGotStreamEP)
			{
				return OTAsyncOpenEndpoint(OTCreateConfiguration(mListenerEP->GetDatagramProtocolName()), 0, NULL, mNotifier.fUPP, this);
			}
			return kNMNoError; //we just wait for the stream endpoint to get done
		}

		//	Get the pointer to the cached ep object
		datagramEP = OTGetLinkObject(acceptorLink, CachedEP, link);
		op_assert(datagramEP != NULL);
		
		//	Remove the notifier that was being used for cacheing and install the "normal" one
		OTRemoveNotifier(datagramEP->ep);
		OTInstallNotifier(datagramEP->ep, mNotifier.fUPP, this);

		mNewEP->mDatagramEndpoint->mEP = datagramEP->ep;
		
		delete datagramEP;
		
		//if we got both endpoints, go ahead and bind here
		if (mState & kGotStreamEP)
		{
			//	Bind the endpoint.  Execution continues in the notifier for T_BINDCOMPLETE
			mBindReq.addr.len = 0;
			mBindReq.addr.buf = NULL;
			mBindRet.addr = mNewEP->mDatagramEndpoint->mLocalAddress;

			status = OTBind(mNewEP->mDatagramEndpoint->mEP,NULL, &mBindRet);
			//status = OTBind(mNewEP->mDatagramEndpoint->mEP,&mBindReq, &mBindRet);

			DEBUG_NETWORK_API(mNewEP->mDatagramEndpoint->mEP, "OTBind", status);					
			//ThrowIfOSErr_(status);
			if (status)
				goto error;
		}
	}
	//Catch_(code)
	error:
	if (status)
	{
		NMErr code = status;
		return code;
	}
	
	return kNMNoError;
}
コード例 #16
0
ファイル: SDLnetUDP.c プロジェクト: OS2World/LIB-SDL
/* Open a UDP network socket
   If 'port' is non-zero, the UDP socket is bound to a fixed local port.
*/
extern UDPsocket SDLNet_UDP_Open(Uint16 port)
{
	UDPsocket sock;
#ifdef MACOS_OPENTRANSPORT
	EndpointRef dummy = NULL;
#endif

	/* Allocate a UDP socket structure */
	sock = (UDPsocket)malloc(sizeof(*sock));
	if ( sock == NULL ) {
		SDLNet_SetError("Out of memory");
		goto error_return;
	}
	memset(sock, 0, sizeof(*sock));
	
	/* Open the socket */
#ifdef MACOS_OPENTRANSPORT
	{
		sock->error = OTAsyncOpenEndpoint(
			OTCreateConfiguration(kUDPName),0, &(sock->info),
			(OTNotifyProcPtr)AsyncUDPNotifier, sock );
		AsyncUDPPopEvent( sock );
		while( !sock->error && !( sock->completion & CompleteMask(T_OPENCOMPLETE)))
		{
			AsyncUDPPopEvent( sock );
		}
		if( sock->error )
		{
			SDLNet_SetError("Could not open UDP socket");
			goto error_return;
		}
		// Should we ??
		// (01/05/03 minami<*****@*****.**>
		OTSetBlocking( sock->channel );
	}
#else
	sock->channel = socket(AF_INET, SOCK_DGRAM, 0);
#endif /* MACOS_OPENTRANSPORT */

	if ( sock->channel == INVALID_SOCKET ) 
	{
		SDLNet_SetError("Couldn't create socket");
		goto error_return;
	}

#ifdef MACOS_OPENTRANSPORT
	{
	InetAddress required, assigned;
	TBind req_addr, assigned_addr;
	OSStatus status;
	InetInterfaceInfo info;
		
		memset(&assigned_addr, 0, sizeof(assigned_addr));
		assigned_addr.addr.maxlen = sizeof(assigned);
		assigned_addr.addr.len = sizeof(assigned);
		assigned_addr.addr.buf = (UInt8 *) &assigned;
		
		if ( port ) {
			status = OTInetGetInterfaceInfo( &info, kDefaultInetInterface );
			if( status != kOTNoError )
				goto error_return;
			OTInitInetAddress(&required, port, info.fAddress );
			req_addr.addr.maxlen = sizeof( required );
			req_addr.addr.len = sizeof( required );
			req_addr.addr.buf = (UInt8 *) &required;
		
			sock->error = OTBind(sock->channel, &req_addr, &assigned_addr);
		} else {
			sock->error = OTBind(sock->channel, nil, &assigned_addr );
		}
		AsyncUDPPopEvent(sock);

		while( !sock->error && !(sock->completion & CompleteMask(T_BINDCOMPLETE)))
		{
			AsyncUDPPopEvent(sock);
		}	
		if (sock->error != noErr)
		{
			SDLNet_SetError("Couldn't bind to local port, OTBind() = %d",(int) status);
			goto error_return;
		}

		sock->address.host = assigned.fHost;
		sock->address.port = assigned.fPort;
		
#ifdef DEBUG_NET
		printf("UDP open host = %d, port = %d\n", assigned.fHost, assigned.fPort );
#endif
	}
#else
	/* Bind locally, if appropriate */
	if ( port )
	{
		struct sockaddr_in sock_addr;
		memset(&sock_addr, 0, sizeof(sock_addr));
		sock_addr.sin_family = AF_INET;
		sock_addr.sin_addr.s_addr = INADDR_ANY;
		sock_addr.sin_port = SDL_SwapBE16(port);

		/* Bind the socket for listening */
		if ( bind(sock->channel, (struct sockaddr *)&sock_addr,
				sizeof(sock_addr)) == SOCKET_ERROR ) {
			SDLNet_SetError("Couldn't bind to local port");
			goto error_return;
		}
		/* Fill in the channel host address */
		sock->address.host = sock_addr.sin_addr.s_addr;
		sock->address.port = sock_addr.sin_port;
	}

	/* Allow LAN broadcasts with the socket */
	{ int yes = 1;
		setsockopt(sock->channel, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(yes));
	}
#endif /* MACOS_OPENTRANSPORT */

	/* The socket is ready */
	
	return(sock);

error_return:
#ifdef MACOS_OPENTRANSPORT
	if( dummy )
		OTCloseProvider( dummy );
#endif
	SDLNet_UDP_Close(sock);
	
	return(NULL);
}
コード例 #17
0
ファイル: chuukei.c プロジェクト: erikbroo/chengband
int connect_chuukei_server(char *prf_name)
{
#ifndef MACINTOSH

#ifdef WINDOWS
	WSADATA wsaData;
	WORD wVersionRequested = (WORD) (( 1) |  ( 1 << 8));
#endif

	struct sockaddr_in ask;
	struct hostent *hp;

	if (read_chuukei_prf(prf_name) < 0)
	{
		printf("Wrong prf file\n");
		return (-1);
	}

	if (init_buffer() < 0)
	{
		printf("Malloc error\n");
		return (-1);
	}

#ifdef WINDOWS
	if (WSAStartup(wVersionRequested, &wsaData))
	{
		msg_print("Report: WSAStartup failed.");
		return (-1);
	}
#endif

	printf("server = %s\nport = %d\n", server_name, server_port);

	if ((hp = gethostbyname(server_name)) != NULL)
	{
		memset(&ask, 0, sizeof(ask));
		memcpy(&ask.sin_addr, hp->h_addr_list[0], hp->h_length);
	}
	else
	{
		if ((ask.sin_addr.s_addr=inet_addr(server_name)) == 0)
		{
			printf("Bad hostname\n");
			return (-1);
		}
	}

	ask.sin_family = AF_INET;
	ask.sin_port = htons((unsigned short)server_port);

#ifndef WINDOWS
	if ((sd=socket(PF_INET,SOCK_STREAM, 0)) < 0)
#else
	if ((sd=socket(PF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET)
#endif
	{
		printf("Can't create socket\n");
		return (-1);
	}

	if (connect(sd, (struct sockaddr *)&ask, sizeof(ask)) < 0)
	{
		close(sd);
		printf("Can't connect %s port %d\n", server_name, server_port);
		return (-1);
	}

	return (0);
#else	/* MACINTOSH */
	OSStatus err;
	InetHostInfo 	response;
	InetHost 		host_addr;
	InetAddress 	inAddr;
	TCall 			sndCall;
	Boolean			bind	= false;
	OSStatus 	junk;

	if (read_chuukei_prf(prf_name) < 0){
		printf("Wrong prf file\n");
		return (-1);
	}
	
	init_buffer();
	
	printf("server = %s\nport = %d\n", server_name, server_port);


#if TARGET_API_MAC_CARBON
	err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
#else
	err = InitOpenTransport();
#endif

	memset(&response, 0, sizeof(response));


#if TARGET_API_MAC_CARBON
	inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
#else
	inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
#endif
	
	if (err == noErr) {
		err = OTInetStringToAddress(inet_services, (char *)server_name, &response);
		
		if (err == noErr) {
			host_addr = response.addrs[0];
		} else {
			printf("Bad hostname\n");
		}
		
#if TARGET_API_MAC_CARBON
		ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
#else
		ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
#endif

		if (err == noErr) {
			err = OTBind(ep, nil, nil);
			bind = (err == noErr);
	    }
	    if (err == noErr){
		OTInitInetAddress(&inAddr, server_port, host_addr);
			
			sndCall.addr.len 	= sizeof(InetAddress);				
			sndCall.addr.buf	= (unsigned char*) &inAddr;
			sndCall.opt.buf 	= nil;		/* no connection options */
			sndCall.opt.len 	= 0;
			sndCall.udata.buf 	= nil;		/* no connection data */
			sndCall.udata.len 	= 0;
			sndCall.sequence 	= 0;		/* ignored by OTConnect */
			
			err = OTConnect(ep, &sndCall, NULL);
			
			if( err != noErr ){
				printf("Can't connect %s port %d\n", server_name, server_port);
			}
		}
		
		err = OTSetSynchronous(ep);
		if (err == noErr)		
			err = OTSetBlocking(ep);
		
	}
	
	if( err != noErr ){
		if( bind ){
			OTUnbind(ep);
		}
		/* Clean up. */
		if (ep != kOTInvalidEndpointRef) {
			OTCloseProvider(ep);
			ep = nil;
		}
		if (inet_services != nil) {
			OTCloseProvider(inet_services);
			inet_services = nil;
		}
	
		return -1;
	}
	
	return 0;

#endif
}