Exemplo n.º 1
0
int
ACE_TLI_Connector::complete (ACE_TLI_Stream &new_stream,
                             ACE_Addr *remote_sap,
                             ACE_Time_Value *tv)
{
  ACE_TRACE ("ACE_TLI_Connector::complete");
#if defined (ACE_WIN32)
   if (WaitForSingleObject (new_stream.get_handle(), tv->msec()) == WAIT_OBJECT_0)
    {
      if (ACE_OS::t_look (new_stream.get_handle()) == T_CONNECT)
        return t_rcvconnect (new_stream.get_handle(), 0);
      else
        return -1;
    }
  else
    return -1;
#else
  ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
                                             tv,
                                             1);
  if (h == ACE_INVALID_HANDLE)
    {
      new_stream.close ();
      return -1;
    }
  else    // We've successfully connected!
    {
      if (remote_sap != 0)
        {
#if defined (ACE_HAS_XTI) || defined (ACE_HAS_SVR4_TLI)
          struct netbuf name;

          name.maxlen = remote_sap->get_size ();
          name.buf    = (char *) remote_sap->get_addr ();

          if (ACE_OS::t_getname (new_stream.get_handle (),
                                 &name,
                                 REMOTENAME) == -1)
#else /* SunOS4 */
          if (0)
#endif /* ACE_HAS_XTI || ACE_HAS_SVR4_TLI */
            {
              new_stream.close ();
              return -1;
            }
        }

      // Start out with non-blocking disabled on the <new_stream>.
      new_stream.disable (ACE_NONBLOCK);

      return 0;
    }
#endif /* ACE_WIN32 */
}
Exemplo n.º 2
0
Arquivo: nwio.c Projeto: DeadZen/qse
int qse_nwio_init (
	qse_nwio_t* nwio, qse_mmgr_t* mmgr, const qse_nwad_t* nwad, 
	int flags, const qse_nwio_tmout_t* tmout)
{
	qse_skad_t addr;
	qse_sck_len_t addrlen;
	int family, type, tmp;

	QSE_MEMSET (nwio, 0, QSE_SIZEOF(*nwio));
	nwio->mmgr = mmgr;
	nwio->flags = flags;
	nwio->errnum = QSE_NWIO_ENOERR;
	if (tmout) nwio->tmout = *tmout;
	else
	{
		nwio->tmout.r.sec = -1;
		nwio->tmout.w.sec = -1;
		nwio->tmout.c.sec = -1;
		nwio->tmout.a.sec = -1;
	}

	tmp = qse_nwadtoskad (nwad, &addr);
	if (tmp <= -1) 
	{
		nwio->errnum = QSE_NWIO_EINVAL;
		return -1;
	}
	addrlen = tmp;

#if defined(SOCK_STREAM) && defined(SOCK_DGRAM)
	if (flags & QSE_NWIO_TCP) type = SOCK_STREAM;
	else if (flags & QSE_NWIO_UDP) type = SOCK_DGRAM;
	else
#endif
	{
		nwio->errnum = QSE_NWIO_EINVAL;
		return -1;
	}

	family = qse_skadfamily (&addr);

#if defined(_WIN32)
	nwio->handle = socket (family, type, 0);
	if (nwio->handle == INVALID_SOCKET)
	{
		nwio->errnum = skerr_to_errnum (WSAGetLastError());
		goto oops;
	}

	if ((flags & QSE_NWIO_TCP) && (flags & QSE_NWIO_KEEPALIVE))
	{
		int optval = 1;
		setsockopt (nwio->handle, SOL_SOCKET, SO_KEEPALIVE, (void*)&optval, QSE_SIZEOF(optval));
	}

	if (flags & QSE_NWIO_PASSIVE)
	{
		qse_nwio_hnd_t handle;

		if (flags & QSE_NWIO_REUSEADDR)
		{
			int optval = 1;
			setsockopt (nwio->handle, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, QSE_SIZEOF(optval));
		}

		if (bind (nwio->handle, (struct sockaddr*)&addr, addrlen) == SOCKET_ERROR)
		{
			nwio->errnum = skerr_to_errnum (WSAGetLastError());
			goto oops;
		}

		if (flags & QSE_NWIO_TCP)
		{
			if (listen (nwio->handle, 10) == SOCKET_ERROR)
			{
				nwio->errnum = skerr_to_errnum (WSAGetLastError());
				goto oops;
			}

			if (TMOUT_ENABLED(nwio->tmout.a) &&
			    wait_for_data (nwio, &nwio->tmout.a, 0) <= -1) goto oops;

			handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
			if (handle == INVALID_SOCKET)
			{
				nwio->errnum = skerr_to_errnum (WSAGetLastError());
				goto oops;
			}

			closesocket (nwio->handle);
			nwio->handle = handle;
		}
		else if (flags & QSE_NWIO_UDP)
		{
			nwio->status |= STATUS_UDP_CONNECT;
		}
	}
	else
	{
		int xret;

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			unsigned long cmd = 1;

			if (ioctlsocket(nwio->handle, FIONBIO, &cmd) == SOCKET_ERROR) 
			{
				nwio->errnum = skerr_to_errnum (WSAGetLastError());
				goto oops;
			}
		}

		xret = connect (nwio->handle, (struct sockaddr*)&addr, addrlen);

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			unsigned long cmd = 0;
			
			if ((xret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) ||
			    ioctlsocket (nwio->handle, FIONBIO, &cmd) == SOCKET_ERROR)
			{
				nwio->errnum = skerr_to_errnum (WSAGetLastError());
				goto oops;
			}

			if (wait_for_data (nwio, &nwio->tmout.c, 1) <= -1) goto oops;
			else 
			{
				int xlen;
				DWORD xerr;

				xlen = QSE_SIZEOF(xerr);
				if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xerr, &xlen) == SOCKET_ERROR)
				{
					nwio->errnum = skerr_to_errnum (WSAGetLastError());
					goto oops;
				}
				else if (xerr != 0)
				{
					nwio->errnum = skerr_to_errnum (xerr);
					goto oops;
				}
			}
		}
		else
		{
			if (xret == SOCKET_ERROR)
			{
				nwio->errnum = skerr_to_errnum (WSAGetLastError());
				goto oops;
			}
		}
	}

#elif defined(__OS2__)
	nwio->handle = socket (family, type, 0);
	if (nwio->handle <= -1)
	{
		nwio->errnum = skerr_to_errnum (sock_errno());
		goto oops;
	}

	if ((flags & QSE_NWIO_TCP) && (flags & QSE_NWIO_KEEPALIVE))
	{
		int optval = 1;
		setsockopt (nwio->handle, SOL_SOCKET, SO_KEEPALIVE, (void*)&optval, QSE_SIZEOF(optval));
	}

	if (flags & QSE_NWIO_PASSIVE)
	{
		qse_nwio_hnd_t handle;

		if (flags & QSE_NWIO_REUSEADDR)
		{
			int optval = 1;
			setsockopt (nwio->handle, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, QSE_SIZEOF(optval));
		}

		if (bind (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1)
		{
			nwio->errnum = skerr_to_errnum (sock_errno());
			goto oops;
		}

		if (flags & QSE_NWIO_TCP)
		{
			if (listen (nwio->handle, 10) <= -1)
			{
				nwio->errnum = skerr_to_errnum (sock_errno());
				goto oops;
			}

			if (TMOUT_ENABLED(nwio->tmout.a) &&
			    wait_for_data (nwio, &nwio->tmout.a, 0) <= -1) goto oops;

			handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
			if (handle <= -1)
			{
				nwio->errnum = skerr_to_errnum (sock_errno());
				goto oops;
			}

			soclose (nwio->handle);
			nwio->handle = handle;
		}
		else if (flags & QSE_NWIO_UDP)
		{
			nwio->status |= STATUS_UDP_CONNECT;
		}
	}
	else
	{
		int xret;

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			int noblk = 1;

			if (ioctl (nwio->handle, FIONBIO, (void*)&noblk, QSE_SIZEOF(noblk)) <= -1)
			{
				nwio->errnum = skerr_to_errnum (sock_errno());
				goto oops;
			}
		}

		xret = connect (nwio->handle, (struct sockaddr*)&addr, addrlen);

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			int noblk = 0;
			
			if ((xret <= -1 && sock_errno() != SOCEINPROGRESS) ||
			    ioctl (nwio->handle, FIONBIO, (void*)&noblk, QSE_SIZEOF(noblk)) <= -1)
			{
				nwio->errnum = skerr_to_errnum (sock_errno());
				goto oops;
			}

			if (wait_for_data (nwio, &nwio->tmout.c, 1) <= -1) goto oops;
			else 
			{
				int xlen, xerr;

				xlen = QSE_SIZEOF(xerr);
				if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xerr, &xlen) <= -1)
				{
					nwio->errnum = skerr_to_errnum (sock_errno());
					goto oops;
				}
				else if (xerr != 0)
				{
					nwio->errnum = skerr_to_errnum (xerr);
					goto oops;
				}
			}
		}
		else
		{
			if (xret <= -1)
			{
				nwio->errnum = skerr_to_errnum (sock_errno());
				goto oops;
			}
		}
	}

