分类目录归档:未分类

dart-在model classes里序列化JSON

user.dart

class User {
  final String name;
  final String email;

  User(this.name, this.email);

  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        email = json['email'];

  Map<string, dynamic> toJson() => {
        'name': name,
        'email': email,
      };
}

hello.dart

import 'dart:convert';
import 'user.dart';

String jsonString = '''
{
  "name": "John Smith",
  "email": "john@example.com"
}
''';


void main() {
    Map<String, dynamic> userMap = jsonDecode(jsonString);

    var user = User.fromJson(userMap);

    print('Howdy, ${user.name}!');
    print('We sent the verification link to ${user.email}.');

    String json = jsonEncode(user);
    print(json);
}

被调用的代码根本不需要担心序列化 JSON 数据的问题。然而,你仍然需要模型类。你当然会希望序列化数据在一个生产环境的应用里能奏效。在实践中,User.fromJson() 和 User.toJson() 方法都需要单元测试以便验证正确的行为。

使用 dart:convert 手动序列化 JSON 数据

将下列内容保存为 hello.dart

import 'dart:convert';


String jsonString = '''
{
  "name": "John Smith",
  "email": "john@example.com"
}
''';



void main() {

    Map user = jsonDecode(jsonString);

    print('Howdy, ${user['name']}!');
    print('We sent the verification link to ${user['email']}.');
}

运行
dart hello.dart

各运营商的VoWiFI服务

统一由3gpp来管理的

https://www.freecheckdomain.com/cn/dnsCheck.html
https://dnschecker.org/
来检测

中国联通,此域名不存在
epdg.epc.mnc001.mcc460.pub.3gppnetwork.org


马来 U Mobile
epdg.epc.mnc018.mcc502.pub.3gppnetwork.org
123.136.110.180
123.136.100.132


泰国 AIS
epdg.epc.mnc003.mcc520.pub.3gppnetwork.org
119.31.121.14
119.31.123.26


MCC 520 泰国 Thailand
MNC 01 AIS
03 AIS
15 AIS
23 AIS
—————
MCC 502 马来西亚 Malaysia
01 Telekom
11 MTX Utara
12 Maxis
13 TM Touch
16 DIGI
17 Maxis
18 U Mobile
—————

epdg.epc.mnc260.mcc310.pub.3gppnetwork.org CNAME epdg.epc.geo.mnc260.mcc310.pub.3gppnetwork.org
epdg.epc.geo.mnc260.mcc310.pub.3gppnetwork.org 208.54.36.3
208.54.40.3
208.54.148.227
208.54.87.3
208.54.2.67
208.54.39.35 (可用)

epdg.epc.mnc260.mcc310.pub.3gppnetwork.org epdg.epc.geo.mnc260.mcc310.pub.3gppnetwork.org
208.54.2.67 (可用)
————-

UDP port 500或4500 是 Internet Security Association and Key Management Protocol (ISAKMP)

UDP PORT 4500是 UDP-encapsulated ESP and IKE
——————–
在OpenWRT的 /etc/config/firewall里有放行的配置

config rule                 
        option name 'Allow-IPSec-ESP'
        option src 'wan'       
        option dest 'lan'
        option proto 'esp'   
        option target 'ACCEPT'   

config rule                   
        option name 'Allow-ISAKMP'
        option src 'wan'              
        option dest 'lan'    
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

IPSEC建立分为三个阶段:phase1(建立IKE SA)、phase1.5(xauth,可选)、phase2(建立最终SA并协商SA参数)

IPSEC建立好之后,用ESP协议封装报文。ESP是等同于UDP\TCP的协议,IP协议号是50(因此ESP并不是UDP的上层协议,而是跟UDP\TCP平行协议)

当IKE在阶段一进行NAT监测时候,发现网络中存在NAT,IKE会把端口从500改到4500,后续的ESP流量前面加一个UDP的头,端口4500

在vowifi场景下,NAT是肯定存在的,所以500端口只有第一个请求才会用到,后面都是4500,(而且4500这个 UDP-encapsulated ESP and IKE是不可以配置和更改的,是RFC规定死的 )。

