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;
|
long nwtcl_ttl;
|
||||||
} nwio_tcpcl_t;
|
} nwio_tcpcl_t;
|
||||||
|
|
||||||
|
#define TCF_DEFAULT 0 /* Default parameters */
|
||||||
|
#define TCF_ASYNCH 1 /* Asynchronous connect for non-blocking
|
||||||
|
* socket emulation.
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct nwio_tcpatt
|
typedef struct nwio_tcpatt
|
||||||
{
|
{
|
||||||
long nwta_flags;
|
long nwta_flags;
|
||||||
|
|
|
@ -284,6 +284,13 @@ unsigned operations;
|
||||||
return ENOTCONN; /* Is this right? */
|
return ENOTCONN; /* Is this right? */
|
||||||
return resops;
|
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 (operations & SR_SELECT_READ)
|
||||||
{
|
{
|
||||||
if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))
|
if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))
|
||||||
|
@ -807,7 +814,12 @@ assert (conf_acc->acc_length == sizeof(*tcp_conf));
|
||||||
break;
|
break;
|
||||||
case NWIOTCPCONN:
|
case NWIOTCPCONN:
|
||||||
if (tcp_fd->tf_flags & TFF_CONNECTING)
|
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)
|
if (tcp_fd->tf_flags & TFF_CONNECTEDx)
|
||||||
{
|
{
|
||||||
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
|
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
|
||||||
|
@ -816,6 +828,8 @@ assert (conf_acc->acc_length == sizeof(*tcp_conf));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result= tcp_connect(tcp_fd);
|
result= tcp_connect(tcp_fd);
|
||||||
|
if (result == NW_OK)
|
||||||
|
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
|
||||||
break;
|
break;
|
||||||
case NWIOTCPLISTEN:
|
case NWIOTCPLISTEN:
|
||||||
case NWIOTCPLISTENQ:
|
case NWIOTCPLISTENQ:
|
||||||
|
@ -1839,10 +1853,6 @@ tcp_conn_t *tcp_conn;
|
||||||
return;
|
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)
|
if (tcp_conn->tc_state == TCS_CLOSED)
|
||||||
{
|
{
|
||||||
reply= tcp_conn->tc_error;
|
reply= tcp_conn->tc_error;
|
||||||
|
@ -1855,6 +1865,28 @@ tcp_conn_t *tcp_conn;
|
||||||
tcp_fd->tf_flags |= TFF_CONNECTEDx;
|
tcp_fd->tf_flags |= TFF_CONNECTEDx;
|
||||||
reply= NW_OK;
|
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);
|
tcp_reply_ioctl (tcp_fd, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1920,10 +1952,25 @@ int fd;
|
||||||
assert(tcp_fd->tf_listenq[i] == NULL);
|
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;
|
tcp_fd->tf_flags &= ~TFF_INUSE;
|
||||||
if (!tcp_fd->tf_conn)
|
if (!tcp_fd->tf_conn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
tcp_conn= tcp_fd->tf_conn;
|
tcp_conn= tcp_fd->tf_conn;
|
||||||
assert(tcp_conn->tc_fd == tcp_fd);
|
assert(tcp_conn->tc_fd == tcp_fd);
|
||||||
tcp_conn->tc_fd= NULL;
|
tcp_conn->tc_fd= NULL;
|
||||||
|
@ -2020,6 +2067,10 @@ PRIVATE int tcp_connect(tcp_fd)
|
||||||
tcp_fd_t *tcp_fd;
|
tcp_fd_t *tcp_fd;
|
||||||
{
|
{
|
||||||
tcp_conn_t *tcp_conn;
|
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))
|
if (!(tcp_fd->tf_flags & TFF_CONF_SET))
|
||||||
{
|
{
|
||||||
|
@ -2036,6 +2087,28 @@ tcp_fd_t *tcp_fd;
|
||||||
return NW_OK;
|
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);
|
assert(!tcp_fd->tf_conn);
|
||||||
tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport,
|
tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport,
|
||||||
tcp_fd->tf_port->tp_ipaddr,
|
tcp_fd->tf_port->tp_ipaddr,
|
||||||
|
@ -2060,7 +2133,14 @@ tcp_fd_t *tcp_fd;
|
||||||
}
|
}
|
||||||
tcp_fd->tf_conn= tcp_conn;
|
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