1. 前言

  本文分析libtorrent中LSD功能的实现源码。LSD,即Local Service Discovery,是BT下载中局域网内客户端寻找、发现节点的方法,简洁有效,易于实现。其基本原理是采用组播的形式发送报文给指定的IP网段,然后接收、解析并判断。

2. LSD协议基本内容

(1)网段
  包括IPV4和IPV6:A) 239.192.152.143:6771 (org-local) and B) [ff15::efc0:988f]:6771

(2)announce内容

BT-SEARCH * HTTP/1.1\r\n
Host: <host>\r\n
Port: <port>\r\n
Infohash: <ihash>\r\n
cookie: <cookie (optional)>\r\n
\r\n
\r\n

其中host为(1)中地址,port为自己的端口, infohash提取自torrent/magnet文件,cookie为可选项,用于过滤自己产生的回环消息使用。

3. 源码分析

(1)报文消息的生成

  这里其实很简单,就是一个字符串的替换而已

int render_lsd_packet(char* dst, int const len, int const listen_port, char const* info_hash_hex, int const cookie, char const* host)
{TORRENT_ASSERT(len > 0);return std::snprintf(dst, aux::numeric_cast<std::size_t>(len),"BT-SEARCH * HTTP/1.1\r\n""Host: %s:6771\r\n""Port: %d\r\n""Infohash: %s\r\n""cookie: %x\r\n""\r\n\r\n", host, listen_port, info_hash_hex, cookie);
}

(2)报文解析

void lsd::on_announce(udp::endpoint const& from, span<char const> buf)
{//这里是一个http消息解释器,其实就是分类读取announce报文中的各段消息,可以轻松实现http_parser p;bool error = false;p.incoming(buf, error);//检测http消息格式,是否有HTTP/1.1\r\nif (!p.header_finished() || error){#ifndef TORRENT_DISABLE_LOGGINGdebug_log("<== LSD: incomplete HTTP message");
#endifreturn;}//检测是否是BT查询if (p.method() != "bt-search"){#ifndef TORRENT_DISABLE_LOGGINGdebug_log("<== LSD: invalid HTTP method: %s", p.method().c_str());
#endifreturn;}//检测并记录端口std::string const& port_str = p.header("port");if (port_str.empty()){#ifndef TORRENT_DISABLE_LOGGINGdebug_log("<== LSD: invalid BT-SEARCH, missing port");
#endifreturn;}long const port = std::strtol(port_str.c_str(), nullptr, 10);if (port <= 0 || port >= int(std::numeric_limits<std::uint16_t>::max())){#ifndef TORRENT_DISABLE_LOGGINGdebug_log("<== LSD: invalid BT-SEARCH port value: %s", port_str.c_str());
#endifreturn;}auto const& headers = p.headers();//如果有cookie则根据cookie进行判断是否是本地loopbackauto const cookie_iter = headers.find("cookie");if (cookie_iter != headers.end()){// we expect it to be hexadecimal// if it isn't, it's not our cookie anywaylong const cookie = std::strtol(cookie_iter->second.c_str(), nullptr, 16);if (cookie == m_cookie){#ifndef TORRENT_DISABLE_LOGGINGdebug_log("<== LSD: ignoring packet (cookie matched our own): %x", m_cookie);
#endifreturn;}}//infohash的判断:相同的infohash则表示下载同一个文件,会加入到节点之中进行后续处理auto const ihs = headers.equal_range("infohash");for (auto i = ihs.first; i != ihs.second; ++i){std::string const& ih_str = i->second;if (ih_str.size() != 40){#ifndef TORRENT_DISABLE_LOGGINGdebug_log("<== LSD: invalid BT-SEARCH, invalid infohash: %s", ih_str.c_str());
#endifcontinue;}sha1_hash ih;aux::from_hex(ih_str, ih.data());//判断成功,则加入节点中,进行后续peer wire协议if (!ih.is_all_zeros()){#ifndef TORRENT_DISABLE_LOGGINGif (should_log()){debug_log("<== LSD: %s:%d ih: %s", print_address(from.address()).c_str(), int(port), ih_str.c_str());}
#endif// we got an announce, pass it on through the callbackm_callback.on_lsd_peer(tcp::endpoint(from.address(), std::uint16_t(port)), ih);}}
}

(3)除此之外就是发送和接收部分,调用boost库进行处理,实现非常容易,代码也清晰易懂,就不做赘述了