#elif defined(__DOS__)

	nwio->handle = socket (family, type, 0);
	if (nwio->handle <= -1)
	{
		nwio->errnum = skerr_to_errnum (errno);
		goto oops;
	}

	if ((flags & QSE_NWIO_TCP) && (flags & QSE_NWIO_KEEPALIVE))
	{
		int optval = 1;
		setsockopt (nwio->handle, SOL_SOCKET, SO_KEEPALIVE, (void*)&optval, QSE_SIZEOF(optval));
	}

	if (flags & QSE_NWIO_PASSIVE)
	{
		qse_nwio_hnd_t handle;

	#if defined(SO_REUSEADDR)
		if (flags & QSE_NWIO_REUSEADDR)
		{
			int optval = 1;
			setsockopt (nwio->handle, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, QSE_SIZEOF(optval));
		}
	#endif

		if (bind (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1)
		{
			nwio->errnum = skerr_to_errnum (errno);
			goto oops;
		}

		if (flags & QSE_NWIO_TCP)
		{
			if (listen (nwio->handle, 10) <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}

			if (TMOUT_ENABLED(nwio->tmout.a) &&
			    wait_for_data (nwio, &nwio->tmout.a, 0) <= -1) goto oops;

			handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
			if (handle <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}

			close_s (nwio->handle);
			nwio->handle = handle;
		}
		else if (flags & QSE_NWIO_UDP)
		{
			nwio->status |= STATUS_UDP_CONNECT;
		}
	}
	else
	{
		int xret;

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			int cmd = 1;

			if (ioctlsocket(nwio->handle, FIONBIO, (char*)&cmd) == SOCKET_ERROR) 
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}
		}

		xret = connect (nwio->handle, (struct sockaddr*)&addr, addrlen);

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			int cmd = 0;

			if ((xret == SOCKET_ERROR && errno != EWOULDBLOCK) ||
			    ioctlsocket (nwio->handle, FIONBIO, (char*)&cmd) == SOCKET_ERROR)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}

			if (wait_for_data (nwio, &nwio->tmout.c, 1) <= -1) goto oops;
			else 
			{
				int xlen, xerr;

				xlen = QSE_SIZEOF(xerr);
				if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xerr, &xlen) <= -1)
				{
					nwio->errnum = skerr_to_errnum (errno);
					goto oops;
				}
				else if (xerr != 0)
				{
					nwio->errnum = skerr_to_errnum (xerr);
					goto oops;
				}
			}
		}
		else
		{
			if (xret <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}
		}
	}

