Ticket #5888: 5888-utorrent-3.4-utp.patch

File 5888-utorrent-3.4-utp.patch, 15.7 KB (added by mike.dld, 7 years ago)
  • libtransmission/net.c

     
    305305{
    306306  struct UTPSocket * ret = NULL;
    307307
    308   if (tr_address_is_valid_for_peers (addr, port))
     308  if (session->utp_context != NULL && tr_address_is_valid_for_peers (addr, port))
    309309    {
    310310      struct sockaddr_storage ss;
    311311      const socklen_t sslen = setup_sockaddr (addr, port, &ss);
    312       ret = UTP_Create (tr_utpSendTo, session, (struct sockaddr*)&ss, sslen);
     312      ret = utp_create_socket (session->utp_context);
     313      if (ret != NULL)
     314        {
     315          if (utp_connect (ret, (struct sockaddr*) &ss, sslen) < 0)
     316            {
     317              utp_close (ret);
     318              ret = NULL;
     319            }
     320        }
    313321    }
    314322
    315323  return ret;
  • libtransmission/peer-io.c

     
    409409#ifdef WITH_UTP
    410410/* UTP callbacks */
    411411
    412 static void
    413 utp_on_read (void *closure, const unsigned char *buf, size_t buflen)
     412static uint64
     413utp_on_read (utp_callback_arguments * a)
    414414{
    415415    int rc;
    416     tr_peerIo *io = closure;
     416    tr_peerIo *io = utp_get_userdata (a->socket);
     417    const unsigned char * const buf = a->buf;
     418    const size_t buflen = a->len;
     419    if (io == NULL) return 0;
    417420    assert (tr_isPeerIo (io));
    418421
    419422    rc = evbuffer_add (io->inbuf, buf, buflen);
     
    421424
    422425    if (rc < 0) {
    423426        tr_logAddNamedError ("UTP", "On read evbuffer_add");
    424         return;
     427        return 0;
    425428    }
    426429
    427430    tr_peerIoSetEnabled (io, TR_DOWN, true);
    428431    canReadWrapper (io);
    429 }
    430432
    431 static void
    432 utp_on_write (void *closure, unsigned char *buf, size_t buflen)
    433 {
    434     int rc;
    435     tr_peerIo *io = closure;
    436     assert (tr_isPeerIo (io));
    437 
    438     rc = evbuffer_remove (io->outbuf, buf, buflen);
    439     dbgmsg (io, "utp_on_write sending %"TR_PRIuSIZE" bytes... evbuffer_remove returned %d", buflen, rc);
    440     assert (rc == (int)buflen); /* if this fails, we've corrupted our bookkeeping somewhere */
    441     if (rc < (long)buflen) {
    442         tr_logAddNamedError ("UTP", "Short write: %d < %ld", rc, (long)buflen);
    443     }
    444 
    445     didWriteWrapper (io, buflen);
     433    return 0;
    446434}
    447435
    448 static size_t
    449 utp_get_rb_size (void *closure)
     436static uint64
     437utp_get_rb_size (utp_callback_arguments * a)
    450438{
    451439    size_t bytes;
    452     tr_peerIo *io = closure;
     440    tr_peerIo *io = utp_get_userdata (a->socket);
     441    if (io == NULL) return 0;
    453442    assert (tr_isPeerIo (io));
    454443
    455444    bytes = tr_bandwidthClamp (&io->bandwidth, TR_DOWN, UTP_READ_BUFFER_SIZE);
     
    471460    tr_peerIoSetEnabled (io, TR_UP, n && evbuffer_get_length (io->outbuf));
    472461}
    473462
    474 static void
    475 utp_on_state_change (void *closure, int state)
     463static uint64
     464utp_on_state_change (utp_callback_arguments * a)
    476465{
    477     tr_peerIo *io = closure;
     466    tr_peerIo *io = utp_get_userdata (a->socket);
     467    const int state = a->state;
     468    if (io == NULL) return 0;
    478469    assert (tr_isPeerIo (io));
    479470
    480471    if (state == UTP_STATE_CONNECT) {
     
    489480            io->gotError (io, BEV_EVENT_EOF, io->userData);
    490481    } else if (state == UTP_STATE_DESTROYING) {
    491482        tr_logAddNamedError ("UTP", "Impossible state UTP_STATE_DESTROYING");
    492         return;
    493483    } else {
    494484        tr_logAddNamedError ("UTP", "Unknown state %d", state);
    495485    }
     486
     487    return 0;
    496488}
    497489
    498 static void
    499 utp_on_error (void *closure, int errcode)
     490static uint64
     491utp_on_error (utp_callback_arguments * a)
    500492{
    501     tr_peerIo *io = closure;
     493    tr_peerIo *io = utp_get_userdata (a->socket);
     494    const int errcode = a->error_code;
     495    if (io == NULL) return 0;
    502496    assert (tr_isPeerIo (io));
    503497
    504498    dbgmsg (io, "utp_on_error -- errcode is %d", errcode);
     
    507501        errno = errcode;
    508502        io->gotError (io, BEV_EVENT_ERROR, io->userData);
    509503    }
     504
     505    return 0;
    510506}
    511507
    512 static void
    513 utp_on_overhead (void *closure, uint8_t send, size_t count, int type UNUSED)
     508static uint64
     509utp_on_overhead (utp_callback_arguments * a)
    514510{
    515     tr_peerIo *io = closure;
     511    tr_peerIo *io = utp_get_userdata (a->socket);
     512    const bool send = a->send;
     513    const size_t count = a->len;
     514    if (io == NULL) return 0;
    516515    assert (tr_isPeerIo (io));
    517516
    518517    dbgmsg (io, "utp_on_overhead -- count is %"TR_PRIuSIZE, count);
     
    519518
    520519    tr_bandwidthUsed (&io->bandwidth, send ? TR_UP : TR_DOWN,
    521520                      count, false, tr_time_msec ());
     521    return 0;
    522522}
    523523
    524 static struct UTPFunctionTable utp_function_table = {
    525     .on_read = utp_on_read,
    526     .on_write = utp_on_write,
    527     .get_rb_size = utp_get_rb_size,
    528     .on_state = utp_on_state_change,
    529     .on_error = utp_on_error,
    530     .on_overhead = utp_on_overhead
    531 };
    532 
    533 
    534524/* Dummy UTP callbacks. */
    535525/* We switch a UTP socket to use these after the associated peerIo has been
    536526   destroyed -- see io_dtor. */
     
    576566    return;
    577567}
    578568
    579 static struct UTPFunctionTable dummy_utp_function_table = {
    580     .on_read = dummy_read,
    581     .on_write = dummy_write,
    582     .get_rb_size = dummy_get_rb_size,
    583     .on_state = dummy_on_state_change,
    584     .on_error = dummy_on_error,
    585     .on_overhead = dummy_on_overhead
    586 };
    587 
    588569#endif /* #ifdef WITH_UTP */
    589570
    590571static tr_peerIo*
     
    642623    }
    643624#ifdef WITH_UTP
    644625    else {
    645         UTP_SetSockopt (utp_socket, SO_RCVBUF, UTP_READ_BUFFER_SIZE);
    646         dbgmsg (io, "%s", "calling UTP_SetCallbacks &utp_function_table");
    647         UTP_SetCallbacks (utp_socket,
    648                           &utp_function_table,
    649                           io);
    650         if (!isIncoming) {
    651             dbgmsg (io, "%s", "calling UTP_Connect");
    652             UTP_Connect (utp_socket);
    653         }
     626        utp_set_userdata (utp_socket, io);
    654627    }
    655628#endif
    656629
     
    657630    return io;
    658631}
    659632
     633void
     634tr_peerIoUtpInit (struct struct_utp_context * ctx)
     635{
     636#ifdef WITH_UTP
     637
     638  utp_set_callback (ctx, UTP_ON_READ, &utp_on_read);
     639  utp_set_callback (ctx, UTP_GET_READ_BUFFER_SIZE, &utp_get_rb_size);
     640  utp_set_callback (ctx, UTP_ON_STATE_CHANGE, &utp_on_state_change);
     641  utp_set_callback (ctx, UTP_ON_ERROR, &utp_on_error);
     642  utp_set_callback (ctx, UTP_ON_OVERHEAD_STATISTICS, &utp_on_overhead);
     643
     644  utp_context_set_option (ctx, UTP_RCVBUF, UTP_READ_BUFFER_SIZE);
     645
     646#else
     647
     648  (void) ctx;
     649
     650#endif
     651}
     652
    660653tr_peerIo*
    661654tr_peerIoNewIncoming (tr_session        * session,
    662655                      tr_bandwidth      * parent,
     
    808801
    809802#ifdef WITH_UTP
    810803    if (io->utp_socket) {
    811         UTP_SetCallbacks (io->utp_socket,
    812                           &dummy_utp_function_table,
    813                           NULL);
    814         UTP_Close (io->utp_socket);
     804        utp_set_userdata (io->utp_socket, NULL);
     805        utp_close (io->utp_socket);
    815806
    816807        io->utp_socket = NULL;
    817808    }
     
    12341225             * It opens up the congestion window by sending an ACK (soonish)
    12351226             * if one was not going to be sent. */
    12361227            if (evbuffer_get_length (io->inbuf) == 0)
    1237                 UTP_RBDrained (io->utp_socket);
     1228                utp_read_drained (io->utp_socket);
    12381229        }
    12391230        else /* tcp peer connection */
    12401231        {
     
    12791270    {
    12801271        if (io->utp_socket != NULL) /* utp peer connection */
    12811272        {
    1282             UTP_Write (io->utp_socket, howmuch);
    1283             n = old_len - evbuffer_get_length (io->outbuf);
     1273            n = utp_write (io->utp_socket, evbuffer_pullup (io->outbuf, howmuch), howmuch);
     1274            if (n > 0)
     1275            {
     1276                evbuffer_drain (io->outbuf, n);
     1277                didWriteWrapper (io, n);
     1278            }
    12841279        }
    12851280        else
    12861281        {
  • libtransmission/peer-io.h

     
    2727#include "utils.h" /* tr_time () */
    2828
    2929struct evbuffer;
     30struct struct_utp_context;
     31
    3032struct tr_bandwidth;
    3133struct tr_datatype;
    3234struct tr_peerIo;
     
    119121***
    120122**/
    121123
     124void tr_peerIoUtpInit (struct struct_utp_context * ctx);
     125
    122126tr_peerIo*  tr_peerIoNewOutgoing (tr_session              * session,
    123127                                  struct tr_bandwidth     * parent,
    124128                                  const struct tr_address * addr,
  • libtransmission/peer-mgr.c

     
    20712071      if (socket != TR_BAD_SOCKET)
    20722072        tr_netClose (session, socket);
    20732073      else
    2074         UTP_Close (utp_socket);
     2074        utp_set_userdata (utp_socket, NULL), utp_close (utp_socket);
    20752075    }
    20762076  else if (getExistingHandshake (&manager->incomingHandshakes, addr))
    20772077    {
     
    20782078      if (socket != TR_BAD_SOCKET)
    20792079        tr_netClose (session, socket);
    20802080      else
    2081         UTP_Close (utp_socket);
     2081        utp_set_userdata (utp_socket, NULL), utp_close (utp_socket);
    20822082    }
    20832083  else /* we don't have a connection to them yet... */
    20842084    {
  • libtransmission/session.c

     
    746746  if (session->isLPDEnabled)
    747747    tr_lpdInit (session, &session->public_ipv4->addr);
    748748
     749  tr_utpInit (session);
     750
    749751  /* cleanup */
    750752  tr_variantFree (&settings);
    751753  data->done = true;
     
    17961798  if (session->isLPDEnabled)
    17971799    tr_lpdUninit (session);
    17981800
    1799   tr_utpClose (session);
    18001801  tr_dhtUninit (session);
    18011802
    18021803  event_free (session->saveTimer);
     
    18471848  tr_statsClose (session);
    18481849  tr_peerMgrFree (session->peerMgr);
    18491850
     1851  tr_utpClose (session);
     1852
    18501853  closeBlocklists (session);
    18511854
    18521855  tr_fdClose (session);
  • libtransmission/session.h

     
    4747
    4848struct event_base;
    4949struct evdns_base;
     50struct struct_utp_context;
    5051
    5152struct tr_address;
    5253struct tr_announcer;
     
    157158    struct event                 *udp_event;
    158159    struct event                 *udp6_event;
    159160
     161    struct struct_utp_context  * utp_context;
     162
    160163    /* The open port on the local machine for incoming peer requests */
    161164    tr_port                      private_peer_port;
    162165
  • libtransmission/tr-utp.c

     
    3232#include "net.h"
    3333#include "session.h"
    3434#include "crypto-utils.h" /* tr_rand_int_weak () */
     35#include "peer-io.h"
    3536#include "peer-mgr.h"
    3637#include "tr-utp.h"
    3738#include "utils.h"
     
    7172    return false;
    7273}
    7374
     75void tr_utpInit (tr_session * session) { }
     76
    7477int tr_utpPacket (const unsigned char *buf UNUSED, size_t buflen UNUSED,
    7578                 const struct sockaddr *from UNUSED, socklen_t fromlen UNUSED,
    7679                 tr_session *ss UNUSED) { return -1; }
     
    8689
    8790void tr_utpClose (tr_session * ss UNUSED) { }
    8891
    89 void tr_utpSendTo (void *closure UNUSED,
    90                   const unsigned char *buf UNUSED, size_t buflen UNUSED,
    91                   const struct sockaddr *to UNUSED, socklen_t tolen UNUSED) { }
    92 
    9392#else
    9493
    9594/* Greg says 50ms works for them. */
     
    9897
    9998static struct event *utp_timer = NULL;
    10099
    101 static void
    102 incoming (void *closure, struct UTPSocket *s)
     100static uint64
     101utp_on_accept (utp_callback_arguments * a)
    103102{
    104     tr_session *ss = closure;
     103    tr_session * ss = utp_context_get_userdata (a->context);
     104    struct UTPSocket * const s = a->socket;
    105105    struct sockaddr_storage from_storage;
    106106    struct sockaddr *from = (struct sockaddr*)&from_storage;
    107107    socklen_t fromlen = sizeof (from_storage);
    108108    tr_address addr;
    109109    tr_port port;
     110    if (ss == NULL) { utp_close (s); return 0; }
    110111
    111112    if (!tr_sessionIsUTPEnabled (ss)) {
    112         UTP_Close (s);
    113         return;
     113        utp_close (s);
     114        return 0;
    114115    }
    115116
    116     UTP_GetPeerName (s, from, &fromlen);
     117    utp_getpeername (s, from, &fromlen);
    117118    if (!tr_address_from_sockaddr_storage (&addr, &port, &from_storage))
    118119    {
    119120        tr_logAddNamedError ("UTP", "Unknown socket family");
    120         UTP_Close (s);
    121         return;
     121        utp_close (s);
     122        return 0;
    122123    }
    123124
    124125    tr_peerMgrAddIncoming (ss->peerMgr, &addr, port, TR_BAD_SOCKET, s);
     126    return 0;
    125127}
    126128
    127 void
    128 tr_utpSendTo (void *closure, const unsigned char *buf, size_t buflen,
    129              const struct sockaddr *to, socklen_t tolen)
     129static uint64
     130utp_send_to (utp_callback_arguments * a)
    130131{
    131     tr_session *ss = closure;
     132    tr_session * ss = utp_context_get_userdata (a->context);
     133    const unsigned char * const buf = a->buf;
     134    const size_t buflen = a->len;
     135    const struct sockaddr * const to = a->address;
     136    const socklen_t tolen = a->address_len;
     137    if (ss == NULL) return 0;
    132138
    133139    if (to->sa_family == AF_INET && ss->udp_socket != TR_BAD_SOCKET)
    134140        sendto (ss->udp_socket, (const void *) buf, buflen, 0, to, tolen);
    135141    else if (to->sa_family == AF_INET6 && ss->udp6_socket != TR_BAD_SOCKET)
    136142        sendto (ss->udp6_socket, (const void *) buf, buflen, 0, to, tolen);
     143
     144    return 0;
    137145}
    138146
     147static uint64
     148utp_log (utp_callback_arguments * a)
     149{
     150    fprintf (stderr, "[utp] %s\n", a->buf);
     151    return 0;
     152}
     153
    139154static void
    140155reset_timer (tr_session *ss)
    141156{
     
    160175timer_callback (evutil_socket_t s UNUSED, short type UNUSED, void *closure)
    161176{
    162177    tr_session *ss = closure;
    163     UTP_CheckTimeouts ();
     178    utp_check_timeouts (ss->utp_context);
    164179    reset_timer (ss);
    165180}
    166181
     182void
     183tr_utpInit (tr_session * session)
     184{
     185  struct struct_utp_context * ctx;
     186
     187  if (session->utp_context != NULL)
     188    return;
     189
     190  ctx = utp_init (2);
     191  if (ctx == NULL)
     192    return;
     193
     194  utp_context_set_userdata (ctx, session);
     195
     196  utp_set_callback (ctx, UTP_LOG, &utp_log);
     197  utp_set_callback (ctx, UTP_ON_ACCEPT, &utp_on_accept);
     198  utp_set_callback (ctx, UTP_SENDTO, &utp_send_to);
     199
     200  tr_peerIoUtpInit (ctx);
     201
     202  utp_context_set_option (ctx, UTP_LOG_NORMAL, 1);
     203  /* utp_context_set_option (ctx, UTP_LOG_MTU, 1); */
     204  /* utp_context_set_option (ctx, UTP_LOG_DEBUG, 1); */
     205
     206  session->utp_context = ctx;
     207}
     208
    167209int
    168210tr_utpPacket (const unsigned char *buf, size_t buflen,
    169211             const struct sockaddr *from, socklen_t fromlen,
     
    177219        reset_timer (ss);
    178220    }
    179221
    180     return UTP_IsIncomingUTP (incoming, tr_utpSendTo, ss,
    181                              buf, buflen, from, fromlen);
     222    return utp_process_udp (ss->utp_context, buf, buflen, from, fromlen);
    182223}
    183224
    184225void
    185 tr_utpClose (tr_session * session UNUSED)
     226tr_utpClose (tr_session * session)
    186227{
    187228    if (utp_timer)
    188229    {
     
    189230        evtimer_del (utp_timer);
    190231        utp_timer = NULL;
    191232    }
     233
     234    if (session->utp_context != NULL)
     235    {
     236        utp_context_set_userdata (session->utp_context, NULL);
     237        utp_destroy (session->utp_context);
     238        session->utp_context = NULL;
     239    }
    192240}
    193241
    194242#endif /* #ifndef WITH_UTP ... else */
  • libtransmission/tr-utp.h

     
    2828#ifndef _TR_UTP_H_
    2929#define _TR_UTP_H_
    3030
     31void tr_utpInit (tr_session * session);
     32
    3133int tr_utpPacket (const unsigned char *buf, size_t buflen,
    3234                 const struct sockaddr *from, socklen_t fromlen,
    3335                 tr_session *ss);
     
    3436
    3537void tr_utpClose (tr_session *);
    3638
    37 void tr_utpSendTo (void *closure, const unsigned char *buf, size_t buflen,
    38                   const struct sockaddr *to, socklen_t tolen);
    39 
    4039#endif /* #ifndef _TR_UTP_H_ */