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 */ }
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; } }