#elif defined(USE_TLI)

	{

		static const qse_mchar_t* dev_path[2][2] = 
		{
			{ "/dev/tcp", "/dev/inet/tcp" },
			{ "/dev/udp", "/dev/inet/tcp" }
		};
		int dev_id;

		if (flags & QSE_NWIO_TCP) dev_id = 0;
		else 
		{
			QSE_ASSERT (flags & QSE_NWIO_UDP);
			dev_id = 1;
		}

		nwio->handle = t_open (dev_path[dev_id][0], O_RDWR, QSE_NULL);
		if (nwio->handle <= -1)
		{
			nwio->handle = t_open (dev_path[dev_id][1], O_RDWR, QSE_NULL);
			if (nwio->handle <= -1)
			{
				nwio->errnum = tlierr_to_errnum (t_errno, errno);
				goto oops;
			}
		}

		if (flags & QSE_NWIO_PASSIVE)
		{
			/* TODO: */
			nwio->errnum = QSE_NWIO_ENOIMPL;
			goto oops;
		}
		else
		{
			struct t_call call; /* for connecting */
			struct t_bind req, ret; /* for binding */
			qse_skad_t reqaddr, retaddr;
			qse_nwad_t reqnwad;

			/*
			call = t_alloc (nwio->handle, T_CALL, T_ADDR);
			if (!call)
			{
				nwio->errnum = tlierr_to_errnum (t_errno, errno);
				goto oops;
			}*/

			qse_clearnwad (&reqnwad, nwad->type);
			qse_nwadtoskad (&reqnwad, &reqaddr);

			QSE_MEMSET (&ret, 0, QSE_SIZEOF(req));
			req.addr.maxlen = addrlen;
			req.addr.len = addrlen;
			req.addr.buf = &reqaddr;

			QSE_MEMSET (&ret, 0, QSE_SIZEOF(ret));
			ret.addr.maxlen = addrlen;
			ret.addr.len = addrlen;
			ret.addr.buf = &retaddr;

			if (t_bind (nwio->handle, &req, &ret) <= -1)
			{
				nwio->errnum = tlierr_to_errnum (t_errno, errno);
				goto oops;
			}

/* TODO: should i use t_alloc() and t_free for call, ret, req? */
			QSE_MEMSET (&call, 0, QSE_SIZEOF(call));
			call.addr.maxlen = addrlen;
			call.addr.len = addrlen;
			call.addr.buf = &addr;

			if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
			{
				int orgfl;

				orgfl = fcntl (nwio->handle, F_GETFL, 0);
				if (orgfl <= -1 || fcntl (nwio->handle, F_SETFL, orgfl | O_NONBLOCK) <= -1)
				{
					nwio->errnum = skerr_to_errnum (errno);
					goto oops;
				}

				if (t_connect (nwio->handle, &call, 0) <= -1)
				{
					if (t_errno != TNODATA)
					{
						nwio->errnum = tlierr_to_errnum (t_errno, errno);
						goto oops;
					}

			/* TODO: this doesn't seem to work wel... REDO THE WORK */
					if (wait_for_data (nwio, &nwio->tmout.c, 0) <= -1) goto oops;

					if (t_rcvconnect (nwio->handle, QSE_NULL) <= -1)
					{
						nwio->errnum = tlierr_to_errnum (t_errno, errno);
						goto oops;
					}
				}

				if (fcntl (nwio->handle, F_SETFL, orgfl) <= -1) 
				{
					nwio->errnum = skerr_to_errnum (errno);
					goto oops;
				}
			}
			else
			{
				if (t_connect (nwio->handle, &call, 0) <= -1)
				{
					nwio->errnum = tlierr_to_errnum (t_errno, errno);
					goto oops;
				}
			}
		}
	}

