308760841 发表于 2024/10/16 08:32

NexusPHP1.5 如PT客户端有V4V6地址,做种汇报数据问题

在NP1.5程序,如PT客户端同时有V4V6地址,做种汇报数据会翻倍的,如上传量下载量

在种子详情,同伴出现这样



这个,如何解决呢

小樱 发表于 2024/10/16 19:11

有些NexusPHP的pt站点禁用qbittorrent就是这个原因,多次重复汇报数据
https://bbs.itzmx.com/thread-98030-1-1.html

不过按理来说原版NexusPHP不会发生这种现象,除非qb多次重复汇报的时候还去主动改变了peerid
正常来说第一次汇报是ipv4,第二次汇报是ipv6,那么NexusPHP会重写原有客户端的ip地址改为新的ipv6

要不然在域名上把v6的aaaa解析删掉也可以解决
其实也微乎其微,私有种子用户群毕竟小,影响不算特别大,建立ipv6成功后会通过 bittorrent.peer_dual_ip 返回自身ipv4给对方
不过这个返回有个前提是建立成功,在成功之前不知道对方2个ip地址中的另一个ip地址,此时可能因为端口未打开引起建立失败无法进行交换ip信息
虽然同时汇报A和AAAA是最终解决办法,但是tracker服务器并不承认一个peerid拥有2个地址,甚至可能因为双次请求拉黑名单

308760841 发表于 2024/10/16 22:48

域名没解析V6. 这有什么好的方法解决呢

小樱 发表于 2024/10/17 04:23

308760841 发表于 2024/10/16 22:48
域名没解析V6. 这有什么好的方法解决呢

那可能是站点使用了CDN,然后用户通过hosts文件绑定了ipv6的节点服务器到域名上,可以在CDN或者源站上做个检测,访问地址是ipv6就禁止
如果是使用CF cloudflare,可以用waf功能,匹配"IP 源地址"
值填写
中国电信
240e::/16
中国联通
2408::/16
中国移动
2409::/16

https://developers.cloudflare.com/waf/tools/lists/custom-lists/
https://developers.cloudflare.com/waf/tools/ip-access-rules/parameters/

但是屏蔽ipv6访问不是最好的解决办法,而是要找到php文件中哪里有问题将其修复才是正确的,比如说对比下当前站点使用的文件与原版NexusPHP的差异

308760841 发表于 2024/10/17 08:33

应该是NP1.5的bug, 不关CDN的事, 2019年,那时流行双宽带叠加。如会员双宽带叠加,有双IP,上传汇报数据也是翻倍的,上传速度超100M被封号

小樱 发表于 2024/10/17 19:14

308760841 发表于 2024/10/17 08:33
应该是NP1.5的bug, 不关CDN的事, 2019年,那时流行双宽带叠加。如会员双宽带叠加,有双IP,上传汇报数据 ...

使用NexusPHP原版测试没有这个bug,无法复现,就算ip地址在多频繁切换ip,也只会记录一条ip数据
你先对比下 announce.php 文件是否有不同
记得点回复按钮,不然收不到回复提醒

308760841 发表于 2024/10/17 22:13

对比announce.php,基本不变,只是在最后加VIP不计下载量与种子认领
if (count($updateset)) // Update only when there is change in peer counts
{
        $updateset[] = "visible = 'yes'";
        $updateset[] = "last_action = $dt";
        sql_query("UPDATE torrents SET " . join(",", $updateset) . " WHERE id = $torrentid");
}

