Asynchronous connect (for non-blocking socket connect emulation)
This commit is contained in:
parent
a9a8299e88
commit
5f7b803dcd
2 changed files with 91 additions and 6 deletions
|
@ -36,6 +36,11 @@ typedef struct nwio_tcpcl
|
|||
long nwtcl_ttl;
|
||||
} nwio_tcpcl_t;
|
||||
|
||||
#define TCF_DEFAULT 0 /* Default parameters */
|
||||
#define TCF_ASYNCH 1 /* Asynchronous connect for non-blocking
|
||||
* socket emulation.
|
||||
*/
|
||||
|
||||
typedef struct nwio_tcpatt
|
||||
{
|
||||
long nwta_flags;
|
||||
|
|
|
@ -284,6 +284,13 @@ unsigned operations;
|
|||
return ENOTCONN; /* Is this right? */
|
||||
return resops;
|
||||
}
|
||||
if (tcp_fd->tf_flags & TFF_CONNECTING)
|
||||
{
|
||||
/* Special case for CONNECTING */
|
||||
if (operations & SR_SELECT_WRITE)
|
||||
tcp_fd->tf_flags |= TFF_SEL_WRITE;
|
||||
return 0;
|
||||
}
|
||||
if (operations & SR_SELECT_READ)
|
||||
{
|
||||
if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))
|
||||
|
@ -807,7 +814,12 @@ assert (conf_acc->acc_length == sizeof(*tcp_conf));
|
|||
break;
|
||||
case NWIOTCPCONN:
|
||||
if (tcp_fd->tf_flags & TFF_CONNECTING)
|
||||
assert(NOT_IMPLEMENTED);
|
||||
{
|
||||
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
|
||||
reply_thr_get (tcp_fd, EALREADY, TRUE);
|
||||
result= NW_OK;
|
||||
break;
|
||||
}
|
||||
if (tcp_fd->tf_flags & TFF_CONNECTEDx)
|
||||
{
|
||||
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
|
||||
|
@ -816,6 +828,8 @@ assert (conf_acc->acc_length == sizeof(*tcp_conf));
|
|||
break;
|
||||
}
|
||||
result= tcp_connect(tcp_fd);
|
||||
if (result == NW_OK)
|
||||
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
|
||||
break;
|
||||
case NWIOTCPLISTEN:
|
||||
case NWIOTCPLISTENQ:
|
||||
|
@ -1839,10 +1853,6 @@ tcp_conn_t *tcp_conn;
|
|||
return;
|
||||
}
|
||||
|
||||
assert(tcp_fd->tf_flags & TFF_IOCTL_IP);
|
||||
assert(tcp_fd->tf_ioreq == NWIOTCPLISTEN ||
|
||||
tcp_fd->tf_ioreq == NWIOTCPCONN);
|
||||
|
||||
if (tcp_conn->tc_state == TCS_CLOSED)
|
||||
{
|
||||
reply= tcp_conn->tc_error;
|
||||
|
@ -1855,6 +1865,28 @@ tcp_conn_t *tcp_conn;
|
|||
tcp_fd->tf_flags |= TFF_CONNECTEDx;
|
||||
reply= NW_OK;
|
||||
}
|
||||
|
||||
if (tcp_fd->tf_flags & TFF_CONNECTING)
|
||||
{
|
||||
/* Special code for asynchronous connects */
|
||||
tcp_fd->tf_flags &= ~TFF_CONNECTING;
|
||||
|
||||
/* Reply for select */
|
||||
if ((tcp_fd->tf_flags & TFF_SEL_WRITE) &&
|
||||
tcp_fd->tf_select_res)
|
||||
{
|
||||
tcp_fd->tf_flags &= ~TFF_SEL_WRITE;
|
||||
tcp_fd->tf_select_res(tcp_fd->tf_srfd,
|
||||
SR_SELECT_WRITE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
assert(tcp_fd->tf_flags & TFF_IOCTL_IP);
|
||||
assert(tcp_fd->tf_ioreq == NWIOTCPLISTEN ||
|
||||
tcp_fd->tf_ioreq == NWIOTCPCONN);
|
||||
|
||||
tcp_reply_ioctl (tcp_fd, reply);
|
||||
}
|
||||
|
||||
|
@ -1920,10 +1952,25 @@ int fd;
|
|||
assert(tcp_fd->tf_listenq[i] == NULL);
|
||||
}
|
||||
|
||||
if (tcp_fd->tf_flags & TFF_CONNECTING)
|
||||
{
|
||||
tcp_conn= tcp_fd->tf_conn;
|
||||
assert(tcp_conn != NULL);
|
||||
|
||||
assert (tcp_conn->tc_connInprogress);
|
||||
tcp_conn->tc_connInprogress= 0;
|
||||
tcp_conn->tc_fd= NULL;
|
||||
tcp_fd->tf_conn= NULL;
|
||||
tcp_close_connection(tcp_conn, ENOCONN);
|
||||
|
||||
tcp_fd->tf_flags &= ~TFF_CONNECTING;
|
||||
}
|
||||
|
||||
tcp_fd->tf_flags &= ~TFF_INUSE;
|
||||
if (!tcp_fd->tf_conn)
|
||||
return;
|
||||
|
||||
|
||||
tcp_conn= tcp_fd->tf_conn;
|
||||
assert(tcp_conn->tc_fd == tcp_fd);
|
||||
tcp_conn->tc_fd= NULL;
|
||||
|
@ -2020,6 +2067,10 @@ PRIVATE int tcp_connect(tcp_fd)
|
|||
tcp_fd_t *tcp_fd;
|
||||
{
|
||||
tcp_conn_t *tcp_conn;
|
||||
nwio_tcpcl_t *tcpcl;
|
||||
long nwtcl_flags;
|
||||
int r, do_asynch;
|
||||
acc_t *data;
|
||||
|
||||
if (!(tcp_fd->tf_flags & TFF_CONF_SET))
|
||||
{
|
||||
|
@ -2036,6 +2087,28 @@ tcp_fd_t *tcp_fd;
|
|||
return NW_OK;
|
||||
}
|
||||
|
||||
data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0,
|
||||
sizeof(*tcpcl), TRUE);
|
||||
if (!data)
|
||||
return EFAULT;
|
||||
|
||||
data= bf_packIffLess(data, sizeof(*tcpcl));
|
||||
assert (data->acc_length == sizeof(*tcpcl));
|
||||
tcpcl= (nwio_tcpcl_t *)ptr2acc_data(data);
|
||||
|
||||
nwtcl_flags= tcpcl->nwtcl_flags;
|
||||
bf_afree(data); data= NULL; tcpcl= NULL;
|
||||
|
||||
if (nwtcl_flags == TCF_ASYNCH)
|
||||
do_asynch= 1;
|
||||
else if (nwtcl_flags == TCF_DEFAULT)
|
||||
do_asynch= 0;
|
||||
else
|
||||
{
|
||||
tcp_reply_ioctl(tcp_fd, EINVAL);
|
||||
return NW_OK;
|
||||
}
|
||||
|
||||
assert(!tcp_fd->tf_conn);
|
||||
tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport,
|
||||
tcp_fd->tf_port->tp_ipaddr,
|
||||
|
@ -2060,7 +2133,14 @@ tcp_fd_t *tcp_fd;
|
|||
}
|
||||
tcp_fd->tf_conn= tcp_conn;
|
||||
|
||||
return tcp_su4connect(tcp_fd);
|
||||
r= tcp_su4connect(tcp_fd);
|
||||
if (r == NW_SUSPEND && do_asynch)
|
||||
{
|
||||
tcp_fd->tf_flags |= TFF_CONNECTING;
|
||||
tcp_reply_ioctl(tcp_fd, EINPROGRESS);
|
||||
r= NW_OK;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue