Total Pageviews

Wednesday, 23 September 2026

mac上的小工具mos让你的滚轮爽如触控板

 一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具, 让你的滚轮爽如触控板 | A lightweight tool used to smooth scrolling and set scroll direction independently for your mouse on macOS.

 http://mos.caldis.me/

让 macOS 上的鼠标滚轮和触控板一样顺滑,同时保留鼠标该有的精准控制。

Latest release macOS 10.13+ Swift 5 License: CC BY-NC 4.0

中文 · English · Deutsch · 日本語 · 한국어 · Русский · Bahasa Indonesia

官网 · 下载 · Wiki · Discussions

 

为什么是 Mos

普通滚轮在 macOS 上常常显得生硬, 这是由于滚轮的精度不足导致的。Mos 会接管鼠标滚轮事件,将滚动行为插值转换成更顺滑的滚动,同时保留每个应用、每个方向、每颗按键的控制权。

同时, 你还可以使用 Mos 对任意鼠标按键进行重新映射或改写, 以适配你的工作流。

Mos 是免费的开源菜单栏工具,支持 macOS 10.13 及以上版本。

功能亮点

  • 平滑滚动:自定义最短步长、速度增益和持续时间,也可以启用模拟触控板模式。
  • 轴向独立:垂直/水平滚动可以分别设置平滑和反向。
  • 滚动功能键:为加速、方向转换、禁用平滑滚动绑定任意自定义按键。
  • 按应用配置:每个 App 可以继承全局设置,也可以单独覆盖滚动、快捷键和按钮绑定规则。
  • 按钮绑定:录制鼠标、键盘或自定义事件,绑定到系统动作、快捷键、打开 App、运行脚本或打开文件。
  • 动作库:内置调度中心、空间切换、截图、访达操作、文档编辑、鼠标滚动等常用动作。
  • Logi/HID++ 支持:支持 Bolt、Unifying 接收器和蓝牙直连设备上的 Logitech 按钮事件,并可处理 Logi 专有动作。

 

下载与安装

手动安装

从 GitHub Releases 下载最新版本,解压后将 Mos.app 放入 /Applications。

首次启动时,macOS 可能会要求你授予 Mos 辅助功能权限。Mos 需要这项权限读取和重写滚动事件;如果授权后仍无法工作,可以参考 Wiki 中的权限排查。

Homebrew

如果你习惯用 Homebrew 管理应用:

brew install --cask mos

更新:

brew update
brew upgrade --cask mos

贡献:

Mos 是一个会处理系统输入、辅助功能权限、Logi/HID 设备和用户持久化配置的小工具。维护成本和回归风险都很真实,所以我们更欢迎小而集中的改动。

涉及 Logi/HID、辅助功能权限、签名、notarization、更新机制或真实设备测试的改动风险较高,请先在 issue 或 Discussions 中说明背景。

PR 描述中请说明变更动机、测试方式和可能影响的行为。

由 AI 开发的代码已经成为主流,我们理解现在大量的 PR 都经由 AI 生成 (包括我自己)。但提交者仍需要自行理解、整理并验证每一行代码的实际作用, 因为每个 PR 审查都有成本。

非常欢迎:

  • 小范围 bug 修复,并提供复现路径或验证说明。
  • UI/UX 细节修补,例如布局、文案、可读性和引导流程的小改进。
  • 小范围安全加固,例如更稳妥的权限状态处理、输入保护和边界检查。
  • 本地化、文档和测试补充。
  • 单一主题、变更行数较小、容易 review 的 PR。

暂不合并:

  • 未经讨论的大型新功能、模块或架构改造。
  • 大量 AI 生成的代码重写、格式化、迁移或“顺手优化”。
  • 会改变输入事件处理、权限提示、更新检查、旧用户数据读取或持久化格式的行为。
  • 一次性补全大量机器翻译,尤其是无法由母语使用者校对的翻译集。

我们欢迎任何形式的贡献,有任何建议或意见您可以给我们 提问。

如果你对新增功能非常有热情,欢迎先在 Discussions 发起讨论。

鸣谢

from  https://github.com/Caldis/Mos

前一刻卻發生震驚一幕:它為什麼發生

 

-tmd,共匪狂徒太嚣张了。使馆前的人行道属于公共空间,谁都可以在那里抗议和摆放抗议横幅。

WiFi的监控能力大增