高通基带MBN

/vendor/firmware_mnt 独立分区

/vendor/firmware_mnt/image
vsimapp
voicepri
modem

/vendor/firmware_mnt/image/modem_pr/mcfg/configs/mcfg_sw
SEA 东南亚 下面有泰国的 AIS, 菲律宾 Globe, 马来 UMobile

UMobile/Commercial/Malaysia/mcfg_sw.mbn
Globe/Commercial/PH/mcfg_sw.mbn
AIS/Commercial/Thailand/mcfg_sw.mbn

China/CU/Commercial/OpenMkt/mcfg_sw.mbn
China/CU/Commercial/VoLTE/mcfg_sw.mbn
China/CMCC/Commercial/Volte_OpenMkt/mcfg_sw.mbn

支持VoWiFI的运营商

VoWiFi, 也成 WiFi Calling (Wi-Fi 通話)

澳大利亚:
amaysim https://www.amaysim.com.au/
Optus http://www.optus.com.au/iphone
Telstra http://www.telstra.com.au/iphone
Vodafone http://www.vodafone.com.au/
—————-
柬埔寨
Smart http://www.smart.com.kh/
————-
香港
1O1O 和 CSL http://1010.hkcsl.com/jsp/home/index.jsp
Three http://iphone.three.com.hk/website/chi/home/index.html
中国移动 https://eshop.hk.chinamobile.com/tc/AppleFamily.html
HKBN https://www.hkbn.net/personal/mobile/tc/
SmarTone http://www.smartone.com/tc/
SunMobile https://www.sunmobile.com.hk/iphone/carriersupport
———————
澳门

Three http://iphone.three.com.mo/
——————
马来
Digi https://new.digi.com.my/
Maxis http://www.maxis.com.my/
U Mobile http://www.u.com.my/

————————-
马儿代夫
Ooredoo https://ooredoo.mv/

————–
新西兰

https://www.2degreesmobile.co.nz/help-and-support/mobile/your-phone-or-device
http://www.spark.co.nz/

—————
菲律宾
http://www.globe.com.ph/
http://www.smart.com.ph/
———–
新加坡
https://www.m1.com.sg/
https://www.singtel.com/personal/support
https://www.starhub.com/personal/support/contact-us.html
————
斯里兰卡
http://www.dialog.lk/dlg/index.jsp
http://www.mobitel.lk/

————–
台湾
http://www.aptg.com.tw/
http://iphone.emome.net/
https://www.fetnet.net/
https://www.taiwanmobile.com/

——–
泰国
http://www.ais.co.th/iPhone
https://www.dtac.co.th/en/
http://truemoveh.truecorp.co.th/

———–
越南
http://www.mobifone.vn/

————-

openwrt disable ipv6 firewall

config zone                                  
        option name 'wan'                       
        option input 'REJECT'          改成   ACCEPT     
        option output 'ACCEPT'                  
        option forward 'REJECT'         改成   ACCEPT        
        option masq '1'                      
        option mtu_fix '1'                      
        list network 'wan'  
....
config rule                            
        option name 'allow-IPV6-wrt'   
        option src 'wan'               
        option proto 'tcp'             
        option family 'ipv6'           
        option target 'ACCEPT'         
                                       
config rule                            
        option name 'Allow-IPV6-all'   
        option src 'wan'               
        option dest 'lan'              
        option family 'ipv6'        
        option target 'ACCEPT'      
        list proto 'all'   

fw4 print可以看到