if($client_familyid != 0 && $client_familyid != $az['clientselect']){//20221119
        $USERUPDATESET[] = "clientselect = ".sqlesc($client_familyid);
}       
/**
* VIP do not calculate downloaded
* @since 20221119
*/
if ($az['class'] == UC_VIP) {
    foreach ($USERUPDATESET as $key => $value) {
      if (preg_match("/downloaded/i", $value)) {
            unset($USERUPDATESET[$key]);
      }
    }
}
if(count($USERUPDATESET) && $userid)
{
        sql_query("UPDATE users SET " . join(",", $USERUPDATESET) . " WHERE id = ".$userid);
        //种子认领20181127
        //sql_query("UPDATE my_torrents_claim SETm_up=m_up+".($trueupthis+0)." ,m_down=m_down+".(0+$truedownthis)." ,m_seedtime=m_seedtime+".($self['announcetime']+0)." WHERE torrent_id = $torrentid and user_id =$userid");
    //20181210new
        sql_query("UPDATE my_torrents_claim SETm_up=m_up+".($trueupthis+0)." ,m_down=m_down+".(0+$truedownthis)." WHERE torrent_id = $torrentid and user_id =$userid");
       
}
if($userid)
{
    //20181210种子认领做种时间
        //20181210 update 20181211
        $m_res = @mysql_fetch_array(@sql_query("SELECT uploaded,downloaded,started,last_action,prev_action FROM peers WHERE torrent=$torrentid AND seeder ='yes' AND userid=" . sqlesc($userid)));
        $prev_action = strtotime($m_res['prev_action']);
        if($prev_action>0){
                $m_seedtime = strtotime($m_res['last_action'])-strtotime($m_res['prev_action']);
                sql_query("UPDATE my_torrents_claim SETm_seedtime=m_seedtime+".($m_seedtime+0)." WHERE torrent_id = $torrentid and user_id =$userid");
        }else{
                $m_seedtime = strtotime($m_res['last_action'])-strtotime($m_res['started']);
                sql_query("UPDATE my_torrents_claim SETm_seedtime=m_seedtime+".($m_seedtime+0)." WHERE torrent_id = $torrentid and user_id =$userid");
        }
       
}
benc_resp_raw($resp);

不是切换IP,要客户端同时有2个IP才汇报数据翻倍的

小樱 发表于 2024/10/18 00:32

308760841 发表于 2024/10/17 22:13
对比announce.php,基本不变,只是在最后加VIP不计下载量与种子认领




对的,我说的就是客户端有多个ip的意思
你这段代码有很多次套娃my_torrents_claim操作,增加上传(m_up)和下载(m_down)数据,可以确定就是这段代码的问题
在20181210new这一段里面,后面的UPDATE操作没有注释掉,后续产生的if($userid)重复几次看起来挺可疑的,应该是这个引起的?要找个php大佬确认一下这段代码怎么修复,下方这份修复代码这可能报错500无法正常工作,由于代码中涉及到数据库更新,注意备份数据库在尝试。
if (count($updateset)) {
    $updateset[] = "visible = 'yes'";
    $updateset[] = "last_action = $dt";
    sql_query("UPDATE torrents SET " . join(",", $updateset) . " WHERE id = $torrentid");
}

if ($client_familyid != 0 && $client_familyid != $az['clientselect']) {
    $USERUPDATESET[] = "clientselect = ".sqlesc($client_familyid);
}

if ($az['class'] == UC_VIP) {
    foreach ($USERUPDATESET as $key => $value) {
      if (preg_match("/downloaded/i", $value)) {
            unset($USERUPDATESET[$key]);
      }
    }
}

if (count($USERUPDATESET) && $userid) {
    sql_query("UPDATE users SET " . join(",", $USERUPDATESET) . " WHERE id = ".$userid);

    $torrentsClaimUpdate = "m_up=m_up+".($trueupthis+0).", m_down=m_down+".(0+$truedownthis);
    sql_query("UPDATE my_torrents_claim SET $torrentsClaimUpdate WHERE torrent_id = $torrentid and user_id =$userid");
}