#else
	#if defined(SOCK_CLOEXEC)
	nwio->handle = socket (family, type | SOCK_CLOEXEC, 0);
	#else
	nwio->handle = socket (family, type, 0);
	#endif
	if (nwio->handle <= -1)
	{
		nwio->errnum = skerr_to_errnum (errno);
		goto oops;
	}

	#if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC)
	{ 
		int tmp = fcntl (nwio->handle, F_GETFD);
		if (tmp >= 0) fcntl (nwio->handle, F_SETFD, tmp | FD_CLOEXEC);
	}
	#endif

	if ((flags & QSE_NWIO_TCP) && (flags & QSE_NWIO_KEEPALIVE))
	{
		int optval = 1;
		setsockopt (nwio->handle, SOL_SOCKET, SO_KEEPALIVE, (void*)&optval, QSE_SIZEOF(optval));
	}

	if (flags & QSE_NWIO_PASSIVE)
	{
		qse_nwio_hnd_t handle;

	#if defined(SO_REUSEADDR)
		if (flags & QSE_NWIO_REUSEADDR)
		{
			int optval = 1;
			setsockopt (nwio->handle, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, QSE_SIZEOF(optval));
		}
	#endif

		if (bind (nwio->handle, (struct sockaddr*)&addr, addrlen) <= -1)
		{
			nwio->errnum = skerr_to_errnum (errno);
			goto oops;
		}

		if (flags & QSE_NWIO_TCP)
		{
			if (listen (nwio->handle, 10) <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}

			if (TMOUT_ENABLED(nwio->tmout.a) &&
			    wait_for_data (nwio, &nwio->tmout.a, 0) <= -1) goto oops;

			handle = accept (nwio->handle, (struct sockaddr*)&addr, &addrlen);
			if (handle <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}

			qse_closesckhnd (nwio->handle); /* close the listening socket */
			nwio->handle = handle; /* set the handle to the accepted socket */
		}
		else if (flags & QSE_NWIO_UDP)
		{
			nwio->status |= STATUS_UDP_CONNECT;
		}
	}
	else
	{
		int xret;

		if (TMOUT_ENABLED(nwio->tmout.c) && (flags & QSE_NWIO_TCP))
		{
			int orgfl;

			orgfl = fcntl (nwio->handle, F_GETFL, 0);
			if (orgfl <= -1 || fcntl (nwio->handle, F_SETFL, orgfl | O_NONBLOCK) <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}
		
			xret = connect (nwio->handle, (struct sockaddr*)&addr, addrlen);
		
			if ((xret <= -1 && errno != EINPROGRESS) ||
			    fcntl (nwio->handle, F_SETFL, orgfl) <= -1) 
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}

			if (wait_for_data (nwio, &nwio->tmout.c, 1) <= -1) goto oops;
			else 
			{
				qse_sck_len_t xlen;
				xlen = QSE_SIZEOF(xret);
				if (getsockopt (nwio->handle, SOL_SOCKET, SO_ERROR, (char*)&xret, &xlen) <= -1)
				{
					nwio->errnum = skerr_to_errnum (errno);
					goto oops;
				}
				else if (xret != 0)
				{
					nwio->errnum = skerr_to_errnum (xret);
					goto oops;
				}
			}
		}
		else
		{
			xret = connect (nwio->handle, (struct sockaddr*)&addr, addrlen);
			if (xret <= -1)
			{
				nwio->errnum = skerr_to_errnum (errno);
				goto oops;
			}
		}
	}
#endif

	if (flags & QSE_NWIO_TEXT)
	{
		int topt = 0;

		if (flags & QSE_NWIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR;
		if (flags & QSE_NWIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH;

		nwio->tio = qse_tio_open (mmgr, QSE_SIZEOF(qse_nwio_t*), topt);
		if (nwio->tio == QSE_NULL)
		{
			nwio->errnum = QSE_NWIO_ENOMEM;
			goto oops;
		}

		/* store the back-reference to nwio in the extension area.*/
		*(qse_nwio_t**)QSE_XTN(nwio->tio) = nwio;

		if (qse_tio_attachin (nwio->tio, socket_input, QSE_NULL, 4096) <= -1 ||
		    qse_tio_attachout (nwio->tio, socket_output, QSE_NULL, 4096) <= -1)
		{
			if (nwio->errnum == QSE_NWIO_ENOERR) 
				nwio->errnum = tio_errnum_to_nwio_errnum (nwio->tio);
			goto oops;
		}
	}