...
	chain input_wan {
		meta nfproto ipv4 udp dport 68 counter accept comment "!fw4: Allow-DHCP-Renew"
		meta nfproto ipv4 icmp type 8 counter accept comment "!fw4: Allow-Ping"
		meta nfproto ipv6 meta l4proto tcp counter accept comment "!fw4: allow-IPV6-wrt"
		meta nfproto ipv4 meta l4proto igmp counter accept comment "!fw4: Allow-IGMP"
		meta nfproto ipv6 udp dport 546 counter accept comment "!fw4: Allow-DHCPv6"
		ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { 130 . 0, 131 . 0, 132 . 0, 143 . 0 } counter accept comment "!fw4: Allow-MLD"
		meta nfproto ipv6 icmpv6 type { 128, 129, 1, 3, 133, 134 } limit rate 1000/second counter accept comment "!fw4: Allow-ICMPv6-Input"
		meta nfproto ipv6 icmpv6 type . icmpv6 code { 2 . 0, 4 . 0, 4 . 1, 135 . 0, 136 . 0 } limit rate 1000/second counter accept comment "!fw4: Allow-ICMPv6-Input"
		jump reject_from_wan
	}

...
chain forward_wan {
		meta nfproto ipv6 counter jump accept_to_lan comment "!fw4: Allow-IPV6-all"
		meta nfproto ipv6 icmpv6 type { 128, 129, 1, 3 } limit rate 1000/second counter accept comment "!fw4: Allow-ICMPv6-Forward"
		meta nfproto ipv6 icmpv6 type . icmpv6 code { 2 . 0, 4 . 0, 4 . 1 } limit rate 1000/second counter accept comment "!fw4: Allow-ICMPv6-Forward"
		meta l4proto esp counter jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
		udp dport 500 counter jump accept_to_lan comment "!fw4: Allow-ISAKMP"
		jump reject_to_wan
	}

libvirt网桥设置

方法1: 用nmcli

nmcli con add    type bridge         ifname br0       stp no   con-name br0
nmcli con add    type bridge-slave   ifname eno1      master br0

默认名字为 bridge-br0 和 bridge-slave-eno1

对于stp属性,创建后,也可以开启关闭

 nmcli con modify br0 bridge.stp no

查看连接 和 活动连接

nmcli con show 
nmcli con show --active 

关闭有线连接,开启桥接

nmcli con down '有线连接 1'
nmcli con up br0

这里必须用 nmcli con show –active 显示的名字 ‘有线连接 1’
而不是 eno1

修改 /usr/share/libvirt/networks/default.xml

<network>
<name>br0</name>
<forward mode="bridge"/>
<bridge name="br0" />
</network>

或者创建一个临时文件

virsh net-define /tmp/br0.xml

启用

# virsh net-start br0
# virsh net-autostart br0
# virsh net-list --all

另外还有文件 /etc/libvirt/qemu/networks/default.xml

打印和编辑

virsh net-dumpxml default
virsh net-edit default

也可以创建和销毁

virsh net-create --file ./netpriv.xml
virsh net-destroy netpriv

也可以用iproute2来创建

ip link add name br0 type bridge
ip link set dev br0 up
添加物理接口到bridge前,先让它起来开
ip link set eth0 up
ip link set eth0 master br0
查看
/sbin/bridge link

删除桥接

ip link set eth0 nomaster
ip link set eth0 down
ip link delete br0 type bridge

python录制音频

import pyaudio
import wave
 
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1024
RECORD_SECONDS = 10
WAVE_OUTPUT_FILENAME = "file.wav"
 
audio = pyaudio.PyAudio()
 
# start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS,
                rate=RATE, input=True,
                frames_per_buffer=CHUNK)
print("recording...")
frames = []
 
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)
print("finished recording")
 
 
# stop Recording
stream.stop_stream()
stream.close()
audio.terminate()
 
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()

默认录制10秒

给headscale安装单独的DERP服务

headscale 内建 DERP服务, 在配置里启用即可

但是为了更好地中继, 可以在其他节点建立DERP中继服务

0. 先安装一个 Tailscale 客户端并注册到 Headscale

这样做的目的是让搭建的 DERP Server 开启客户端认证

1. 安装DERP

#  安装 DERP Server 
go install tailscale.com/cmd/derper@main

2. 验证

# derper --hostname=your-hostname.com --verify-clients

2022/11/25 10:19:35 no config path specified; using /var/lib/derper/derper.key
2022/11/25 10:19:35 derper: serving on :443 with TLS
2022/11/25 10:19:35 running STUN server on [::]:3478

