Ticket #1111: rtorrent-0.8.7-ipv6-08.patch

File rtorrent-0.8.7-ipv6-08.patch, 21.4 KB (added by anonymous, 13 months ago)
  • rak/socket_address.h

    diff -Nru rtorrent-0.8.7.orig/rak/socket_address.h rtorrent-0.8.7/rak/socket_address.h
    old new  
    145145  }; 
    146146}; 
    147147 
    148 // Remeber to set the AF_INET. 
     148// Remember to set the AF_INET. 
    149149 
    150150class socket_address_inet { 
    151151public: 
     
    184184 
    185185  const sockaddr*     c_sockaddr() const                      { return reinterpret_cast<const sockaddr*>(&m_sockaddr); } 
    186186  const sockaddr_in*  c_sockaddr_inet() const                 { return &m_sockaddr; } 
     187   
     188#ifdef RAK_USE_INET6 
     189  socket_address_inet6 to_mapped_address() const; 
     190#endif 
    187191 
    188192  bool                operator == (const socket_address_inet& rhs) const; 
    189193  bool                operator < (const socket_address_inet& rhs) const; 
     
    192196  struct sockaddr_in  m_sockaddr; 
    193197}; 
    194198 
     199#ifdef RAK_USE_INET6 
     200// Remember to set the AF_INET6. 
     201 
     202class socket_address_inet6 { 
     203public: 
     204  bool                is_any() const                          { return is_port_any() && is_address_any(); } 
     205  bool                is_valid() const                        { return !is_port_any() && !is_address_any(); } 
     206  bool                is_port_any() const                     { return port() == 0; } 
     207  bool                is_address_any() const                  { return std::memcmp(&m_sockaddr.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0; } 
     208 
     209  void                clear()                                 { std::memset(this, 0, sizeof(socket_address_inet6)); set_family(); } 
     210 
     211  uint16_t            port() const                            { return ntohs(m_sockaddr.sin6_port); } 
     212  uint16_t            port_n() const                          { return m_sockaddr.sin6_port; } 
     213  void                set_port(uint16_t p)                    { m_sockaddr.sin6_port = htons(p); } 
     214  void                set_port_n(uint16_t p)                  { m_sockaddr.sin6_port = p; } 
     215 
     216  in6_addr            address() const                         { return m_sockaddr.sin6_addr; } 
     217  std::string         address_str() const; 
     218  bool                address_c_str(char* buf, socklen_t size) const; 
     219 
     220  void                set_address(in6_addr a)                 { m_sockaddr.sin6_addr = a; } 
     221  bool                set_address_str(const std::string& a)   { return set_address_c_str(a.c_str()); } 
     222  bool                set_address_c_str(const char* a); 
     223 
     224  void                set_address_any()                       { set_port(0); set_address(in6addr_any); } 
     225 
     226  sa_family_t         family() const                          { return m_sockaddr.sin6_family; } 
     227  void                set_family()                            { m_sockaddr.sin6_family = AF_INET6; } 
     228 
     229  sockaddr*           c_sockaddr()                            { return reinterpret_cast<sockaddr*>(&m_sockaddr); } 
     230  sockaddr_in6*       c_sockaddr_inet6()                      { return &m_sockaddr; } 
     231 
     232  const sockaddr*     c_sockaddr() const                      { return reinterpret_cast<const sockaddr*>(&m_sockaddr); } 
     233  const sockaddr_in6* c_sockaddr_inet6() const                { return &m_sockaddr; } 
     234 
     235  socket_address      normalize_address() const; 
     236 
     237  bool                operator == (const socket_address_inet6& rhs) const; 
     238  bool                operator < (const socket_address_inet6& rhs) const; 
     239 
     240private: 
     241  struct sockaddr_in6 m_sockaddr; 
     242}; 
     243#endif 
     244 
    195245// Unique key for the address, excluding port numbers etc. 
    196246class socket_address_key { 
    197247public: 
     
    241291  switch (family()) { 
    242292  case af_inet: 
    243293    return sa_inet()->is_valid(); 
    244 //   case af_inet6: 
    245 //     return sa_inet6().is_valid(); 
     294#ifdef RAK_USE_INET6 
     295  case af_inet6: 
     296    return sa_inet6()->is_valid(); 
     297#endif 
    246298  default: 
    247299    return false; 
    248300  } 
     
    253305  switch (family()) { 
    254306  case af_inet: 
    255307    return !sa_inet()->is_address_any(); 
     308#ifdef RAK_USE_INET6 
     309  case af_inet6: 
     310    return !sa_inet6()->is_address_any(); 
     311#endif 
    256312  default: 
    257313    return false; 
    258314  } 
     
    263319  switch (family()) { 
    264320  case af_inet: 
    265321    return sa_inet()->is_address_any(); 
     322#ifdef RAK_USE_INET6 
     323  case af_inet6: 
     324    return sa_inet6()->is_address_any(); 
     325#endif 
    266326  default: 
    267327    return true; 
    268328  } 
     
    273333  switch (family()) { 
    274334  case af_inet: 
    275335    return sa_inet()->port(); 
     336#ifdef RAK_USE_INET6 
     337  case af_inet6: 
     338    return sa_inet6()->port(); 
     339#endif 
    276340  default: 
    277341    return 0; 
    278342  } 
     
    283347  switch (family()) { 
    284348  case af_inet: 
    285349    return sa_inet()->set_port(p); 
     350#ifdef RAK_USE_INET6 
     351  case af_inet6: 
     352    return sa_inet6()->set_port(p); 
     353#endif 
    286354  default: 
    287355    break; 
    288356  } 
     
    293361  switch (family()) { 
    294362  case af_inet: 
    295363    return sa_inet()->address_str(); 
     364#ifdef RAK_USE_INET6 
     365  case af_inet6: 
     366    return sa_inet6()->address_str(); 
     367#endif 
    296368  default: 
    297369    return std::string(); 
    298370  } 
     
    303375  switch (family()) { 
    304376  case af_inet: 
    305377    return sa_inet()->address_c_str(buf, size); 
     378#ifdef RAK_USE_INET6 
     379  case af_inet6: 
     380    return sa_inet6()->address_c_str(buf, size); 
     381#endif 
    306382  default: 
    307383    return false; 
    308384  } 
     
    314390    sa_inet()->set_family(); 
    315391    return true; 
    316392 
     393#ifdef RAK_USE_INET6 
     394  } else if (sa_inet6()->set_address_c_str(a)) { 
     395    sa_inet6()->set_family(); 
     396    return true; 
     397#endif 
     398 
    317399  } else { 
    318400    return false; 
    319401  } 
     
    325407  switch(family()) { 
    326408  case af_inet: 
    327409    return sizeof(sockaddr_in); 
     410#ifdef RAK_USE_INET6 
     411  case af_inet6: 
     412    return sizeof(sockaddr_in6); 
     413#endif 
    328414  default: 
    329415    return 0; 
    330416  }       
     
    349435  switch (family()) { 
    350436  case af_inet: 
    351437    return *sa_inet() == *rhs.sa_inet(); 
    352 //   case af_inet6: 
    353 //     return *sa_inet6() == *rhs.sa_inet6(); 
     438#ifdef RAK_USE_INET6 
     439  case af_inet6: 
     440    return *sa_inet6() == *rhs.sa_inet6(); 
     441#endif 
    354442  default: 
    355443    throw std::logic_error("socket_address::operator == (rhs) invalid type comparison."); 
    356444  } 
     
    364452  switch (family()) { 
    365453  case af_inet: 
    366454    return *sa_inet() < *rhs.sa_inet(); 
    367 //   case af_inet6: 
    368 //     return *sa_inet6() < *rhs.sa_inet6(); 
     455#ifdef RAK_USE_INET6 
     456  case af_inet6: 
     457    return *sa_inet6() < *rhs.sa_inet6(); 
     458#endif 
    369459  default: 
    370460    throw std::logic_error("socket_address::operator < (rhs) invalid type comparison."); 
    371461  } 
     
    391481  return inet_pton(AF_INET, a, &m_sockaddr.sin_addr); 
    392482} 
    393483 
     484#ifdef RAK_USE_INET6 
     485inline socket_address_inet6 
     486socket_address_inet::to_mapped_address() const { 
     487  uint32_t addr32[4]; 
     488  addr32[0] = 0; 
     489  addr32[1] = 0; 
     490  addr32[2] = htonl(0xffff); 
     491  addr32[3] = m_sockaddr.sin_addr.s_addr; 
     492   
     493  socket_address_inet6 sa; 
     494  sa.clear(); 
     495  sa.set_address(*reinterpret_cast<in6_addr *>(addr32)); 
     496  sa.set_port_n(m_sockaddr.sin_port); 
     497  return sa; 
     498} 
     499#endif 
     500 
    394501inline bool 
    395502socket_address_inet::operator == (const socket_address_inet& rhs) const { 
    396503  return 
     
    406513     m_sockaddr.sin_port < rhs.m_sockaddr.sin_port); 
    407514} 
    408515 
     516#ifdef RAK_USE_INET6 
     517 
     518inline std::string 
     519socket_address_inet6::address_str() const { 
     520  char buf[INET6_ADDRSTRLEN]; 
     521 
     522  if (!address_c_str(buf, INET6_ADDRSTRLEN)) 
     523    return std::string(); 
     524 
     525  return std::string(buf); 
     526} 
     527 
     528inline bool 
     529socket_address_inet6::address_c_str(char* buf, socklen_t size) const { 
     530  return inet_ntop(family(), &m_sockaddr.sin6_addr, buf, size); 
     531} 
     532 
     533inline bool 
     534socket_address_inet6::set_address_c_str(const char* a) { 
     535  return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr); 
     536} 
     537 
     538inline socket_address 
     539socket_address_inet6::normalize_address() const { 
     540  const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(m_sockaddr.sin6_addr.s6_addr); 
     541  if (addr32[0] == 0 && addr32[1] == 0 && addr32[2] == htonl(0xffff)) { 
     542    socket_address addr4; 
     543    addr4.sa_inet()->set_family(); 
     544    addr4.sa_inet()->set_address_n(addr32[3]); 
     545    addr4.sa_inet()->set_port_n(m_sockaddr.sin6_port); 
     546    return addr4; 
     547  } 
     548  return *reinterpret_cast<const socket_address*>(this); 
     549} 
     550 
     551inline bool 
     552socket_address_inet6::operator == (const socket_address_inet6& rhs) const { 
     553  return 
     554    memcmp(&m_sockaddr.sin6_addr, &rhs.m_sockaddr.sin6_addr, sizeof(in6_addr)) == 0 && 
     555    m_sockaddr.sin6_port == rhs.m_sockaddr.sin6_port; 
     556} 
     557 
     558inline bool 
     559socket_address_inet6::operator < (const socket_address_inet6& rhs) const { 
     560  int addr_comp = memcmp(&m_sockaddr.sin6_addr, &rhs.m_sockaddr.sin6_addr, sizeof(in6_addr)); 
     561  return 
     562    addr_comp < 0 || 
     563    (addr_comp == 0 || 
     564     m_sockaddr.sin6_port < rhs.m_sockaddr.sin6_port); 
     565} 
     566 
     567#endif 
     568 
    409569} 
    410570 
    411571#endif 
  • src/command_download.cc

    diff -Nru rtorrent-0.8.7.orig/src/command_download.cc rtorrent-0.8.7/src/command_download.cc
    old new  
    340340  if (download->download()->info()->is_private()) 
    341341    throw torrent::input_error("Download is private."); 
    342342 
     343#ifdef RAK_USE_INET6 
     344  ret = std::sscanf(arg.c_str(), "[%64[^]]]:%i%c", host, &port, &dummy); 
     345  if (ret < 1) 
     346    ret = std::sscanf(arg.c_str(), "%1023[^:]:%i%c", host, &port, &dummy); 
     347#else 
    343348  ret = std::sscanf(arg.c_str(), "%1023[^:]:%i%c", host, &port, &dummy); 
     349#endif 
    344350 
    345351  if (ret == 1) 
    346352    port = 6881; 
     
    350356  if (port < 1 || port > 65535) 
    351357    throw torrent::input_error("Invalid port number."); 
    352358 
     359#ifdef RAK_USE_INET6 
     360  torrent::connection_manager()->resolver()(host, (int)rak::socket_address::pf_unspec, SOCK_STREAM, call_add_d_peer_t(download, port)); 
     361#else 
    353362  torrent::connection_manager()->resolver()(host, (int)rak::socket_address::pf_inet, SOCK_STREAM, call_add_d_peer_t(download, port)); 
     363#endif 
    354364} 
    355365 
    356366torrent::Object 
  • src/command_network.cc

    diff -Nru rtorrent-0.8.7.orig/src/command_network.cc rtorrent-0.8.7/src/command_network.cc
    old new  
    355355 
    356356        control->core()->push_log("The SCGI socket has not been bound to any address and likely poses a security risk."); 
    357357 
     358#ifdef RAK_USE_INET6 
     359      } else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2 || 
     360                 std::sscanf(arg.c_str(), "[%64[^]]]:%i%c", address, &port, &dummy) == 2) { // [xx::xx]:port format 
     361#else 
    358362      } else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2) { 
    359         if ((err = rak::address_info::get_address_info(address, PF_INET, SOCK_STREAM, &ai)) != 0) 
     363#endif 
     364        if ((err = rak::address_info::get_address_info(address,PF_UNSPEC, SOCK_STREAM, &ai)) != 0) 
    360365          throw torrent::input_error("Could not bind address: " + std::string(rak::address_info::strerror(err)) + "."); 
    361366 
    362367        saPtr = ai->address(); 
  • src/command_peer.cc

    diff -Nru rtorrent-0.8.7.orig/src/command_peer.cc rtorrent-0.8.7/src/command_peer.cc
    old new  
    6969 
    7070torrent::Object 
    7171retrieve_p_address(torrent::Peer* peer) { 
    72   return rak::socket_address::cast_from(peer->peer_info()->socket_address())->address_str(); 
     72  const rak::socket_address *addr = rak::socket_address::cast_from(peer->peer_info()->socket_address()); 
     73#ifdef RAK_USE_INET6 
     74  if (addr->family() == rak::socket_address::af_inet6) 
     75    return "[" + addr->address_str() + "]"; 
     76  else 
     77#endif 
     78  return addr->address_str(); 
    7379} 
    7480 
    7581torrent::Object 
  • src/core/curl_get.cc

    diff -Nru rtorrent-0.8.7.orig/src/core/curl_get.cc rtorrent-0.8.7/src/core/curl_get.cc
    old new  
    8888  curl_easy_setopt(m_handle, CURLOPT_NOSIGNAL,       (long)1); 
    8989  curl_easy_setopt(m_handle, CURLOPT_FOLLOWLOCATION, (long)1); 
    9090  curl_easy_setopt(m_handle, CURLOPT_MAXREDIRS,      (long)5); 
    91   curl_easy_setopt(m_handle, CURLOPT_IPRESOLVE,      CURL_IPRESOLVE_V4); 
     91 
     92  curl_easy_setopt(m_handle, CURLOPT_IPRESOLVE,      CURL_IPRESOLVE_WHATEVER); 
     93 
    9294  curl_easy_setopt(m_handle, CURLOPT_ENCODING,       ""); 
     95#ifdef RAK_USE_INET6 
     96  m_ipv6 = false; 
     97#endif 
    9398 
    9499  m_stack->add_get(this); 
    95100} 
     
    107112  m_handle = NULL; 
    108113} 
    109114 
     115#ifdef RAK_USE_INET6 
     116void 
     117CurlGet::retry_ipv6() { 
     118  CURL* nhandle = curl_easy_duphandle(m_handle); 
     119  curl_easy_setopt(nhandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); 
     120  curl_easy_cleanup(m_handle); 
     121  m_handle = nhandle; 
     122  m_ipv6 = true; 
     123} 
     124#endif 
     125 
    110126void 
    111127CurlGet::receive_timeout() { 
    112128  return m_stack->transfer_done(m_handle, "Timed out"); 
  • src/core/curl_get.h

    diff -Nru rtorrent-0.8.7.orig/src/core/curl_get.h rtorrent-0.8.7/src/core/curl_get.h
    old new  
    5656 
    5757  void               start(); 
    5858  void               close(); 
     59#ifdef RAK_USE_INET6 
     60  bool               is_using_ipv6()    { return m_ipv6; } 
     61  void               retry_ipv6(); 
     62#endif 
    5963 
    6064  bool               is_busy() const    { return m_handle; } 
    6165  bool               is_active() const  { return m_active; } 
     
    7478  void               receive_timeout(); 
    7579 
    7680  bool               m_active; 
     81#ifdef RAK_USE_INET6 
     82  bool               m_ipv6; 
     83#endif 
    7784 
    7885  rak::priority_item m_taskTimeout; 
    7986   
  • src/core/curl_stack.cc

    diff -Nru rtorrent-0.8.7.orig/src/core/curl_stack.cc rtorrent-0.8.7/src/core/curl_stack.cc
    old new  
    111111        if (msg->msg != CURLMSG_DONE) 
    112112          throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE."); 
    113113 
     114#ifdef RAK_USE_INET6 
     115        if (msg->data.result == CURLE_COULDNT_RESOLVE_HOST) { 
     116          iterator itr = std::find_if(begin(), end(), rak::equal(msg->easy_handle, std::mem_fun(&CurlGet::handle))); 
     117 
     118          if (itr == end()) 
     119            throw torrent::internal_error("Could not find CurlGet when calling CurlStack::receive_action."); 
     120 
     121          if (!(*itr)->is_using_ipv6()) { 
     122            (*itr)->retry_ipv6(); 
     123            if (curl_multi_add_handle((CURLM*)m_handle, (*itr)->handle()) > 0) 
     124              throw torrent::internal_error("Error calling curl_multi_add_handle."); 
     125            continue; 
     126          } 
     127        } else 
     128#endif 
    114129        transfer_done(msg->easy_handle, msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result)); 
    115130      } 
    116131 
  • src/core/manager.cc

    diff -Nru rtorrent-0.8.7.orig/src/core/manager.cc rtorrent-0.8.7/src/core/manager.cc
    old new  
    301301  int err; 
    302302  rak::address_info* ai; 
    303303 
     304 
     305#ifdef RAK_USE_INET6 
     306  if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 && 
     307      (err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0) 
     308#else 
    304309  if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0) 
     310#endif 
    305311    throw torrent::input_error("Could not set bind address: " + std::string(rak::address_info::strerror(err)) + "."); 
    306312   
    307313  try { 
     
    335341  int err; 
    336342  rak::address_info* ai; 
    337343 
     344#ifdef RAK_USE_INET6 
     345  if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 && 
     346      (err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0) 
     347#else 
    338348  if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0) 
     349#endif 
    339350    throw torrent::input_error("Could not set local address: " + std::string(rak::address_info::strerror(err)) + "."); 
    340351   
    341352  try { 
  • src/display/window_peer_list.cc

    diff -Nru rtorrent-0.8.7.orig/src/display/window_peer_list.cc rtorrent-0.8.7/src/display/window_peer_list.cc
    old new  
    6868  int x = 2; 
    6969  int y = 0; 
    7070 
    71   m_canvas->print(x, y, "IP");     x += 16; 
     71#ifdef RAK_USE_INET6 
     72  m_canvas->print(x, y, "IP");      x += 25; 
     73#else 
     74  m_canvas->print(x, y, "IP");      x += 16; 
     75#endif 
    7276  m_canvas->print(x, y, "UP");      x += 7; 
    7377  m_canvas->print(x, y, "DOWN");    x += 7; 
    7478  m_canvas->print(x, y, "PEER");    x += 7; 
     
    99103 
    100104    x = 0; 
    101105 
     106    std::string ip_address = rak::socket_address::cast_from(p->address())->address_str(); 
     107#ifdef RAK_USE_INET6 
     108    if (ip_address.size() >= 24) { 
     109      ip_address.replace(ip_address.begin() + 21, ip_address.end(), "..."); 
     110    } 
     111#endif 
     112 
    102113    m_canvas->print(x, y, "%c %s", 
    103114                    range.first == *m_focus ? '*' : ' ', 
    104                     rak::socket_address::cast_from(p->address())->address_str().c_str()); 
     115                    ip_address.c_str()); 
     116#ifdef RAK_USE_INET6 
     117    x += 27; 
     118#else 
    105119    x += 18; 
     120#endif 
    106121 
    107122    m_canvas->print(x, y, "%.1f", (double)p->up_rate()->rate() / 1024); x += 7; 
    108123    m_canvas->print(x, y, "%.1f", (double)p->down_rate()->rate() / 1024); x += 7; 
  • src/utils/socket_fd.cc

    diff -Nru rtorrent-0.8.7.orig/src/utils/socket_fd.cc rtorrent-0.8.7/src/utils/socket_fd.cc
    old new  
    7171  check_valid(); 
    7272  int opt = p; 
    7373 
     74#ifdef RAK_USE_INET6 
     75  if (m_ipv6_socket) 
     76    return setsockopt(m_fd, IPPROTO_IPV6, IPV6_TCLASS, &opt, sizeof(opt)) == 0; 
     77  else 
     78#endif 
    7479  return setsockopt(m_fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)) == 0; 
    7580} 
    7681 
     
    130135 
    131136bool 
    132137SocketFd::open_stream() { 
     138#ifdef RAK_USE_INET6 
     139  m_fd = socket(rak::socket_address::pf_inet6, SOCK_STREAM, IPPROTO_TCP); 
     140  if (m_fd == -1) { 
     141    m_ipv6_socket = false; 
     142    return (m_fd = socket(rak::socket_address::pf_inet, SOCK_STREAM, IPPROTO_TCP)) != -1; 
     143  } 
     144  m_ipv6_socket = true; 
     145 
     146  int zero = 0; 
     147  return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) != -1; 
     148#else 
    133149  return (m_fd = socket(rak::socket_address::pf_inet, SOCK_STREAM, IPPROTO_TCP)) != -1; 
     150#endif 
    134151} 
    135152 
    136153bool 
    137154SocketFd::open_datagram() { 
     155#ifdef RAK_USE_INET6 
     156  m_fd = socket(rak::socket_address::pf_inet6, SOCK_DGRAM, 0); 
     157  if (m_fd == -1) { 
     158    m_ipv6_socket = false; 
     159    return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1; 
     160  } 
     161  m_ipv6_socket = true; 
     162 
     163  int zero = 0; 
     164  return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) != -1; 
     165#else 
    138166  return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1; 
     167#endif 
    139168} 
    140169 
    141170bool 
     
    153182SocketFd::bind(const rak::socket_address& sa) { 
    154183  check_valid(); 
    155184 
     185#ifdef RAK_USE_INET6 
     186  if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) { 
     187    rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address(); 
     188    return !::bind(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)); 
     189  } 
     190#endif 
    156191  return !::bind(m_fd, sa.c_sockaddr(), sa.length()); 
    157192} 
    158193 
     
    160195SocketFd::bind(const rak::socket_address& sa, unsigned int length) { 
    161196  check_valid(); 
    162197 
     198#ifdef RAK_USE_INET6 
     199  if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) { 
     200    rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address(); 
     201    return !::bind(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)); 
     202  } 
     203#endif 
    163204  return !::bind(m_fd, sa.c_sockaddr(), length); 
    164205} 
    165206 
     
    167208SocketFd::connect(const rak::socket_address& sa) { 
    168209  check_valid(); 
    169210 
     211#ifdef RAK_USE_INET6 
     212  if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) { 
     213    rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address(); 
     214    return !::connect(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)) || errno == EINPROGRESS; 
     215  } 
     216#endif 
    170217  return !::connect(m_fd, sa.c_sockaddr(), sa.length()) || errno == EINPROGRESS; 
    171218} 
    172219 
    173220bool 
     221SocketFd::getsockname(rak::socket_address *sa) { 
     222  check_valid(); 
     223 
     224  socklen_t len = sizeof(rak::socket_address); 
     225  if (::getsockname(m_fd, sa->c_sockaddr(), &len)) { 
     226    return false; 
     227  } 
     228 
     229#ifdef RAK_USE_INET6 
     230  if (m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) { 
     231    *sa = sa->sa_inet6()->normalize_address(); 
     232  } 
     233#endif 
     234 
     235  return true; 
     236} 
     237 
     238bool 
    174239SocketFd::listen(int size) { 
    175240  check_valid(); 
    176241 
     
    182247  check_valid(); 
    183248  socklen_t len = sizeof(rak::socket_address); 
    184249 
     250#ifdef RAK_USE_INET6 
     251  if (sa == NULL) { 
     252    return SocketFd(::accept(m_fd, NULL, &len)); 
     253  } 
     254  int fd = ::accept(m_fd, sa->c_sockaddr(), &len); 
     255  if (fd != -1 && m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) { 
     256    *sa = sa->sa_inet6()->normalize_address(); 
     257  } 
     258  return SocketFd(fd); 
     259#else 
    185260  return SocketFd(::accept(m_fd, sa != NULL ? sa->c_sockaddr() : NULL, &len)); 
     261#endif 
    186262} 
    187263 
    188264// unsigned int 
  • src/utils/socket_fd.h

    diff -Nru rtorrent-0.8.7.orig/src/utils/socket_fd.h rtorrent-0.8.7/src/utils/socket_fd.h
    old new  
    8080  bool                bind(const rak::socket_address& sa); 
    8181  bool                bind(const rak::socket_address& sa, unsigned int length); 
    8282  bool                connect(const rak::socket_address& sa); 
     83  bool                getsockname(rak::socket_address* sa); 
    8384 
    8485  bool                listen(int size); 
    8586  SocketFd            accept(rak::socket_address* sa); 
     
    9192  inline void         check_valid() const; 
    9293 
    9394  int                 m_fd; 
     95#ifdef RAK_USE_INET6 
     96  bool                m_ipv6_socket; 
     97#endif 
    9498}; 
    9599 
    96100}