Ticket #6066: bep-41.patch

File bep-41.patch, 3.5 KB (added by bredov, 3 years ago)
  • libtransmission/announcer-udp.c

     
    273273*****
    274274****/
    275275
     276typedef enum
     277{
     278    TAU_OPTION_END_OF_OPTIONS = 0,
     279    TAU_OPTION_NOP            = 1,
     280    TAU_OPTION_URL_DATA       = 2
     281}
     282tau_announce_option_type;
     283
     284enum
     285{
     286    TAU_OPTION_LEN_MAX = 255
     287};
     288
     289struct tau_announce_option
     290{
     291    struct tau_announce_option * next;
     292
     293    void * payload;
     294    uint8_t payload_len;
     295    tau_announce_option_type type;
     296};
     297
     298static struct tau_announce_option *
     299tau_announce_option_new (struct tau_announce_option * ops,
     300                         tau_announce_option_type type,
     301                         void * payload,
     302                         uint8_t payload_len)
     303{
     304    struct tau_announce_option * op = tr_new0(struct tau_announce_option, 1);
     305
     306    op->type = type;
     307    op->payload = payload ? tr_memdup(payload, payload_len) : NULL;
     308    op->payload_len = payload_len;
     309    op->next = ops;
     310
     311    return op;
     312}
     313
     314static struct tau_announce_option *
     315tau_announce_option_new_url_data (struct tau_announce_option * ops,
     316                                  char * url)
     317{
     318    char * path = NULL;
     319
     320
     321    if (tr_urlParse (url, strlen (url), NULL, NULL, NULL, &path))
     322    {
     323        size_t path_len = strlen (path);
     324        char * path_ptr = path;
     325
     326        for (; path_len > TAU_OPTION_LEN_MAX; path_len -= TAU_OPTION_LEN_MAX)
     327        {
     328            ops = tau_announce_option_new (ops, TAU_OPTION_URL_DATA, path_ptr, TAU_OPTION_LEN_MAX);
     329            path_ptr += TAU_OPTION_LEN_MAX;
     330        }
     331
     332        if (path_len > 0)
     333        {
     334            ops = tau_announce_option_new (ops, TAU_OPTION_URL_DATA, path_ptr, path_len);
     335        }
     336
     337        tr_free (path);
     338
     339        return ops;
     340    }
     341
     342
     343    return NULL;
     344}
     345
     346static void
     347tau_announce_option_free (struct tau_announce_option * ops)
     348{
     349    for (struct tau_announce_option * op = ops; op != NULL;)
     350    {
     351        struct tau_announce_option * old = op;
     352        op = op->next;
     353        tr_free (old->payload);
     354        tr_free (old);
     355    }
     356}
     357
     358static void
     359tau_announce_option_copyout_to_evbuffer (struct tau_announce_option * op,
     360                                         struct evbuffer * buf)
     361{
     362    uint8_t type = op->type;
     363
     364    evbuffer_add (buf, &type, 1);
     365
     366    if (op->type != TAU_OPTION_END_OF_OPTIONS && op->type != TAU_OPTION_NOP)
     367    {
     368        evbuffer_add (buf, &op->payload_len, 1);
     369
     370        if (op->payload_len > 0)
     371        {
     372            evbuffer_add (buf, op->payload, op->payload_len);
     373        }
     374    }
     375}
     376
     377static void
     378tau_announce_option_copyout_to_evbuffer_all (struct tau_announce_option * ops,
     379                                             struct evbuffer * buf)
     380{
     381    if (ops)
     382    {
     383        tau_announce_option_copyout_to_evbuffer_all (ops->next, buf);
     384        tau_announce_option_copyout_to_evbuffer (ops, buf);
     385    }
     386}
     387
    276388struct tau_announce_request
    277389{
    278390    void * payload;
     
    333445    evbuffer_add_hton_32 (buf, in->numwant);
    334446    evbuffer_add_hton_16 (buf, in->port);
    335447
     448    /* add options (BEP-41) */
     449    struct tau_announce_option * ops = tau_announce_option_new_url_data (NULL, in->url);
     450
     451    if (ops)
     452    {
     453        tau_announce_option_copyout_to_evbuffer_all (ops, buf);
     454    }
     455
     456    tau_announce_option_free (ops);
     457
    336458    /* build the tau_announce_request */
    337459    req = tr_new0 (struct tau_announce_request, 1);
    338460    req->created_at = tr_time ();