if ($userid) {
    $m_res = @mysql_fetch_array(@sql_query("SELECT uploaded, downloaded, started, last_action, prev_action FROM peers WHERE torrent=$torrentid AND seeder ='yes' AND userid=" . sqlesc($userid)));
    $prev_action = strtotime($m_res['prev_action']);
    if ($prev_action > 0) {
      $m_seedtime = strtotime($m_res['last_action']) - $prev_action;
    } else {
      $m_seedtime = strtotime($m_res['last_action']) - strtotime($m_res['started']);
    }
   
    if ($m_seedtime > 0) {
      sql_query("UPDATE my_torrents_claim SET m_seedtime=m_seedtime+".($m_seedtime+0)." WHERE torrent_id = $torrentid and user_id =$userid");
    }
}

benc_resp_raw($resp);

308760841 发表于 2024/10/18 10:18

sql_query("UPDATE my_torrents_claim SETm_up=m_up+".($trueupthis+0)." ,m_down=m_down+".(0+$truedownthis)." WHERE torrent_id = $torrentid and user_id =$userid");
改成
$torrentsClaimUpdate = "m_up=m_up+".($trueupthis+0).", m_down=m_down+".(0+$truedownthis);
    sql_query("UPDATE my_torrents_claim SET $torrentsClaimUpdate WHERE torrent_id = $torrentid and user_id =$userid");
是吗

308760841 发表于 2024/10/18 10:37

我想不是这个问题。记得某会员在2019年,双宽带的,在天空站(HDSKY)也是超速度封号

308760841 发表于 2024/10/18 14:00

看了HDU与南洋PT站,种子详情,同伴也是出重复情况

小樱 发表于 2024/10/18 18:19

308760841 发表于 2024/10/18 14:00
看了HDU与南洋PT站,种子详情,同伴也是出重复情况

你看一下本站的,用的是原版,是不是就没有这种现象?

308760841 发表于 2024/10/18 22:06

本帖最后由 308760841 于 2024/10/18 22:08 编辑

见图

小樱 发表于 2024/10/18 22:44

308760841 发表于 2024/10/18 22:06
见图


目前分析一个人,作弊或者双开客户端
相同的peerid,出现了不同的port端口
等多捕获几个人数据看看


第二位用户,所有行为发生在相同端口,拥有6个客户端peerid发生改变,可以判断对方存在作弊行为,或者对方使用了6个客户端进行做种并且端口号配置错误在相同的一个端口号上
用户有问题,程序会根据peerid变化来做检测
这些用户不正常的行为,网站程序对于这种应该直接判断为作弊的
发起的tracker就不规范,就比如说第一位用户那个抓包图,不可能一直两个端口来回跳动
客户端重启peer一定会发生改变不存在会相同的情况
刚才第二位抓包是每次发起的请求都会发生改变peer
可以百分之百判断是作弊 或者我猜测是使用了qb匿名模式 等会上电脑我复现一下试试
qb有个匿名模式,不知道启用后会不会每次都发生改变 如果每次都发生改变,那么第二位用户他就是正常用户

308760841 发表于 2024/10/18 23:46

应该是NP1.5代码问题

小樱 发表于 2024/10/19 00:02

308760841 发表于 2024/10/18 23:46
应该是NP1.5代码问题

本地模拟了第一位用户的情况,频繁来回改变端口,多次测试并没有复现出现2个或者更多的现象,网站程序有正确处理port改变的情况
可能是未知的bug,暂时还找不到原因

完啦,还找不到原因
主要本地测试没办法复现,找不到如何复现这个问题

308760841 发表于 2024/10/19 22:25

小樱,能找PHP大佬解决?

308760841 发表于 2024/10/30 22:37

这个问题能解决吗

safecat 发表于 2024/12/9 13:58

从bts的公告来的,看了上面的记录,16楼无法复现这个的确是很头痛,修起来会很棘手,如果能找到一位出现此状况的会员配合小樱,应该会容易一点。
另外问题应该不是出现在所有ipv6的会员上,我的qbit跑在一台正常获取ipv6地址(240e开头)的群晖上,我并没有出现双重上报的情况。
请问lz是如何确定问题出现在 “如PT客户端同时有V4V6地址” 的状况下呢