csi和bfi。

 csi: Channel State Information(信道状态信息), 无线通信(如 Wi-Fi、5G)中用来描述信号在传输路径上的衰减、延迟和散射等.

 

无线通信/物联网:信道状态信息(Channel State Information)

在 Wi-Fi、5G 和现代通信领域,CSI 是一个核心概念:

  • 定义:它描述了一条通信链路的信道特性(如散射、衰落、距离衰减等对信号产生的影响)。

  • 应用:

    • 通信优化:帮助路由器或基站根据信道质量调整发信号的策略(如 MIMO 技术)。

    • 感知与定位(Wi-Fi Sensing):近年来热门的研究方向,通过分析空间中 CSI 的微小变化,实现无感测的人体动作识别、跌倒检测、呼吸监测甚至室内定位。

       

       

 

FSD比你看得更清楚

 

将科学上网环境共享给局域网内其它设备的各种方式

 很多朋友分不清各种共享代理方式的区别,把旁路网关与clash、v2ray等代理软件的允许局域网内的其他设备连接,以及手机的wifi热点共享混为一谈。
本期给大家盘点通过手机或者电脑将科学上网环境共享给其他设备的各种方式,基本涵盖了所有的共享方法,让你了解每种共享方式的优缺点,再根据自身情况选择适合的共享模式,解锁更多科学上网姿势。


代理共享模式(http/socks),几乎所有代理工具都支持。

电脑端

    v2rayN:https://github.com/2dust/v2rayN/releases/latest
    Clash for Windows:https://github.com/Fndroid/clash_for_windows_pkg/releases/latest
    ...

安卓端

    v2rayNG:https://github.com/2dust/v2rayNG/releases/latest
    Clash for Android:https://github.com/Kr328/ClashForAndroid/releases/latest
    ...

苹果端

    Shadowrocket:https://apps.apple.com/us/app/shadowrocket/id932747118
    QuantumultX:https://apps.apple.com/us/app/quantumult-x/id1443988620
    ...

网关共享模式:
    Windows系统不支持。
    安卓手机充当旁路网关:https://youtu.be/r6nXCgYkXTQ
    Mac、Linux使用clash的TUN模式并开启ip转发。
        Linux开启ip转发:sysctl -w net.ipv4.ip_forward=1
        Mac开启ip转发:sysctl -w net.inet.ip.forwarding=1
        Mac系统也可以直接使用clashX Pro的增强模式实现。

路由共享模式:
    Windows网卡共享;
    安卓手机Wi-Fi (USB) 共享VPN网络
        部分手机自带该功能
        VPNHotspot:https://github.com/Mygod/VPNHotspot/releases/latest
        VPNHotspot需要root权限,才能使用。

安卓投屏工具:QtScrcpy- https://github.com/barry-ran/QtScrcpy

安卓手机的VPNHotspot app

 Share your VPN connection over hotspot or repeater! (root required).

Releases Android 10-17an

Get it on Obtainium (Pre-release channel)

Connecting things to your VPN made simple. Share your VPN connection over hotspot or repeater. (root required)

This app is useful for:

  • Connecting things that don't support VPN like Chromecasts behind corporate firewalls;
  • Setting up gapps behind corporate firewalls;
  • Connecting to your mobile hotspot but you're not bothered to set up VPN on your device;
  • Identifying, monitoring and blocking (unwanted) clients;
  • Bypassing tethering limits by:
    • (recommended) Use this app with a real VPN/socksifier;
    • Use this app with some adblock/DNS apps that uses system VPN service APIs, i.e. fake VPNs; (troubleshooting/a list of apps that work)
    • Try your luck and simply use this app.

P.S. You can also do the similar on Windows, Mac, and iOS.

Features That Requires System App Installation

The following features in the app requires it to be installed under /system/priv-app since some restricted permissions are required. One way to do this is to use App systemizer for Magisk.

  • (Android 8-10, since app v2.4.0) android.permission.OVERRIDE_WIFI_CONFIG: Read/write system Wi-Fi hotspot configuration. (#117)

Installing as system app also has the side benefit of launching root daemon less frequently due to having privileged permissions listed below.

  • android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS
  • android.permission.LOCAL_MAC_ADDRESS
  • android.permission.MANAGE_USB
  • android.permission.OVERRIDE_WIFI_CONFIG
  • android.permission.READ_WIFI_CREDENTIAL
  • android.permission.TETHER_PRIVILEGED
  • android.permission.WRITE_SECURE_SETTINGS
  • Other system-app exclusive features that are not gated by permissions.

Whenever you install an app update, if there was a new protected permission addition (last updated in v2.17.1), you should update the app installed in system as well to make the system grant the privileged permission.

Q & A

Search the issue tracker for more.

What persistent changes can this app do to my system?

This app only indirectly write persistent changes through system APIs thus it should be generally pretty safe.

  1. In Supplicant mode, the repeater asks wpa_supplicant to create a persistent group on startup, which Android persists in /data/vendor/wifi/wpa/p2p_supplicant.conf or /data/misc/wifi/p2p_supplicant.conf.
  2. If you edited the system Wi-Fi hotspot configuration through this app, those changes will persist.
  3. If you toggle tethering hardware offload through this app, the Android global tether_offload_disabled setting will persist. Toggle it back in this app or the matching Developer options setting to revert it.

Routing, firewall, addresses, and daemon/service state managed by this app are cleaned up when stopped, by Clean, or upon reboot.

Failed to create group due to internal error/repeater shuts down after a while?

This could caused by the Wi-Fi channel you selected is no longer available, due to:

  1. Your device doesn't support operating on this channel, or
  2. There is some nearby Wi-Fi direct device that broadcasted that it can't operate on the channel you picked.

For maximum stability, you need to set channel = 0 so that your device will pick a channel automatically. You can also use WPS to connect your 2.4GHz-only device to force the repeater to switch from 5GHz to 2.4GHz for this time.

Private APIs used / Assumptions for Android customizations

a.k.a. things that can go wrong if this app doesn't work.

This is a list of stuff that might impact this app's functionality if unavailable. This is only meant to be an index. You can read more in the source code. API restrictions are updated up to SHA-256 checksum 9102af02fe6ab68b92464bdff5e5b09f3bd62c65d1130aaf85d3296f17d38074.

Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded or implicitly used)

  • (prior to API 30) Landroid/net/ConnectivityManager;->getLastTetherError(Ljava/lang/String;)I,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_ACTIVE_LOCAL_ONLY:Ljava/lang/String;,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_ACTIVE_TETHER:Ljava/lang/String;,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_AVAILABLE_TETHER:Ljava/lang/String;,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->ACTION_TETHER_STATE_CHANGED:Ljava/lang/String;,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_ERRORED_TETHER:Ljava/lang/String;,max-target-r
  • (since API 30) Landroid/net/ConnectivityModuleConnector;->IN_PROCESS_SUFFIX:Ljava/lang/String;
  • (since API 31) Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
  • (since API 31) Landroid/net/INetd;->ipSecUpdateSecurityPolicy(IIILjava/lang/String;Ljava/lang/String;IIII)V
  • (since API 30) Landroid/net/IIntResultListener$Stub;-><init>()V,blocked
  • (since API 30) Landroid/net/IIntResultListener;->onResult(I)V,blocked
  • (since API 30) Landroid/net/ITetheringConnector;->stopTethering(ILjava/lang/String;Landroid/net/IIntResultListener;)V,blocked
  • (since API 30) Landroid/net/ITetheringConnector;->stopTethering(ILjava/lang/String;Ljava/lang/String;Landroid/net/IIntResultListener;)V,blocked
  • (since API 30) Landroid/net/TetheringManager$ConnectorConsumer;->onConnectorAvailable(Landroid/net/ITetheringConnector;)V,blocked
  • (since API 30) Landroid/net/TetheringManager$TetheringEventCallback;->onTetherableInterfaceRegexpsChanged(Landroid/net/TetheringManager$TetheringInterfaceRegexps;)V,blocked
  • (since API 31) Landroid/net/TetheringManager$TetheringEventCallback;->onSupportedTetheringTypes(Ljava/util/Set;)V,blocked
  • (since API 30) Landroid/net/TetheringManager;->getConnector(Landroid/net/TetheringManager$ConnectorConsumer;)V,blocked
  • Landroid/net/TetheringManager;->TETHER_ERROR_*:I,blocked
  • (since API 30) Landroid/net/TetheringManager;->TETHERING_VIRTUAL:I,blocked
  • (since API 30) Landroid/net/TetheringManager;->TETHERING_WIGIG:I,blocked
  • (since API 31) Landroid/net/IpSecManager;->DIRECTION_FWD:I,blocked
  • (since API 31) Landroid/net/IpSecManager;->INVALID_SECURITY_PARAMETER_INDEX:I,blocked
  • (since API 31) Landroid/net/wifi/SoftApCapability;->getCountryCode()Ljava/lang/String;,blocked
  • (since API 33) Landroid/net/wifi/SoftApConfiguration$Builder;->setRandomizedMacAddress(Landroid/net/MacAddress;)Landroid/net/wifi/SoftApConfiguration$Builder;,blocked
  • (since API 31) Landroid/net/wifi/SoftApConfiguration;->BAND_TYPES:[I,blocked
  • (since API 31) Landroid/net/wifi/SoftApInfo;->getApInstanceIdentifier()Ljava/lang/String;,blocked
  • Landroid/net/wifi/ISoftApCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/ISoftApCallback;,lo-prio,max-target-o
  • (since API 33) Landroid/net/wifi/IWifiManager;->registerLocalOnlyHotspotSoftApCallback(Landroid/net/wifi/ISoftApCallback;Landroid/os/Bundle;)V,blocked
  • (prior to API 31) Landroid/net/wifi/IWifiManager;->registerSoftApCallback(Landroid/os/IBinder;Landroid/net/wifi/ISoftApCallback;I)V,max-target-o
  • (since API 31) Landroid/net/wifi/IWifiManager;->registerSoftApCallback(Landroid/net/wifi/ISoftApCallback;)V,blocked
  • (since API 33) Landroid/net/wifi/IWifiManager;->unregisterLocalOnlyHotspotSoftApCallback(Landroid/net/wifi/ISoftApCallback;Landroid/os/Bundle;)V,blocked
  • (prior to API 31) Landroid/net/wifi/IWifiManager;->unregisterSoftApCallback(I)V,max-target-o
  • (since API 31) Landroid/net/wifi/IWifiManager;->unregisterSoftApCallback(Landroid/net/wifi/ISoftApCallback;)V,blocked
  • (since API 31) Landroid/net/wifi/WifiClient;->getApInstanceIdentifier()Ljava/lang/String;,blocked
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->AP_BAND_2GHZ:I,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->AP_BAND_5GHZ:I,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->AP_BAND_ANY:I,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->apBand:I,unsupported
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->apChannel:I,unsupported
  • (since API 30) Landroid/net/wifi/WifiContext;->ACTION_RESOURCES_APK:Ljava/lang/String;,blocked
  • (since API 30) Landroid/net/wifi/WifiContext;-><init>(Landroid/content/Context;)V,blocked
  • Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/net/wifi/WifiManager;Landroid/os/Looper;Landroid/net/wifi/WifiManager$SoftApCallback;)V
  • Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/net/wifi/WifiManager;Ljava/util/concurrent/Executor;Landroid/net/wifi/WifiManager$SoftApCallback;)V,blocked
  • Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/net/wifi/WifiManager;Ljava/util/concurrent/Executor;Landroid/net/wifi/WifiManager$SoftApCallback;I)V,blocked
  • Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Ljava/util/concurrent/Executor;Landroid/net/wifi/WifiManager$SoftApCallback;I)V
  • (prior to API 30) Landroid/net/wifi/WifiManager$SoftApCallback;->onNumClientsChanged(I)V,greylist-max-o
  • (since API 33) Landroid/net/wifi/WifiManager;->EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE:Ljava/lang/String;,blocked
  • Landroid/net/wifi/WifiManager;->cancelLocalOnlyHotspotRequest()V,unsupported
  • Landroid/net/wifi/WifiManager;->mService:Landroid/net/wifi/IWifiManager;,unsupported
  • Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->MAC_ANY_ADDRESS:Landroid/net/MacAddress;,blocked
  • Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->mNetworkName:Ljava/lang/String;,blocked
  • (since API 30) Landroid/net/wifi/p2p/WifiP2pGroup;->interfaceAddress:[B,unsupported
  • Landroid/net/wifi/p2p/WifiP2pManager;->startWps(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/WpsInfo;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,unsupported
  • Landroid/hardware/wifi/supplicant/V1_0/IfaceType;->P2P:I
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;->getService()Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;->getInterface(Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$IfaceInfo;Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$getInterfaceCallback;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$getInterfaceCallback;->onValues(Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;Landroid/hardware/wifi/supplicant/V1_0/ISupplicantIface;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;->listInterfaces(Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$listInterfacesCallback;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$IfaceInfo;->name:Ljava/lang/String;
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$IfaceInfo;->type:I
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$listInterfacesCallback;->onValues(Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;Ljava/util/ArrayList;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicantP2pIface;->asInterface(Landroid/os/IHwBinder;)Landroid/hardware/wifi/supplicant/V1_0/ISupplicantP2pIface;
  • Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatusCode;->FAILURE_ARGS_INVALID:I
  • Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;->code:I
  • Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;->debugMessage:Ljava/lang/String;
  • Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;->addGroup_1_2(Ljava/util/ArrayList;Ljava/lang/String;ZI[BZ)Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;
  • Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;->castFrom(Landroid/os/IHwInterface;)Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;
  • Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;->setMacRandomization(Z)Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;
  • (since API 30) Landroid/os/ServiceManager;->waitForDeclaredService(Ljava/lang/String;)Landroid/os/IBinder;,blocked
  • (since API 30) Landroid/os/ServiceManager;->waitForService(Ljava/lang/String;)Landroid/os/IBinder;,blocked
  • (since API 30) Lcom/android/server/wifi/SupplicantStaIfaceHalAidlMainlineImpl;->isServiceAvailable(Landroid/content/Context;)Z
  • (since API 30) Landroid/system/wifi/mainline_supplicant/IMainlineSupplicant$Stub;->asInterface(Landroid/os/IBinder;)Landroid/system/wifi/mainline_supplicant/IMainlineSupplicant;
  • (since API 30) Landroid/system/wifi/mainline_supplicant/IMainlineSupplicant;->getVendorSupplicant()Lcom/android/wifi/x/android/hardware/wifi/supplicant/ISupplicant;
  • (prior to API 30) Landroid/provider/Settings$Global;->SOFT_AP_TIMEOUT_ENABLED:Ljava/lang/String;,lo-prio,max-target-o
  • (on API 34) Landroid/service/quicksettings/TileService;->mToken:Landroid/os/IBinder;,lo-prio,max-target-o
  • (prior to API 30) Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I,max-target-q
  • (prior to API 30) Lcom/android/internal/R$array;->config_tether_usb_regexs:I,max-target-q
  • (prior to API 30) Lcom/android/internal/R$array;->config_tether_wifi_regexs:I,max-target-q
  • (on API 29) Lcom/android/internal/R$bool;->config_wifi_p2p_mac_randomization_supported:I,blacklist
  • (prior to API 30) Lcom/android/internal/R$integer;->config_wifi_framework_soft_ap_timeout_delay:I,greylist-max-o
  • Lcom/android/internal/R$string;->config_ethernet_iface_regex:I,lo-prio,max-target-o
  • (since API 31) Lcom/android/server/IpSecService;->FULL_MASK:I
  • (since API 30) Lcom/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlBase;->HAL_INSTANCE_NAME:Ljava/lang/String;
  • (since API 30) Lcom/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlMainlineImpl;->MAINLINE_SUPPLICANT_SERVICE_NAME:Ljava/lang/String;
  • Lcom/android/server/wifi/p2p/WifiP2pServiceImpl;->ANONYMIZED_DEVICE_ADDRESS:Ljava/lang/String;
  • (since API 30) Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;
  • (since API 33) Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;,unsupported
  • (since API 33) Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;,unsupported
  • (prior to API 33) Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,unsupported
  • (prior to API 33) Ljava/lang/invoke/MethodHandles$Lookup;->ALL_MODES:I,lo-prio,max-target-o

See mobile/src/hiddenApiStubs for hidden whitelisted/system APIs as well as partial SDK-class stubs.

Nonexported system resources:

  • (since API 30) @com.android.networkstack.tethering:array/config_tether_bluetooth_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_ncm_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_usb_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_wifi_p2p_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_wifi_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_wigig_regexs
  • (since API 30) @com.android.wifi.resources:bool/config_wifi_p2p_mac_randomization_supported
  • (since API 31) @com.android.wifi.resources:integer/config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond
  • (since API 30) @com.android.wifi.resources:integer/config_wifiFrameworkSoftApShutDownTimeoutMilliseconds

Other:

  • (prior to API 30) Activity com.android.settings/.Settings$TetherSettingsActivity is assumed to be exported.
  • P2P HIDL fallback probes generated supplicant HIDL Java classes from Android 10 wifi-service.jar and Android 11+ AOSP Wi-Fi service-wifi.jar com.android.wifi.x.* jarjar packages.
  • P2P AIDL mode probes the Wi-Fi mainline service wifi_mainline_supplicant from live service-wifi.jar to recover the stable vendor supplicant AIDL binder before falling back to direct vendor HAL registration.
  • IPv6 NAT mode depends on the iptables TPROXY and NFQUEUE targets and transparent sockets. ICMPv6 Echo interception uses app-owned queue 30000 and assumes queued downstream packets expose six-byte source hardware-address metadata through NFQA_HWADDR.
  • (since API 30) Relevant tethering APEX classes used here, including android.net.ITetheringConnector, may be jarjar-relocated under the optional prefixes android.net.connectivity or com.android.connectivity.
  • (since API 31) Relevant netd APEX classes used here, including android.net.INetd*, may be jarjar-relocated under the optional prefixes android.net.connectivity or com.android.connectivity.
  • (since API 30) When runtime TetheringEventCallback.onLocalOnlyInterfacesChanged is present, AOSP dispatches startup tether-state callbacks from one executor.execute { ... } block in onCallbackStarted, and later tether-state updates from one executor.execute { ... } block in onTetherStatesChanged.
  • The Rust DNS proxy submits upstream queries through android_res_nsend/android_res_nresult. To keep daemon tasks nonblocking while still using android_res_nresult as the public result reader/closer, it waits for dnsproxyd to close the one-shot resnsend client socket before reading the result. This assumes resnsend writes the complete resolver result before returning and the socket receive buffer can hold that result until the framework socket listener closes the client socket.
  • For ip rule priorities, AOSP local-network/tethering priorities are assumed to be 17000/18000 on API 29..30 and 20000/21000 on API 31+. VPNHotspot uses the 17500..17900 or 20500..20900 gap between them.
  • For route-table numbers, Android interface tables are assumed to start at ifindex + 1000; IPv6 NAT TPROXY uses table 900 to stay below that range and away from AOSP fixed tables 97..99 and kernel built-ins.
  • Clean flushes table 900 because that table is reserved by VPNHotspot. IPv6 NAT also adds its deterministic ULA /64 route to Android's shared local_network route table 97; Clean never flushes that table and only deletes VPNHotspot prefixes reconstructed from current interface names.
  • For packet marks, Android fwmark is assumed to use low bits for netId and routing metadata.
  • IPv6 NAT fwmark fallback for TPROXY uses masked high reserved bits 0x10000000/0x10000000. That fallback is expected on only kernels without effective FRA_IP_PROTO policy-rule support, which upstream Linux added in 4.17. Probe cleanup deletes at most one rule, omitting FRA_IP_PROTO when support or the mutation outcome is uncertain; repeated stale-rule deletion is reserved for Clean.
  • Daemon reply sockets use the AOSP local-network protected mark 0x00030063, which assumes LOCAL_NET_ID = 99 plus the explicitlySelected and protectedFromVpn fwmark bits.

System/root command assumptions:

The following Android system binaries are assumed to be bundled and executable:

  • /system/bin/dumpsys (ipsec);
  • /system/bin/iptables-restore, /system/bin/ip6tables-restore (-w --noflush, restore input commands including -I, -D, -N, -nvx -L <chain>);
  • /system/bin/ndc (ipfwd, nat);
  • /system/bin/settings (put global);
  • /system/bin/linker or /system/bin/linker64 (path.zip!/program).

from  https://github.com/Mygod/VPNHotspot

永不被墙的vmess+ws,突破白名单限制的免费域前置CDN,无需域名和证书,快速优选gcore和fastly的IP,0-RTT的WS配置,HTTPUpgrade与WebSocket的区别


相关链接

fastly:https://www.fastly.com
fastly前置域:https://fofa.info/result?qbase64=Y2xvdWRfbmFtZT0iZmFzdGx5Ig%3D%3D
VCL脚本:

if (req.http.Upgrade) {
    return (upgrade);
}

gcore:https://www.gcore.com
gcore前置域:

gcore.com
speedtest.gcore.com
hk2-speedtest.tools.gcore.com
la2-speedtest.tools.gcore.com
jp1-speedtest.tools.gcore.com
kal-speedtest.tools.gcore.com
kx-speedtest.tools.gcore.com
lgs-speedtest.tools.gcore.com
min4-speedtest.tools.gcore.com
ny2-speedtest.tools.gcore.com
pa5-speedtest.tools.gcore.com
pl1-speedtest.tools.gcore.com
sg1-speedtest.tools.gcore.com
sp3-speedtest.tools.gcore.com
sy4-speedtest.tools.gcore.com
teg-speedtest.tools.gcore.com
ww-speedtest.tools.gcore.com



v2ray新出的meek协议,通过域前置可以实现节点永不被墙,也讲解了域前置的原理,感兴趣的朋友可以回看,虽然meek可以套用任意cdn ,但代价是必须传输标准的http数据,而http必须先由客户端发起请求,服务端才能推送数据,这种半双工的传输方式效率很低,速度有限,只能当作应急备用方案,无法作为日常科学上网使用,而今天要讲的websocket就不一样了,通过在HTTP协议头部插入Upgrade字段升级成websocket协议,一旦升级完成,WebSocket就会接管连接,然后就没HTTP啥事了,虽说是通过http升级来的,但他们是两个完全不同的协议,WebSocket并不是基于http,而是基于tcp,基于tcp的WebSocket可以实现全双工的双向通信,对比基于http的半双工meek,ws的传输效率和速度都会有很大的提升

接下来简单介绍一下ws的通信过程,如果你对这部分内容不感兴趣,可以直接点击时间轴跳转到搭建部分
以这个vmess+ws配置为例,假设我们已经套好了cdn,当我们通过浏览器访问谷歌的时候,由于配置了代理,浏览器会将请求发送到本机的v2ray客户端,v2ray拿到请求后,根据配置,将数据封装成vmess的格式,默认情况下vmess会对数据进行aes加密,并且由于底层传输方式为ws,v2ray会先发起一个http请求,内容是请求升级为ws协议,数据来到cdn服务器,如果cdn支持转发websocket,那么这条请求将会转发给host域名对应的ip地址,也就是你的vps,你的vps收到数据后,会回复一个101响应,表示协议升级成功,接下来就能使用websocket的帧格式发送数据了,你的vmess数据会封装在ws帧中,cdn会将数据转交给你的节点,节点收到数据后会一层层解封装,拿到客户端的意图,然后帮你访问对应的网站,这就是ws的基本通信过程,此时你会发现一个问题,v2ray必须先发起一个http请求将其升级为ws,并且需要等待服务器的回复,然后才能开始发送vmess数据,这样的话ws对比裸tcp就多了一个rtt的延迟,所以ws节点对比tcp要稍微慢一点,但是tcp没法套cdn,总之各有各的优势,
另外xray的ws可以实现0rtt,当你在ws路径后面加上?ed=2048的时候,客户端在发送http升级ws的请求中,会加入一个sec-websocket-protocol的子协议字段,里面会放入应该在升级之后才会开始发送的数据,也就是说在请求升级ws阶段就携带了vmess数据,从而实现0rtt,但并不是所有客户端都支持这种方式,总之在不清楚是否支持的情况下,你可以在路径后面加入?ed=2048,支持的话就会实现0rtt,不支持的话也不会报错

最后再说一下v2ray近期更新的httpUpgrade的传输协议,它主要就是升级成ws协议,但是里面不传输ws的帧格式,首先升级ws的步骤还是一样的,服务器会回复一个101响应表示升级成功,但接下来就不太一样了,在这条已经建立好的连接中传输的直接就是vmess数据,并不会再封装成ws帧,对于客户端和服务器而言都会减轻一点压力,提升性能,但cdn可能不会接受非标准的ws帧数据,感兴趣的朋友可以自行测试 ,另外httpUpgrade也有升级ws这个步骤,所以cdn也必须要支持转发websocket才行,而websocket并不是所有cdn都支持,这也是meek还能存在的原因,本期主要演示比较成熟的ws传输协议

接下来就是纯搭建步骤,为了让操作看上去很简单,所以不会讲解任何原理。

首先你需要一个ws的节点,vmess或者vless都可以,建议使用vmess,因为vless在没套tls的时候发送的是明文数据。

我使用的端口是18880,将节点导入到v2rayN中,先来测试一下真链接延迟,有延迟说明可以正常使用,接下来就可以套用域前置cdn了,先以上期介绍过的fastly为例,相关网址链接我会放在视频下方的说明栏,注册非常简单,只需要邮箱即可,如果你和我一样出现错误的提示信息,需要换个节点再重新尝试注册,接着就会收到激活邮件,然后登陆即可,跟着视频演示创建cdn,在这里随便填写一个域名,为了加深大家的印象,我填入woshiwoshiyansebuyiyangdeyanhuo.com,点击添加,接着填写这个域名对应的ip,也就是填入我们节点的ip地址,默认情况下是使用80端口回源,点击这里进行修改,在这里输入我们节点的端口,也就是18880,点击更新,接着来到websocket这里,他家的ws回源并不是免费的,只能试用一个月,不过他家的注册很简单,你甚至可以使用临时邮箱,点击试用,接着开启服务,光启动了服务还没用,还需要添加一段vcl脚本,跟着视频演示创建一个vcl片段,名称写ws,复制这段内容,粘贴到这里,点击创建,最后点击右上角的部署,这样fastly的配置就算是完成了,需要等个一两分钟才会生效,接下来给节点套上fastly的cdn,伪装域名这里填写我们刚才设置的woshiwoshiyansebuyiyangdeyanhuo.com,地址这里填写fastly家的ip,或者挂在fastly上的域名,按照上期讲过的方法随便找一个,端口改成80,测试真链接,无法正常使用,这个方式找到的域名并不是百分之百可以使用,可能已经过期了,你可以多换几个试试,我这里就直接输入英国政府的官网,这个网站挂在fastly上,有延迟说明可以正常使用,这样我们就成功的实现了域前置cdn,域名不是我们的,ip也不是我们的,从中间人的角度来看,你是通过fastly的cdn访问woshiwoshiyansebuyiyangdeyanhuo.com这个网站,这样就能做到你vps的IP绝对不会被墙,但这还不是域前置的完全体,完全体需要套tls,复制一个节点出来,将端口改成443,开启tls,sni同样填写gov.uk,点击确定,尝试测真链接,同样可以正常使用,使用这个节点进行科学上网,从中间人的角度来看,你就是在访问gov.uk这个网站,连你自定义的域名都隐藏了,当你还在偷别人证书的时候,域前置已经在用别人的证书了。

接着再来演示gcore,注册同样很简单,只需要一个邮箱即可,进入你邮箱中收到的激活链接,会自动登陆到gcore,点击这里将语言调整为中文,接着创建cdn,选择免费计划,免费计划每个月有1tb流量,账单地址随便输入,激活服务需要几分钟,耐心等待一下,自动跳转到这个页面后,点击创建cdn资源,随便输入一个域名,为了加深大家的印象,我就输入的和fastly一样,点击确认,点击添加dns记录,在ipv4地址这里填入你节点的ip地址,点击确认,他这里虽然要求我们修改域名的ns记录,但我实测发现,即使不改也可以正常使用,所以gcore也是不会验证域名所有者的,再次点击确认,打开资源设置,点击编辑此组,取消勾选使用默认端口,在这里输入你的节点端口,我的是18880,保存更改,这样gcore也配置好了,接着我们再来配置套用gcore的节点,先复制一个原始节点出来,地址改成gcore.com,端口改成80,伪装域名填写刚才设置的woshiwoshiyansebuyiyangdeyanhuo.com,点击确定,测试真链接,无法链接,因为他家的生效时间有点长,可能需要等待10-20分钟才会生效,所以需要耐心等待一下,经过漫长的等待,目前终于是通了,从中间人的角度来看,我是通过gcore的cdn访问woshiwoshiyansebuyiyangdeyanhuo.com这个网站,复制一个出来,同样的可以给他套上tls,实现完全体域前置,将端口改成443,他家的域前置有限制,并不是所有挂在他家的网站都能拿来当前置域,只能用他们的域名,我这里收集了一些子域名,随便选择一个,当然你也可以直接用gcore.com这个主域,但不建议这么做,将地址替换掉,开启tls,sni同样输入这个域名,这样我们的节点就套上了tls了,使用这个节点进行科学上网,从中间人的角度来看,你就是在访问这个jp1的网站,

套了cdn之后,你还可以进行优选ip,搭配我之前的工具可以进行快速优选,复制fastly的节点,粘贴到这里,cdn提供商选择fastly,这个工具的详细使用教程可以回看我之前的视频,点击提取节点,下方会提取出1000个他家ip的节点,再配合我之前做的全自动测速软件使用,点击这里下载,下载解压之后打开主程序,将刚才生成的1000个节点复制粘贴到工具列表,也可以同时复制gcore套了tls的节点,cdn提供商选择gcore,点击提取,同样复制到工具列表中,建议改成xray内核,这个软件的详细使用教程也可以回看之前的内容,点击一件自动测速,软件会自动进行真链接延迟测试,然后会自动进行下载速度测试,这样就可以获取到一批速度还不错的优选ip节点了,并且每个节点都是套了域前置的,不用担心你的vps被墙