[ 
https://issues.apache.org/jira/browse/DISPATCH-1271?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jiri Daněk updated DISPATCH-1271:
---------------------------------
    Description: 
{noformat}
        lws_callback_all_protocol(hs->context, &protocols[1], 
LWS_CALLBACK_USER);
        lws_callback_all_protocol(hs->context, &protocols[2], 
LWS_CALLBACK_USER);
{noformat}
The problem is that {{lws_callback_all_protocol}} compares pointers to protocol 
structs with {{protocol}} parameter. They are never equal, because early on in 
{{listener_start}}, {{lws_create_vhost}} gets called, and it allocates a copy 
of the {{protocols}} array only for that vhost.

I expected that this will cause dispatch not to send heartbeats to clients 
connected over amqpws (since {{pn_transport_tick}} is not called). I tested 
that with qpid-jms, and -it turned out that the heartbeats are flowing 
correctly. In other words, I am not aware of any user-visible bug caused by 
this. Is calling _tick unnecessary? What is it there for?- I saw that dispatch 
is not sending its own heartbeats on the amqpws connections.
{noformat}
LWS_VISIBLE int
lws_callback_all_protocol(struct lws_context *context,
                          const struct lws_protocols *protocol, int reason)
{
        struct lws_context_per_thread *pt = &context->pt[0];
        unsigned int n, m = context->count_threads;
        struct lws *wsi;

        while (m--) {
                for (n = 0; n < pt->fds_count; n++) {
                        wsi = wsi_from_fd(context, pt->fds[n].fd);
                        if (!wsi)
                                continue;
                        if (wsi->protocol == protocol)
                                protocol->callback(wsi, reason, wsi->user_space,
                                                   NULL, 0);
                }
                pt++;
        }

        return 0;
}
{noformat}
{noformat}
LWS_VISIBLE struct lws_vhost *
lws_create_vhost(struct lws_context *context,
                 const struct lws_context_creation_info *info)
{
    [...]
    
        /*
         * give the vhost a unified list of protocols including the
         * ones that came from plugins
         */
        lwsp = lws_zalloc(sizeof(struct lws_protocols) * (vh->count_protocols +
                                   context->plugin_protocol_count + 1),
                          "vhost-specific plugin table");
        if (!lwsp) {
                lwsl_err("OOM\n");
                return NULL;
        }

        m = vh->count_protocols;
        memcpy(lwsp, pcols, sizeof(struct lws_protocols) * m);

    [...]

        if (
#ifdef LWS_WITH_PLUGINS
            (context->plugin_list) ||
#endif
            context->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
                vh->protocols = lwsp;
        else {
                vh->protocols = pcols;
                lws_free(lwsp);
        }

    [...]
}
{noformat}

  was:
{noformat}
        lws_callback_all_protocol(hs->context, &protocols[1], 
LWS_CALLBACK_USER);
        lws_callback_all_protocol(hs->context, &protocols[2], 
LWS_CALLBACK_USER);
{noformat}

The problem is that {{lws_callback_all_protocol}} compares pointers to protocol 
structs with {{protocol}} parameter. They are never equal, because early on in 
{{listener_start}}, {{lws_create_vhost}} gets called, and it allocates a copy 
of the {{protocols}} array only for that vhost.

I expected that this will cause dispatch not to send heartbeats to clients 
connected over amqpws (since {{pn_transport_tick}} is not called). I tested 
that with qpid-jms, and it turned out that the heartbeats are flowing 
correctly. In other words, I am not aware of any user-visible bug caused by 
this. Is calling _tick unnecessary? What is it there for?

{noformat}
LWS_VISIBLE int
lws_callback_all_protocol(struct lws_context *context,
                          const struct lws_protocols *protocol, int reason)
{
        struct lws_context_per_thread *pt = &context->pt[0];
        unsigned int n, m = context->count_threads;
        struct lws *wsi;

        while (m--) {
                for (n = 0; n < pt->fds_count; n++) {
                        wsi = wsi_from_fd(context, pt->fds[n].fd);
                        if (!wsi)
                                continue;
                        if (wsi->protocol == protocol)
                                protocol->callback(wsi, reason, wsi->user_space,
                                                   NULL, 0);
                }
                pt++;
        }

        return 0;
}
{noformat}

{noformat}
LWS_VISIBLE struct lws_vhost *
lws_create_vhost(struct lws_context *context,
                 const struct lws_context_creation_info *info)
{
    [...]
    
        /*
         * give the vhost a unified list of protocols including the
         * ones that came from plugins
         */
        lwsp = lws_zalloc(sizeof(struct lws_protocols) * (vh->count_protocols +
                                   context->plugin_protocol_count + 1),
                          "vhost-specific plugin table");
        if (!lwsp) {
                lwsl_err("OOM\n");
                return NULL;
        }

        m = vh->count_protocols;
        memcpy(lwsp, pcols, sizeof(struct lws_protocols) * m);

    [...]

        if (
#ifdef LWS_WITH_PLUGINS
            (context->plugin_list) ||
#endif
            context->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
                vh->protocols = lwsp;
        else {
                vh->protocols = pcols;
                lws_free(lwsp);
        }

    [...]
}
{noformat}


> The LWS_CALLBACK_USER handler in http-libwebsockets.c is never triggered
> ------------------------------------------------------------------------
>
>                 Key: DISPATCH-1271
>                 URL: https://issues.apache.org/jira/browse/DISPATCH-1271
>             Project: Qpid Dispatch
>          Issue Type: Bug
>    Affects Versions: 1.5.0
>            Reporter: Jiri Daněk
>            Priority: Major
>
> {noformat}
>         lws_callback_all_protocol(hs->context, &protocols[1], 
> LWS_CALLBACK_USER);
>         lws_callback_all_protocol(hs->context, &protocols[2], 
> LWS_CALLBACK_USER);
> {noformat}
> The problem is that {{lws_callback_all_protocol}} compares pointers to 
> protocol structs with {{protocol}} parameter. They are never equal, because 
> early on in {{listener_start}}, {{lws_create_vhost}} gets called, and it 
> allocates a copy of the {{protocols}} array only for that vhost.
> I expected that this will cause dispatch not to send heartbeats to clients 
> connected over amqpws (since {{pn_transport_tick}} is not called). I tested 
> that with qpid-jms, and -it turned out that the heartbeats are flowing 
> correctly. In other words, I am not aware of any user-visible bug caused by 
> this. Is calling _tick unnecessary? What is it there for?- I saw that 
> dispatch is not sending its own heartbeats on the amqpws connections.
> {noformat}
> LWS_VISIBLE int
> lws_callback_all_protocol(struct lws_context *context,
>                         const struct lws_protocols *protocol, int reason)
> {
>       struct lws_context_per_thread *pt = &context->pt[0];
>       unsigned int n, m = context->count_threads;
>       struct lws *wsi;
>       while (m--) {
>               for (n = 0; n < pt->fds_count; n++) {
>                       wsi = wsi_from_fd(context, pt->fds[n].fd);
>                       if (!wsi)
>                               continue;
>                       if (wsi->protocol == protocol)
>                               protocol->callback(wsi, reason, wsi->user_space,
>                                                  NULL, 0);
>               }
>               pt++;
>       }
>       return 0;
> }
> {noformat}
> {noformat}
> LWS_VISIBLE struct lws_vhost *
> lws_create_vhost(struct lws_context *context,
>                const struct lws_context_creation_info *info)
> {
>     [...]
>     
>       /*
>        * give the vhost a unified list of protocols including the
>        * ones that came from plugins
>        */
>       lwsp = lws_zalloc(sizeof(struct lws_protocols) * (vh->count_protocols +
>                                  context->plugin_protocol_count + 1),
>                         "vhost-specific plugin table");
>       if (!lwsp) {
>               lwsl_err("OOM\n");
>               return NULL;
>       }
>       m = vh->count_protocols;
>       memcpy(lwsp, pcols, sizeof(struct lws_protocols) * m);
>     [...]
>       if (
> #ifdef LWS_WITH_PLUGINS
>           (context->plugin_list) ||
> #endif
>           context->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
>               vh->protocols = lwsp;
>       else {
>               vh->protocols = pcols;
>               lws_free(lwsp);
>       }
>     [...]
> }
> {noformat}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to