libtorrent源码分析(四)LSD实现相关推荐

  1. ABP源码分析四十七:ABP中的异常处理

    ABP源码分析四十七:ABP中的异常处理 参考文章: (1)ABP源码分析四十七:ABP中的异常处理 (2)https://www.cnblogs.com/1zhk/p/5538983.html (3 ...

  2. 【投屏】Scrcpy源码分析四(最终章 - Server篇)

    Scrcpy源码分析系列 [投屏]Scrcpy源码分析一(编译篇) [投屏]Scrcpy源码分析二(Client篇-连接阶段) [投屏]Scrcpy源码分析三(Client篇-投屏阶段) [投屏]Sc ...

  3. gSOAP 源码分析(四)

    gSOAP 源码分析(四) 2012-6-2 邵盛松 前言 本文主要说明gSOAP中对Client的认证分析 gSOAP中包含了HTTP基本认证,NTLM认证等,还可以自定义SOAP Heard实现认 ...

  4. Spring 源码分析(四) ——MVC(二)概述

    随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) from:Spring 源码分析(四) --MVC(二)概述 - 水门-kay的个人页面 - OSCHINA ...

  5. 【转】ABP源码分析四十七:ABP中的异常处理

    ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...

  6. 【转】ABP源码分析四:Configuration

    核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...

  7. 谷歌chrome浏览器的源码分析(四)

    上一次说到需要调用这个OpenURLFromTab函数,那么这个函数是做什么的呢?从名称上可能猜到它是打开网页,但是是从目前TAB页里打开呢?还是新建一个?或者使用每个TAB页一个进程呢?这些疑惑,只 ...

  8. 【转】ABP源码分析四十六:ABP ZERO中的Ldap模块

    通过AD作为用户认证的数据源.整个管理用户认证逻辑就在LdapAuthenticationSource类中实现. LdapSettingProvider:定义LDAP的setting和提供Defaut ...

  9. 【转】ABP源码分析四十五:ABP ZERO中的EntityFramework模块

    AbpZeroDbContext:配置ABP.Zero中定义的entity的Dbset EntityFrameworkModelBuilderExtensions:给PrimitiveProperty ...

  10. 【转】ABP源码分析四十三:ZERO的本地化

    ABP Zero模块扩展了ABP基础框架中的本地化功能,实现了通过数据库对本地化功能进行管理.其通过数据库保存本地化语言及其资源. ApplicationLanguage:代表本地化语言的实体类.一种 ...

最新文章

  1. 管理邮件用户(附图)---Michaelf
  2. matlab app designer制作软件_gif制作软件app
  3. Silverlight Com组件支持全解析
  4. Flink中的window知识体系与scala完整案例
  5. uClinux下移植Ne2000兼容的网卡驱动程序(转)
  6. ubuntu mv和cp命令
  7. 程序员眼中的编程语言
  8. tomcat8w.exe起到问题
  9. Python进行特征提取
  10. spring boot java.lang.NoClassDefFoundError: org/springframework/cloud/context/named/NamedContextFact
  11. 金融网络直播室软件的功能介绍
  12. 成都信息工程大学上岸软件工程专硕经验分享
  13. 用友python模块_最新用友NC6.5文件上传漏洞
  14. 仿直播礼物涂鸦/屏幕礼物涂鸦动画
  15. ios越狱c语言编译器,IT之家学院:iOS越狱插件利器之Flex — App UI修改篇
  16. Pdf格式文件怎么修改
  17. 2050年这些职业将逐渐被AI(人工智能)取代
  18. 机器学习:什么是无监督学习(Unsupervised Learning)?
  19. 静态链接之与静态库的链接
  20. Android出海攻略(一):Google Play 上架扫盲

热门文章

  1. lora终端连接云服务器_云服务器如何连接LoRa网关
  2. 群雄逐鹿,AI如何落地刷脸支付
  3. 二重积分计算(几何法)
  4. svn和git 常用的命令
  5. Java 垃圾回收算法
  6. 图解PLC与变频器通讯接线
  7. 零基础学模拟电路--3.同相放大器、反相放大器、加法器、减法器、积分器、微分器
  8. NDK 开发之 Android LOG 工具类
  9. Idea打包Jar文件
  10. 大一c语言试题及答案解析,大一c语言期末题及参考答案.doc