yindebin_2011 发表于 2024/12/9 17:33

safecat 发表于 2024/12/9 13:58
从bts的公告来的,看了上面的记录,16楼无法复现这个的确是很头痛,修起来会很棘手,如果能找到一位出现此 ...

基本上跟ipv4或ipv6关系不大.
大概看了下源码. 出现问题的原因会跟很多外在的因素有关. 比如服务器的配置, 网络因素,站内的用户体量, 总的做种人数,当前服务器负载等.
也确实可以通过修改源码能规避一下问题, 当前问题应该是得到了解决了. 但不知道是使用什么方法.

小樱 发表于 2024/12/9 18:23

yindebin_2011 发表于 2024/12/9 17:33
基本上跟ipv4或ipv6关系不大.
大概看了下源码. 出现问题的原因会跟很多外在的因素有关. 比如服务器的配 ...

是的,,,本地多个ip测试完全复现不了问题,所以触发原因并不是多ip,而且通过观察这些用户,流量汇报情况是正常的,出现多次叠加可能是他那个种子认领引起的?
这是他昨天发的帖子,说修复了
https://bbs.itzmx.com/thread-110906-1-1.html

tonyzzz 发表于 2024/12/10 13:55

我是这个问题的修复人{:127:}我来说下这个问题的原因吧,bt客户端汇报的时候,会将所有的ip同时都汇报一次,拥有ipv4和ipv6双地址的客户端,会同时往announce.php发起两个请求,种子id,用户id,peerid都一样,但是ip不一样。光看代码的话,nexusphp1.5是在peers表插入之前有校验,如果peers已经有相同种子id和peerid的数据,就更新,没有就插入。
但是因为双地址客户端,两个请求时同时过来的,就产生了并发,如果服务器处理的速度不够快的话,就会出现mysql的重复插入。举个例子,首次汇报v4请求过来时,服务器查询peers表没有数据,然后就会进插入的代码逻辑,但是在执行完插入之前,v6请求也到了,v6也查了数据库peers表这时候v4的数据还没插入进去,v6这次请求也判断peers表没数据,也执行了插入操作,结果就是peers数据重复。至于为什么本地测试没有复现,一是可能本地环境数据较少,脚本处理速度够快,第二个请求查询时,第一个请求已经处理完了,就复现不出来了。第二种可能是本地测试没达到同时请求的这种并发级别
修复的话,主要是参考了nexusphp1.8,给peers表和snatched表加了唯一索引,从数据库层面杜绝重复数据。但是唯一索引防不住snatched表上传下载翻倍,1.8的做法是在请求开始阶段用redis做了锁校验,20秒判断为重复校验,60秒判断为请求频繁。1.5的话没有redis,所以我就用memcached简单处理了一下,20秒内同一个用户同一个种子,只处理一次汇报

tonyzzz 发表于 2024/12/10 14:15

本帖最后由 tonyzzz 于 2024/12/11 10:47 编辑

回帖重复了,编辑一下{:123:}

小樱 发表于 2024/12/10 19:06

tonyzzz 发表于 2024/12/10 13:55
我是这个问题的修复人我来说下这个问题的原因吧,bt客户端汇报的时候,会将所有的ip同时都汇报一次 ...

如果服务器处理的速度不够快的话

所以这就是复现的条件了,,,服务器正好卡了才能复现,所以我一直复现不了
不过从我上方的日志抓取来看,可以看时间跨度还是蛮大的,或者只要他可能是一天前重复汇报卡出来的,然后由于中途没有停止运行客户端,就会一直卡在那显示在网站上
重复汇报的时候流量的参数字段数值不会变动的,看起来遇到流量翻倍可能也是这种服务器卡了情况,但是我观察了好些qbittorrent用户没发现这个现象,计算过流量数值是正确的

页: [1]
查看完整版本: NexusPHP1.5 如PT客户端有V4V6地址,做种汇报数据问题