1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

adopt: pass wsi opaque so its set from the start

This commit is contained in:
Andy Green 2019-12-08 21:26:59 +00:00
parent 8c2114a430
commit fb54b590c7
6 changed files with 84 additions and 22 deletions

View file

@ -113,6 +113,40 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
lws_sock_file_fd_type fd, const char *vh_prot_name,
struct lws *parent);
typedef struct lws_adopt_desc {
struct lws_vhost *vh; /**< vhost the wsi should belong to */
lws_adoption_type type; /**< OR-ed combinations of lws_adoption_type flags */
lws_sock_file_fd_type fd; /**< union with either .sockfd or .filefd set */
const char *vh_prot_name; /**< NULL or vh protocol name to bind raw connection to */
struct lws *parent; /**< NULL or struct lws to attach new_wsi to as a child */
void *opaque; /**< opaque pointer to set on created wsi */
} lws_adopt_desc_t;
/**
* lws_adopt_descriptor_vhost_via_info() - adopt foreign socket or file descriptor
* if socket descriptor, should already have been accepted from listen socket
*
* \param info: the struct containing the parameters
*
* - vh: lws vhost
* - type: OR-ed combinations of lws_adoption_type flags
* - fd: union with either .sockfd or .filefd set
* - vh_prot_name: NULL or vh protocol name to bind raw connection to
* - parent: NULL or struct lws to attach new_wsi to as a child
* - opaque: opaque pointer to set on created wsi
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's
* ready to accept an upgrade to ws or just serve http.
*
* parent may be NULL, if given it should be an existing wsi that will become the
* parent of the new wsi created by this call.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info);
/**
* lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
* for the default vhost of context.
@ -181,6 +215,7 @@ lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost,
* \param protocol_name: Name of protocol on vhost to bind wsi to
* \param ifname: NULL, for network interface name to bind socket to
* \param parent_wsi: NULL or parent wsi new wsi will be a child of
* \param opaque: set created wsi opaque ptr to this
* \param retry_policy: NULL for vhost default policy else wsi specific policy
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
@ -189,6 +224,10 @@ lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost,
LWS_VISIBLE LWS_EXTERN struct lws *
lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
int flags, const char *protocol_name, const char *ifname,
struct lws *parent_wsi, const lws_retry_bo_t *retry_policy);
struct lws *parent_wsi, void *opaque,
const lws_retry_bo_t *retry_policy);
#endif
///@}

View file

@ -117,7 +117,8 @@ lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi)
static struct lws *
lws_adopt_descriptor_vhost1(struct lws_vhost *vh, lws_adoption_type type,
const char *vh_prot_name, struct lws *parent)
const char *vh_prot_name, struct lws *parent,
void *opaque)
{
struct lws_context *context = vh->context;
struct lws_context_per_thread *pt;
@ -137,6 +138,8 @@ lws_adopt_descriptor_vhost1(struct lws_vhost *vh, lws_adoption_type type,
if (!new_wsi)
return NULL;
new_wsi->opaque_user_data = opaque;
pt = &context->pt[(int)new_wsi->tsi];
lws_stats_bump(pt, LWSSTATS_C_CONNECTIONS, 1);
@ -307,23 +310,39 @@ fail:
/* if not a socket, it's a raw, non-ssl file descriptor */
LWS_VISIBLE struct lws *
struct lws *
lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
lws_sock_file_fd_type fd, const char *vh_prot_name,
struct lws *parent)
{
lws_adopt_desc_t info;
memset(&info, 0, sizeof(info));
info.vh = vh;
info.type = type;
info.fd = fd;
info.vh_prot_name = vh_prot_name;
info.parent = parent;
return lws_adopt_descriptor_vhost_via_info(&info);
}
struct lws *
lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info)
{
struct lws *new_wsi;
#if defined(LWS_WITH_PEER_LIMITS)
struct lws_peer *peer = NULL;
if (type & LWS_ADOPT_SOCKET) {
peer = lws_get_or_create_peer(vh, fd.sockfd);
if (info->type & LWS_ADOPT_SOCKET) {
peer = lws_get_or_create_peer(info->vh, info->fd.sockfd);
if (peer && vh->context->ip_limit_wsi &&
peer->count_wsi >= vh->context->ip_limit_wsi) {
if (peer && info->vh->context->ip_limit_wsi &&
peer->count_wsi >= info->vh->context->ip_limit_wsi) {
lwsl_notice("Peer reached wsi limit %d\n",
vh->context->ip_limit_wsi);
lws_stats_bump(&vh->context->pt[0],
info->vh->context->ip_limit_wsi);
lws_stats_bump(&info->vh->context->pt[0],
LWSSTATS_C_PEER_LIMIT_WSI_DENIED,
1);
return NULL;
@ -331,27 +350,29 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
}
#endif
new_wsi = lws_adopt_descriptor_vhost1(vh, type, vh_prot_name, parent);
new_wsi = lws_adopt_descriptor_vhost1(info->vh, info->type,
info->vh_prot_name, info->parent,
info->opaque);
if (!new_wsi) {
if (type & LWS_ADOPT_SOCKET)
compatible_close(fd.sockfd);
if (info->type & LWS_ADOPT_SOCKET)
compatible_close(info->fd.sockfd);
return NULL;
}
#if defined(LWS_WITH_ACCESS_LOG)
lws_get_peer_simple_fd(fd.sockfd, new_wsi->simple_ip,
lws_get_peer_simple_fd(info->fd.sockfd, new_wsi->simple_ip,
sizeof(new_wsi->simple_ip));
#endif
#if defined(LWS_WITH_PEER_LIMITS)
if (peer)
lws_peer_add_wsi(vh->context, peer, new_wsi);
lws_peer_add_wsi(info->vh->context, peer, new_wsi);
#endif
return lws_adopt_descriptor_vhost2(new_wsi, type, fd);
return lws_adopt_descriptor_vhost2(new_wsi, info->type, info->fd);
}
LWS_VISIBLE struct lws *
struct lws *
lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd)
{
lws_sock_file_fd_type fd;
@ -561,7 +582,8 @@ bail:
struct lws *
lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
int flags, const char *protocol_name, const char *ifname,
struct lws *parent_wsi, const lws_retry_bo_t *retry_policy)
struct lws *parent_wsi, void *opaque,
const lws_retry_bo_t *retry_policy)
{
#if !defined(LWS_PLAT_OPTEE)
struct lws *wsi;
@ -572,7 +594,7 @@ lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
/* create the logical wsi without any valid fd */
wsi = lws_adopt_descriptor_vhost1(vhost, LWS_ADOPT_RAW_SOCKET_UDP,
protocol_name, parent_wsi);
protocol_name, parent_wsi, opaque);
if (!wsi) {
lwsl_err("%s: udp wsi creation failed\n", __func__);
goto bail;

View file

@ -320,7 +320,7 @@ ok:
context->async_dns.wsi = lws_create_adopt_udp(context->vhost_list, ads,
53, 0, lws_async_dns_protocol.name, NULL,
NULL, &retry_policy);
NULL, NULL, &retry_policy);
if (!dns->wsi) {
lwsl_err("%s: foreign socket adoption failed\n", __func__);
return 1;

View file

@ -199,7 +199,7 @@ lws_dhcpc_retry_conn(struct lws_sorted_usec_list *sul)
68, LWS_CAUDP_PF_PACKET |
LWS_CAUDP_BROADCAST,
"lws-dhcpclient", (const char *)&r[1],
NULL, &bo2);
NULL, NULL, &bo2);
lwsl_debug("%s: created wsi_raw: %p\n", __func__, r->wsi_raw);
if (!r->wsi_raw) {
lwsl_err("%s: unable to create udp skt\n", __func__);

View file

@ -82,7 +82,8 @@ lws_ntpc_retry_conn(struct lws_sorted_usec_list *sul)
v->retry_count_write = 0;
v->wsi_udp = lws_create_adopt_udp(v->vhost, v->ntp_server_ads, 123, 0,
v->protocol->name, NULL, NULL, &bo2);
v->protocol->name, NULL, NULL, NULL,
&bo2);
lwsl_debug("%s: created wsi_udp: %p\n", __func__, v->wsi_udp);
if (!v->wsi_udp) {
lwsl_err("%s: unable to create udp skt\n", __func__);

View file

@ -170,7 +170,7 @@ int main(int argc, const char **argv)
* Create our own "foreign" UDP socket bound to 7681/udp
*/
if (!lws_create_adopt_udp(vhost, NULL, 7681, LWS_CAUDP_BIND,
protocols[0].name, NULL, NULL, NULL)) {
protocols[0].name, NULL, NULL, NULL, NULL)) {
lwsl_err("%s: foreign socket adoption failed\n", __func__);
goto bail;
}