derper –hostname=域名 -c $HOME/derper.conf -http-port -1 -a :81 –verify-clients=true –stun

解释
如果不指定 -a 参数, 则默认监听 :443
如果监听 :443 并且未指定 –certmode=manual 选项,就会 自动强制使用 –hostname 指定的域名进行 ACME 申请证书
指定了 -a 为非 :443 端口, 且没有指定 –certmode=manual 则只监听 HTTP

2.

# 复制到系统可执行目录
mv ${GOPATH}/bin/derper /usr/local/bin

setcap cap_net_bind_service=+ep  /usr/local/bin/derper

# 创建用户和运行目录
useradd \
        --create-home \
        --home-dir /var/lib/derper/ \
        --system \
        --user-group \
        --shell /usr/sbin/nologin \
        derper

3. systemd配置
/lib/systemd/system/derper.service
或者 /etc/systemd/system/derper.service

[Unit]
Description=tailscale derper server
After=syslog.target
After=network.target

[Service]
Type=simple
User=derper
Group=derper
ExecStart=/usr/local/bin/derper -c=/var/lib/derper/derper.key -a=:8989 -stun-port=3456 -verify-clients
Restart=always
RestartSec=5

# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/derper /var/run/derper
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=derper

[Install]
WantedBy=multi-user.target

4. 启动

systemctl enable derper --now

5. 在headscale服务器上修改配置,以启用这个DERP

/etc/headscale/derper.yaml
内容为

regions:
  901:
    regionid: 901
    regioncode: cn
    regionname: "CUCC LTE"
    nodes:
      - name: cucc-derper
        regionid: 901
        # 自行更改为自己的域名
        hostname: derper.xxxxx.com
        # Derper 节点的 IP
        # ipv4: 123.123.123.123 可以不社会自
        # Derper 设置的 STUN 端口
        stunport: 3456
        stunonly: false  ###表示除了使用 STUN 服务,还可以使用 DERP 服务
        derpport: 23456   ## 默认是443

https://derp.XXXX.ccom:23456 应该能看到一个页面

6. 修改 /etc/headscale/config.yaml 的内容

derp:
  server:
    # 这里关闭 Headscale 内置的 Derper Server
    enabled: false

  # urls 留空, 保证不加载官方的默认 Derper
  urls: []


  # 这里填写 Derper 节点信息配置的绝对路径
  paths:
  - /etc/headscale/derper.yaml

  # If enabled, a worker will be set up to periodically
  # refresh the given sources and update the derpmap
  # will be set up.
  auto_update_enabled: true

  # How often should we check for DERP updates?
  update_frequency: 24h

重启headscale服务
重启客户端, 在客户端运行

tailscale netcheck

应该可以看到添加的DERP中继服务

参考资料:
https://mritd.com/2022/10/19/use-headscale-to-build-a-p2p-network/

参数

-a string
server HTTPS listen address, in form “:port”, “ip:port”, or for IPv6 “[ip]:port”. If the IP is omitted, it defaults to all interfaces. (default “:443”)

-c string
config file path

-certdir string
directory to store LetsEncrypt certs, if addr’s port is :443 (default “/root/.cache/tailscale/derper-certs”)

-certmode string
mode for getting a cert. possible options: manual, letsencrypt (default “letsencrypt”)

-hostname string
LetsEncrypt host name, if addr’s port is :443 (default “derp.tailscale.com”)

-http-port int
The port on which to serve HTTP. Set to -1 to disable. The listener is bound to the same IP (if any) as specified in the -a flag. (default 80)

-stun
whether to run a STUN server. It will bind to the same IP (if any) as the –addr flag value. (default true)

-stun-port int
The UDP port on which to serve STUN. The listener is bound to the same IP (if any) as specified in the -a flag. (default 3478)

从代码看,如果不指定config, 且以root执行, /var/lib/derper/derper.key 就是配置文件

keyname := unsafeHostnameCharacters.ReplaceAllString(hostname, “”)
crtPath := filepath.Join(certdir, keyname+”.crt”)
keyPath := filepath.Join(certdir, keyname+”.key”)