mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
ng_ksocket: fix accept(2)
- Provide listen upcall and set it on NGM_KSOCKET_LISTEN
- Mask EWOULDBLOCK on NGM_KSOCKET_ACCEPT
Reviewed by: afedorov
Differential Revision: https://reviews.freebsd.org/D42637
PR: 272319
PR: 275106
Fixes: 779f106aa1
This commit is contained in:
parent
efad7cbfdc
commit
43f7e21668
|
@ -152,6 +152,10 @@ static const struct ng_ksocket_alias ng_ksocket_protos[] = {
|
|||
|
||||
/* Helper functions */
|
||||
static int ng_ksocket_accept(priv_p);
|
||||
static int ng_ksocket_listen_upcall(struct socket *so, void *arg,
|
||||
int waitflag);
|
||||
static void ng_ksocket_listen_upcall2(node_p node, hook_p hook,
|
||||
void *arg1, int arg2);
|
||||
static int ng_ksocket_incoming(struct socket *so, void *arg, int waitflag);
|
||||
static int ng_ksocket_parse(const struct ng_ksocket_alias *aliases,
|
||||
const char *s, int family);
|
||||
|
@ -695,6 +699,12 @@ ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||
/* Listen */
|
||||
so->so_state |= SS_NBIO;
|
||||
error = solisten(so, *((int32_t *)msg->data), td);
|
||||
if (error == 0) {
|
||||
SOLISTEN_LOCK(so);
|
||||
solisten_upcall_set(so,
|
||||
ng_ksocket_listen_upcall, priv);
|
||||
SOLISTEN_UNLOCK(so);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -715,11 +725,15 @@ ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||
/*
|
||||
* If a connection is already complete, take it.
|
||||
* Otherwise let the upcall function deal with
|
||||
* the connection when it comes in.
|
||||
* the connection when it comes in. Don't return
|
||||
* EWOULDBLOCK, per ng_ksocket(4) documentation.
|
||||
*/
|
||||
error = ng_ksocket_accept(priv);
|
||||
if (error != 0 && error != EWOULDBLOCK)
|
||||
if (error == EWOULDBLOCK)
|
||||
error = 0;
|
||||
if (error != 0)
|
||||
ERROUT(error);
|
||||
|
||||
priv->response_token = msg->header.token;
|
||||
priv->response_addr = NGI_RETADDR(item);
|
||||
break;
|
||||
|
@ -1064,10 +1078,6 @@ ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int arg2)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check whether a pending accept operation has completed */
|
||||
if (priv->flags & KSF_ACCEPTING)
|
||||
(void )ng_ksocket_accept(priv);
|
||||
|
||||
/*
|
||||
* If we don't have a hook, we must handle data events later. When
|
||||
* the hook gets created and is connected, this upcall function
|
||||
|
@ -1250,6 +1260,25 @@ ng_ksocket_accept(priv_p priv)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_ksocket_listen_upcall(struct socket *so, void *arg, int waitflag)
|
||||
{
|
||||
priv_p priv = arg;
|
||||
int wait = ((waitflag & M_WAITOK) ? NG_WAITOK : 0) | NG_QUEUE;
|
||||
|
||||
ng_send_fn1(priv->node, NULL, &ng_ksocket_listen_upcall2, priv, 0,
|
||||
wait);
|
||||
return (SU_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_ksocket_listen_upcall2(node_p node, hook_p hook, void *arg1, int arg2)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
(void )ng_ksocket_accept(priv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse out either an integer value or an alias.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue