diff --git a/API.md b/API.md index 601c448..ac91a64 100644 --- a/API.md +++ b/API.md @@ -1,30 +1,10 @@ -# SDLAN API交互文档 - -## 检测客户端版本 - -```text -url: /api/upgrade -method: post -params: - client_id: string - version: int - channel: string // 客户端的渠道信息 -return: - {"result": { - "upgrade_type": 0, // 升级类型,0: 不升级,1: 普通升级,2: 强制升级 - "upgrade_prompt": "升级提升语" - "upgrade_address": "升级提升语" - }} - - {"error": {"code": 1, "message": "错误描述"}} - -``` +# SDLAN 交互文档 ## SDL主动请求的接口 ### 1. 获取全部的可用网络信息 ```text -url: /api/get_all_networks +url: get_all_networks method: get return: @@ -36,7 +16,7 @@ return: ### 2. 获取单个网络信息 ```text -url: /api/get_network?id=:id +url: get_network?id=:id method: get return: {"result": @@ -47,6 +27,7 @@ return: "ipaddr": "192.168.0.1/24", "domain": "punchnet.cn", "owner_id": 1234, + "algorithm": "aes|chacha20", "disabled_clients": ["client_id_xyz", "client_id_xyz1"] } } @@ -55,58 +36,30 @@ return: ``` -### 3.token校验 +### 3. access_token校验 ```text -url: /api/auth_token +url: auth/access_token method: post params: + network_id: int, client_id: string - token: string, - version: int // 当前客户端版本 + mac: string, + ip: string, + mask_len: int, + hostname: string, + access_token: string, return: - {"result": - { - "network_id": 8, - "upgrade_type": 0, // 升级类型,0: 不升级,1: 普通升级,2: 强制升级 - "upgrade_prompt": "升级提升语" - "upgrade_address": "升级提升语" - } - } + {"result": "ok"} {"error": {"code": 1, "message": "错误描述"}} code = 1, Token does not exists code = 2, Client Connection Disable ``` -### 3.网络校验 -```text -url: /api/check_network -method: post -params: - client_id: string - code: string, - version: int // 当前客户端版本 -return: - - {"result": - { - "network_id": 8, - "upgrade_type": 0, // 升级类型,0: 不升级,1: 普通升级,2: 强制升级 - "upgrade_prompt": "升级提升语" - "upgrade_address": "升级提升语" - } - } - - {"error": {"code": 1, "message": "错误描述"}} - code = 1, Token does not exists - code = 2, Client Connection Disable -``` - - ### 4.设置节点的状态 ```text -url: /api/set_node_status +url: set_node_status method: post params: client_id: string @@ -118,21 +71,6 @@ return: {"result": "success"} ``` -### 5. 节点流量汇报(每分钟汇报一次,单位为字节数) -```text -url: /api/flow_report -method: post -params: - client_id: string - network_id: int, - forward_num: int, - p2p_num: int, - inbound_num: int -return: - - {"result": "success"} -``` - ## 管理平台请求SDLAN ### 网络管理接口 @@ -176,6 +114,23 @@ return: ``` +#### 3. 设置网络出口 +```text +url: /network/exit_node_control +method: post +params: + id: int, //网络id + action: int // 0: 关闭,1: 开启 + client_id: string // 目标节点的mac地址 + remark: string // 下发的标签,用于跟踪测试问题,可为空 + timeout: int // 超时设置,单位为秒 +return: + + {"result": "success"} + {"error": {"code": 1, "message": "错误描述"}} + +``` + ### 客户端节点管理 #### 1. 禁用节点 @@ -192,23 +147,4 @@ return: {"result": "success"} {"error": {"code": 1, "message": "错误描述"}} -``` - -#### 2. 迁移到新网络 - -```text -url: /node/move -method: post -params: - client_id: int - to_network_id: int - timeout: int - -return: - - {"result": "success"} - {"error": {"code": 1, "message": "错误描述"}} - -``` - - +``` \ No newline at end of file diff --git a/Register.md b/Register.md new file mode 100644 index 0000000..904c305 --- /dev/null +++ b/Register.md @@ -0,0 +1,189 @@ +# 注册流程 + +## 1. 发送验证码 + url: /register/sendVerfiyCode + method: POST + params: { + username: $username, + } + + result: + success: {code: 0, data: {"session_id": int}} + error: {code: -1, message: "操作失败"} + +## 2. 提交验证码 + url: /register/verfiyCode + method: POST + params: { + session_id: $session_id, + code: int + } + + result: + success: {code: 0, data: "ok"} + error: {code: -1, message: "验证码错误"} + +## 3. 注册 + url: /register/submit + method: POST + params: { + session_id: $session_id, + password: $password + } + + result: + success: {code: 0, data: "ok"} + error: {code: -1, message: "注册失败"} + + +# 找回密码流程 + +## 1. 发送验证码 + url: /password/sendVerfiyCode + method: POST + params: { + username: $username, + } + + result: + success: {code: 0, data: {"session_id": int}} + error: {code: -1, message: "操作失败"} + +## 2. 提交验证码 + url: /password/verfiyCode + method: POST + params: { + session_id: $session_id, + code: int + } + + result: + success: {code: 0, data: "ok"} + error: {code: -1, message: "验证码错误"} + +## 3. 重置 + url: /password/reset + method: POST + params: { + session_id: $session_id, + new_password: $new_password + } + + result: + success: {code: 0, data: "ok"} + error: {code: -1, message: "注册失败"} + +# 注册和找回密码公用的session的结构 + +```text + session: + { + session_id, + username, + code, + verified, + expire_at, + used + } + + ✅ 3. 必须有过期时间 + + 建议: + + 验证码:5分钟 + + session:10分钟 + + ✅ 4. 限流(强烈建议) + sendVerifyCode + + 每个 username:60 秒一次 + + 每个 IP:限制 + + ✅ 5. 防枚举(重要) + + 错误返回统一: + + "操作失败" + + 不要区分: + + 用户存在 + + 用户不存在 +``` + +# app相关的接口 + +## 1. 检查版本 + url: /app/checkUpdate + method: POST + + params: { + app_id: "your_app", // 应用标识 + platform: "macos", // 平台 + version: "1.2.3", // 当前版本 + build: 123, // 构建号(非常重要) + channel: "appstore|direct", // 渠道(可选) + } + + result: + success: { + code: 0, + data: { + has_update: true, + latest_version: "1.3.0", + latest_build: 150, + + force_update: false, + + download_url: "https://xxx.com/app.pkg", + release_notes: "修复了一些问题", + + min_supported_version: "1.0.0", + + publish_time: 1710000000 + } + } + + error: { + code: -1, + message: "检查失败" + } + +## 2. app当前隐私政策和服务条款 + url: /app/policies + method: POST + params: { + platform: "macos" + } + + result: + { + code: 0, + data: { + privacy_policy_url: "https://xxx.com/privacy", + terms_of_service_url: "https://xxx.com/terms", + + privacy_policy_version: "2026-01-01", + terms_version: "2026-01-01" + } + } + +## 3. 用户反馈 + url: /app/issue + method: POST + params: { + username: $username, + // 联系方式 + contact: $contact, + platform: "macos", + content: $content + } + + result: + { + code: 0, + data: "ok" + } \ No newline at end of file diff --git a/apps/sdlan/include/sdlan_pb.hrl b/apps/sdlan/include/sdlan_pb.hrl deleted file mode 100644 index 2a1f09f..0000000 --- a/apps/sdlan/include/sdlan_pb.hrl +++ /dev/null @@ -1,213 +0,0 @@ -%% -*- coding: utf-8 -*- -%% Automatically generated, do not edit -%% Generated by gpb_compile version 4.21.1 - --ifndef(sdlan_pb). --define(sdlan_pb, true). - --define(sdlan_pb_gpb_version, "4.21.1"). - - --ifndef('SDLV_4_INFO_PB_H'). --define('SDLV_4_INFO_PB_H', true). --record(sdl_v4_info, - {port = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - v4 = <<>> :: iodata() | undefined, % = 2, optional - nat_type = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits - }). --endif. - --ifndef('SDLV_6_INFO_PB_H'). --define('SDLV_6_INFO_PB_H', true). --record(sdl_v6_info, - {port = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - v6 = <<>> :: iodata() | undefined % = 2, optional - }). --endif. - --ifndef('SDL_DEV_ADDR_PB_H'). --define('SDL_DEV_ADDR_PB_H', true). --record(sdl_dev_addr, - {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - mac = <<>> :: iodata() | undefined, % = 2, optional - net_addr = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits - net_bit_len = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits - network_domain = <<>> :: unicode:chardata() | undefined % = 5, optional - }). --endif. - --ifndef('SDL_EMPTY_PB_H'). --define('SDL_EMPTY_PB_H', true). --record(sdl_empty, - { - }). --endif. - --ifndef('SDL_REGISTER_SUPER_PB_H'). --define('SDL_REGISTER_SUPER_PB_H', true). --record(sdl_register_super, - {version = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - installed_channel = <<>> :: unicode:chardata() | undefined, % = 2, optional - client_id = <<>> :: unicode:chardata() | undefined, % = 3, optional - dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 4, optional - pub_key = <<>> :: unicode:chardata() | undefined, % = 5, optional - token = <<>> :: unicode:chardata() | undefined, % = 6, optional - network_code = <<>> :: unicode:chardata() | undefined, % = 7, optional - hostname = <<>> :: unicode:chardata() | undefined % = 8, optional - }). --endif. - --ifndef('SDL_REGISTER_SUPER_ACK_PB_H'). --define('SDL_REGISTER_SUPER_ACK_PB_H', true). --record(sdl_register_super_ack, - {dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 1, optional - aes_key = <<>> :: iodata() | undefined, % = 2, optional - upgrade_type = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits - upgrade_prompt :: unicode:chardata() | undefined, % = 4, optional - upgrade_address :: unicode:chardata() | undefined % = 5, optional - }). --endif. - --ifndef('SDL_REGISTER_SUPER_NAK_PB_H'). --define('SDL_REGISTER_SUPER_NAK_PB_H', true). --record(sdl_register_super_nak, - {error_code = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - error_message = <<>> :: unicode:chardata() | undefined % = 2, optional - }). --endif. - --ifndef('SDL_QUERY_INFO_PB_H'). --define('SDL_QUERY_INFO_PB_H', true). --record(sdl_query_info, - {dst_mac = <<>> :: iodata() | undefined % = 1, optional - }). --endif. - --ifndef('SDL_PEER_INFO_PB_H'). --define('SDL_PEER_INFO_PB_H', true). --record(sdl_peer_info, - {dst_mac = <<>> :: iodata() | undefined, % = 1, optional - v4_info = undefined :: sdlan_pb:sdl_v4_info() | undefined, % = 2, optional - v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 3, optional - }). --endif. - --ifndef('SDL_NAT_CHANGED_EVENT_PB_H'). --define('SDL_NAT_CHANGED_EVENT_PB_H', true). --record(sdl_nat_changed_event, - {mac = <<>> :: iodata() | undefined, % = 1, optional - ip = 0 :: non_neg_integer() | undefined % = 2, optional, 32 bits - }). --endif. - --ifndef('SDL_SEND_REGISTER_EVENT_PB_H'). --define('SDL_SEND_REGISTER_EVENT_PB_H', true). --record(sdl_send_register_event, - {dst_mac = <<>> :: iodata() | undefined, % = 1, optional - nat_ip = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits - nat_port = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits - nat_type = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits - v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 5, optional - }). --endif. - --ifndef('SDL_NETWORK_SHUTDOWN_EVENT_PB_H'). --define('SDL_NETWORK_SHUTDOWN_EVENT_PB_H', true). --record(sdl_network_shutdown_event, - {message = <<>> :: unicode:chardata() | undefined % = 1, optional - }). --endif. - --ifndef('SDL_CHANGE_NETWORK_COMMAND_PB_H'). --define('SDL_CHANGE_NETWORK_COMMAND_PB_H', true). --record(sdl_change_network_command, - {dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 1, optional - aes_key = <<>> :: iodata() | undefined % = 2, optional - }). --endif. - --ifndef('SDL_COMMAND_ACK_PB_H'). --define('SDL_COMMAND_ACK_PB_H', true). --record(sdl_command_ack, - {status = false :: boolean() | 0 | 1 | undefined, % = 1, optional - message :: unicode:chardata() | undefined % = 2, optional - }). --endif. - --ifndef('SDL_FLOWS_PB_H'). --define('SDL_FLOWS_PB_H', true). --record(sdl_flows, - {forward_num = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - p2p_num = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits - inbound_num = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits - }). --endif. - --ifndef('SDL_STUN_REQUEST_PB_H'). --define('SDL_STUN_REQUEST_PB_H', true). --record(sdl_stun_request, - {cookie = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - client_id = <<>> :: unicode:chardata() | undefined, % = 2, optional - network_id = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits - mac = <<>> :: iodata() | undefined, % = 4, optional - ip = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits - nat_type = 0 :: non_neg_integer() | undefined, % = 6, optional, 32 bits - v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 7, optional - }). --endif. - --ifndef('SDL_STUN_REPLY_PB_H'). --define('SDL_STUN_REPLY_PB_H', true). --record(sdl_stun_reply, - {cookie = 0 :: non_neg_integer() | undefined % = 1, optional, 32 bits - }). --endif. - --ifndef('SDL_DATA_PB_H'). --define('SDL_DATA_PB_H', true). --record(sdl_data, - {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - src_mac = <<>> :: iodata() | undefined, % = 2, optional - dst_mac = <<>> :: iodata() | undefined, % = 3, optional - is_p2p = false :: boolean() | 0 | 1 | undefined, % = 4, optional - ttl = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits - data = <<>> :: iodata() | undefined % = 6, optional - }). --endif. - --ifndef('SDL_REGISTER_PB_H'). --define('SDL_REGISTER_PB_H', true). --record(sdl_register, - {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - src_mac = <<>> :: iodata() | undefined, % = 2, optional - dst_mac = <<>> :: iodata() | undefined % = 3, optional - }). --endif. - --ifndef('SDL_REGISTER_ACK_PB_H'). --define('SDL_REGISTER_ACK_PB_H', true). --record(sdl_register_ack, - {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - src_mac = <<>> :: iodata() | undefined, % = 2, optional - dst_mac = <<>> :: iodata() | undefined % = 3, optional - }). --endif. - --ifndef('SDL_STUN_PROBE_PB_H'). --define('SDL_STUN_PROBE_PB_H', true). --record(sdl_stun_probe, - {cookie = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - attr = 0 :: non_neg_integer() | undefined % = 2, optional, 32 bits - }). --endif. - --ifndef('SDL_STUN_PROBE_REPLY_PB_H'). --define('SDL_STUN_PROBE_REPLY_PB_H', true). --record(sdl_stun_probe_reply, - {cookie = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits - port = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits - ip = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits - }). --endif. - --endif. diff --git a/apps/sdlan/include/sdlan_tables.hrl b/apps/sdlan/include/sdlan_tables.hrl deleted file mode 100644 index 7bafce0..0000000 --- a/apps/sdlan/include/sdlan_tables.hrl +++ /dev/null @@ -1,19 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2025, -%%% @doc -%%% -%%% @end -%%% Created : 20. 1月 2025 21:35 -%%%------------------------------------------------------------------- --author("anlicheng"). - -%% ip的使用信息 --record(client, { - client_id :: binary(), - mac :: binary(), - ip :: integer(), - host_name :: binary(), - %% 当前状态 - status = normal :: normal | disabled -}). \ No newline at end of file diff --git a/apps/sdlan/src/dns_proxy/dns_cache.erl b/apps/sdlan/src/dns_proxy/dns_cache.erl deleted file mode 100644 index 98383a4..0000000 --- a/apps/sdlan/src/dns_proxy/dns_cache.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(dns_cache). --include_lib("dns_proxy.hrl"). --include_lib("dns_erlang/include/dns.hrl"). --include_lib("dns_erlang/include/dns_records.hrl"). --include_lib("dns_erlang/include/dns_terms.hrl"). - --export([init/0, lookup/1, insert/2]). - --define(TABLE, dns_cache). - -init() -> - ets:new(?TABLE, [named_table, set, public, {keypos, 2}, {read_concurrency, true}]). - -lookup(#dns_query{name = Qname, type = QType, class = QClass}) -> - Key = {Qname, QType, QClass}, - case ets:lookup(?TABLE, Key) of - [Cache = #dns_cache{expire_at = ExpireAt}] -> - Now = os:system_time(second), - case ExpireAt > Now of - true -> - {hit, Cache}; - false -> - true = ets:delete(?TABLE, Key), - miss - end; - [] -> - miss - end. - -insert(#dns_query{name = Qname, type = QType, class = QClass}, - #dns_message{answers = Answers, authority = Authority, additional = Additional, rc = RCode, aa = AA}) -> - TTLs = lists:foldl(fun(Term, Acc) -> - case Term of - #dns_rr{ttl = TTL} -> - [TTL|Acc]; - _ -> - Acc - end - end, [], Answers ++ Authority ++ Additional), - case length(TTLs) > 0 of - true -> - TTL = lists:min(TTLs), - ExpireAt = os:system_time(second) + TTL, - logger:debug("min ttl is: ~p, expire_at: ~p", [TTL, ExpireAt]), - Key = {Qname, QType, QClass}, - Cache = #dns_cache{ - key = Key, - answers = Answers, - authority = Authority, - additional = Additional, - rc = RCode, - flags = #{aa => AA}, - % unix time - expire_at = ExpireAt - }, - true = ets:insert(?TABLE, Cache); - false -> - ok - end. \ No newline at end of file diff --git a/apps/sdlan/src/dns_proxy/dns_handler.erl b/apps/sdlan/src/dns_proxy/dns_handler.erl deleted file mode 100644 index b1011ba..0000000 --- a/apps/sdlan/src/dns_proxy/dns_handler.erl +++ /dev/null @@ -1,263 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2025, -%%% @doc -%%% -%%% @end -%%% Created : 03. 12月 2025 23:00 -%%%------------------------------------------------------------------- --module(dns_handler). --author("anlicheng"). - --behaviour(gen_server). - --include_lib("dns_erlang/include/dns.hrl"). --include_lib("pkt/include/pkt.hrl"). --include("dns_proxy.hrl"). - -%% API --export([start_link/0]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --export([handle_ip_packet/5]). - --define(SERVER, ?MODULE). --define(RESOLVER_POOL, dns_resolver_pool). - -%% 协议部分 --define(TCP_PROTOCOL, 6). --define(UDP_PROTOCOL, 17). - --record(state, {}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -start_link() -> - gen_server:start_link(?MODULE, [], []). - -handle_ip_packet(Pid, Sock, SrcIp, SrcPort, Packet) when is_pid(Pid) -> - gen_server:cast(Pid, {handle_ip_packet, Sock, SrcIp, SrcPort, Packet}). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - {ok, #state{}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call(_Request, _From, State = #state{}) -> - {reply, ok, State}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast({handle_ip_packet, Sock, SrcIp, SrcPort, IpPacket}, State) -> - {#ipv4{saddr = ReqSAddr, daddr = ReqDAddr, p = Protocol}, ReqIpPayload} = pkt:ipv4(IpPacket), - case Protocol =:= ?UDP_PROTOCOL of - true -> - {#udp{sport = ReqSPort, dport = ReqDPort}, UdpPayload} = pkt:udp(ReqIpPayload), - case resolver(UdpPayload) of - {ok, DnsResp} -> - RespIpPacket = build_ip_packet(ReqDAddr, ReqSAddr, ReqDPort, ReqSPort, DnsResp), - gen_udp:send(Sock, SrcIp, SrcPort, RespIpPacket); - {error, Reason} -> - logger:notice("[dns_handler] resolver get error: ~p", [Reason]) - end; - false -> - logger:notice("[dns_handler] resolver invalid protocol: ~p", [Protocol]) - end, - {stop, normal, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info(_Info, State) -> - {noreply, State}. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== - --spec resolver(Packet :: binary()) -> {ok, Resp :: binary()} | {error, Reason :: any()}. -resolver(Packet) when is_binary(Packet) -> - resolver0(Packet, dns:decode_message(Packet)). -resolver0(Packet, QueryMsg = #dns_message{qc = 1, questions = [Question = #dns_query{name = QName, type = QType, class = QClass}|_]}) -> - %% 查找是否是内置的域名 - case sdlan_hostname_regedit:lookup(QName) of - {ok, Ip} -> - Answer = #dns_rr { - name = QName, - type = QType, - class = QClass, - ttl = 300, - data = #dns_rrdata_a { - ip = Ip - } - }, - RespMsg = QueryMsg#dns_message{ - qr = true, - ra = true, - anc = 1, - auc = 0, - adc = 0, - answers = [Answer], - authority = [], - additional = [] - }, - logger:debug("[dns_handler] punchnet inbuilt qnanme: ~p, ip: ~p", [QName, Ip]), - {ok, dns:encode_message(RespMsg)}; - error -> - %% 是否命中内部的域名后缀 - EmptyDnsResp = dns:encode_message(build_nxdomain_response(QueryMsg)), - case sdlan_domain_regedit:maybe_domain(QName) of - true -> - logger:debug("[dns_handler] punchnet inbuilt qnanme: ~p, nxdomain", [QName]), - {ok, EmptyDnsResp}; - false -> - case dns_cache:lookup(Question) of - {hit, Cache} -> - logger:debug("[dns_handler] qname: ~p, hit cache answers: ~p", [QName, Cache#dns_cache.answers]), - RespMsg = build_response(QueryMsg, Cache), - {ok, dns:encode_message(RespMsg)}; - miss -> - Ref = make_ref(), - forward_to_upstream(Ref, Packet, QueryMsg), - logger:debug("[dns_handler] cache is miss, forward_to_upstream"), - receive - {dns_resolver_reply, Ref, Resp} -> - case dns:decode_message(Resp) of - RespMsg = #dns_message{answers = Answers} -> - logger:debug("[dns_handler] get a response answers: ~p", [Answers]), - dns_cache:insert(Question, RespMsg), - {ok, Resp}; - Error -> - logger:debug("[dns_handler] parse reply get error: ~p", [Error]), - {ok, EmptyDnsResp} - end - after 5000 -> - logger:debug("[dns_handler] forward_to_upstream timeout"), - {ok, EmptyDnsResp} - end - end - end - end; -resolver0(_, Error) -> - logger:warning("[dns_handler] decode dns_query get error: ~p", [Error]), - {error, Error}. - --spec forward_to_upstream(Ref :: reference(), Request :: binary(), QueryMsg :: #dns_message{}) -> no_return(). -forward_to_upstream(Ref, Request, QueryMsg) -> - ReceiverPid = self(), - poolboy:transaction(?RESOLVER_POOL, fun(Pid) -> dns_resolver:forward(Pid, ReceiverPid, Ref, Request, QueryMsg) end). - --spec build_response(QueryMsg :: #dns_message{}, Dns_cache :: #dns_cache{}) -> RespMsg :: #dns_message{}. -build_response(QueryMsg, #dns_cache{expire_at = ExpireAt, answers = Answers, authority = Authority, additional = Additional, rc = RCode, flags = #{aa := AA}}) -> - Now = os:system_time(second), - RemainingTTL = ExpireAt - Now, - - Answers2 = [adjust_ttl(RR, RemainingTTL) || RR <- Answers], - Authority2 = [adjust_ttl(RR, RemainingTTL) || RR <- Authority], - Additional2 = [adjust_ttl(RR, RemainingTTL) || RR <- Additional], - - QueryMsg#dns_message{ - qr = true, - ra = true, - aa = AA, - rc = RCode, - anc = length(Answers2), - auc = length(Authority2), - adc = length(Additional2), - answers = Answers2, - authority = Authority2, - additional = Additional2 - }. - --spec adjust_ttl(RR :: any(), RemainingTTL :: integer()) -> any(). -adjust_ttl(RR = #dns_rr{}, RemainingTTL) -> - RR#dns_rr{ttl = max(0, RemainingTTL)}; -adjust_ttl(RR, _RemainingTTL) -> - RR. - --spec build_nxdomain_response(QueryMsg :: #dns_message{}) -> EmptyResp :: #dns_message{}. -build_nxdomain_response(QueryMsg) -> - QueryMsg#dns_message{ - qr = true, - aa = true, - ra = true, - rc = ?DNS_RCODE_NXDOMAIN, - anc = 0, - auc = 0, - adc = 0, - answers = [], - authority = [], - additional = [] - }. - --spec build_ip_packet(SAddr :: inet:ip4_address(), DAddr :: inet:ip4_address(), SPort :: integer(), DPort :: integer(), Payload :: binary()) -> IpPacket :: binary(). -build_ip_packet(SAddr, DAddr, SPort, DPort, UdpPayload) when is_integer(SPort), is_integer(DPort), is_binary(UdpPayload) -> - ULen = 8 + byte_size(UdpPayload), - RespUdpHeader = pkt:udp(#udp{ - sport = SPort, - dport = DPort, - ulen = ULen, - sum = dns_utils:udp_checksum(SAddr, DAddr, SPort, DPort, UdpPayload) - }), - IpPayload = <>, - - IpPacket0 = #ipv4{ - len = 20 + ULen, - ttl = 64, - off = 0, - mf = 0, - sum = 0, - p = ?UDP_PROTOCOL, - saddr = SAddr, - daddr = DAddr, - opt = <<>> - }, - IpCheckSum = dns_utils:ip_checksum(IpPacket0), - IpHeader = pkt:ipv4(IpPacket0#ipv4{sum = IpCheckSum}), - - <>. \ No newline at end of file diff --git a/apps/sdlan/src/dns_proxy/dns_pending_wheel.erl b/apps/sdlan/src/dns_proxy/dns_pending_wheel.erl deleted file mode 100644 index ad72903..0000000 --- a/apps/sdlan/src/dns_proxy/dns_pending_wheel.erl +++ /dev/null @@ -1,64 +0,0 @@ --module(dns_pending_wheel). - --export([start/0, insert/2, lookup/1, delete/1]). - --define(TTL, 5). --define(TICK_MS, 1000). --define(WHEEL_SIZE, (?TTL + 1)). - -%%% ===================================================== -%%% Public API -%%% ===================================================== - -start() -> - ets:new(dns_pending_data, [ordered_set, public, named_table, {read_concurrency, true}, {write_concurrency, true}]), - ets:new(dns_pending_wheel, [bag, public, named_table, {read_concurrency, true}, {write_concurrency, true}]), - start_scanner(). - --spec insert(Key :: any(), Val :: any()) -> ok. -insert(Key, Val) -> - Tick = now_tick(), - Slot = Tick rem ?WHEEL_SIZE, - ets:insert(dns_pending_data, {Key, {Val, Tick}}), - ets:insert(dns_pending_wheel, {Slot, {Key, Tick}}), - ok. - --spec lookup(Key :: any()) -> [term()]. -lookup(Key) -> - ets:lookup(dns_pending_data, Key). - --spec delete(Key :: any()) -> ok. -delete(Key) -> - ets:delete(dns_pending_data, Key), - ok. - -%%% ===================================================== -%%% Internal -%%% ===================================================== - -start_scanner() -> - {ok, spawn_link(fun tick_loop/0)}. - -%% 当前插入数据是在Tick, 而清理是从 Tick + 1 开始的,没有问题 -tick_loop() -> - Tick = now_tick(), - CleanSlot = (Tick + 1) rem ?WHEEL_SIZE, - spawn(fun() -> clean_slot(CleanSlot) end), - timer:sleep(?TICK_MS), - tick_loop(). - -clean_slot(Slot) -> - Items = ets:lookup(dns_pending_wheel, Slot), - true = ets:delete(dns_pending_wheel, Slot), - lists:foreach(fun({_, {Key, InsertTick}}) -> - case ets:lookup(dns_pending_data, Key) of - [{Key, {_Val, InsertTick}}] -> - ets:delete(dns_pending_data, Key); - _ -> - ok - end - end, Items). - --spec now_tick() -> integer(). -now_tick() -> - erlang:system_time(second). \ No newline at end of file diff --git a/apps/sdlan/src/dns_proxy/dns_resolver.erl b/apps/sdlan/src/dns_proxy/dns_resolver.erl deleted file mode 100644 index 05ca163..0000000 --- a/apps/sdlan/src/dns_proxy/dns_resolver.erl +++ /dev/null @@ -1,141 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2025, -%%% @doc -%%% -%%% @end -%%% Created : 03. 12月 2025 18:26 -%%%------------------------------------------------------------------- --module(dns_resolver). --author("anlicheng"). --include_lib("dns_erlang/include/dns.hrl"). - --behaviour(gen_server). - -%% API --export([start_link/1]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --export([forward/5]). - --define(SERVER, ?MODULE). - --record(state, { - socket, - idx :: integer(), - dns_servers = [] -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -forward(Pid, ReceiverPid, Ref, Request, QueryMsg) -> - gen_server:cast(Pid, {forward, ReceiverPid, Ref, Request, QueryMsg}). - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link(Args :: list()) -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link(Args) when is_list(Args) -> - gen_server:start_link(?MODULE, [], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - {ok, DnsServers} = application:get_env(sdlan, public_dns_servers), - {ok, Sock} = gen_udp:open(0, [binary, {active, true}]), - Idx = erlang:unique_integer([monotonic, positive]), - {ok, #state{socket = Sock, idx = Idx, dns_servers = DnsServers}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call(_Request, _From, State = #state{}) -> - {reply, ok, State}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast({forward, ReceiverPid, Ref, Request, #dns_message{id = TxId, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]}}, - State = #state{socket = Socket, idx = Idx, dns_servers = DnsServers}) -> - - lists:foreach(fun({DnsIp, DnsPort}) -> - ok = gen_udp:send(Socket, DnsIp, DnsPort, Request), - Key = {Idx, TxId, DnsIp, DnsPort, QName, QType, QClass}, - logger:debug("[dns_resolver] key: ~p, send to: ~p, packet: ~p", [Key, {DnsIp, DnsPort}, Request]), - dns_pending_wheel:insert(Key, {Ref, ReceiverPid}) - end, DnsServers), - - {noreply, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({udp, Socket, TargetIp, TargetPort, Resp}, State = #state{socket = Socket, idx = Idx}) -> - try dns:decode_message(Resp) of - #dns_message{id = TxId, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]} -> - Key = {Idx, TxId, TargetIp, TargetPort, QName, QType, QClass}, - Records = dns_pending_wheel:lookup(Key), - dns_pending_wheel:delete(Key), - resolver_reply(Records, Resp); - _ -> - ok - catch error:_ -> - ok - end, - {noreply, State}. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== - --spec resolver_reply(list(), Resp :: binary()) -> no_return(). -resolver_reply(Records, Resp) when is_binary(Resp) -> - lists:foreach(fun({_, {Ref, ReceiverPid}}) -> - case is_process_alive(ReceiverPid) of - true -> - ReceiverPid ! {dns_resolver_reply, Ref, Resp}; - false -> - ok - end - end, Records). \ No newline at end of file diff --git a/apps/sdlan/src/dns_proxy/dns_server.erl b/apps/sdlan/src/dns_proxy/dns_server.erl deleted file mode 100644 index 228f2c4..0000000 --- a/apps/sdlan/src/dns_proxy/dns_server.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(dns_server). --export([start_link/1, init/1]). - -start_link(Port) when is_integer(Port) -> - {ok, spawn_link(?MODULE, init, [Port])}. - -init(Port) -> - dns_cache:init(), - {ok, Sock} = gen_udp:open(Port, [binary, {active, true}]), - logger:debug("[dns_server] DNS Forwarder started on UDP port ~p~n", [Port]), - loop(Sock). - -loop(Sock) -> - receive - {udp, Sock, Ip, Port, Packet} -> - logger:debug("[dns_server] ip: ~p, get a packet: ~p", [{Ip, Port}, Packet]), - case dns_handler_sup:start_handler() of - {ok, HandlerPid} -> - dns_handler:handle_ip_packet(HandlerPid, Sock, Ip, Port, Packet); - Error -> - logger:debug("[dns_server] start handler get error: ~p", [Error]) - end, - loop(Sock) - end. \ No newline at end of file diff --git a/apps/sdlan/src/http_handler/file_handler.erl b/apps/sdlan/src/http_handler/file_handler.erl deleted file mode 100644 index 838e385..0000000 --- a/apps/sdlan/src/http_handler/file_handler.erl +++ /dev/null @@ -1,24 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 09. 4月 2024 14:28 -%%%------------------------------------------------------------------- --module(file_handler). --author("anlicheng"). - -%% API --export([init/2]). - -init(Req, State) -> - %% 拼接得到文件的真实路径 - FullPath = "/tmp/files/test.dmg", - %% 使用cowboy_req:reply函数返回文件内容 - {ok, Content} = file:read_file(FullPath), - Req1 = cowboy_req:reply(200, #{ - <<"Content-Type">> => <<"application/octet-stream">> - }, Content, Req), - - {ok, Req1, State}. \ No newline at end of file diff --git a/apps/sdlan/src/http_handler/network_handler.erl b/apps/sdlan/src/http_handler/network_handler.erl deleted file mode 100644 index 3475723..0000000 --- a/apps/sdlan/src/http_handler/network_handler.erl +++ /dev/null @@ -1,61 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 09. 4月 2024 14:28 -%%%------------------------------------------------------------------- --module(network_handler). --author("anlicheng"). - -%% API --export([handle_request/4]). - -handle_request("POST", "/network/create", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> - case sdlan_network_sup:ensured_network_started(NetworkId) of - {ok, Pid} when is_pid(Pid) -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {error, Reason} -> - logger:debug("[network_handler] create network: ~p, get error: ~p", [NetworkId, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"error">>)} - end; - -handle_request("POST", "/network/reload", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> - case sdlan_network:get_pid(NetworkId) of - undefined -> - case sdlan_network_sup:start_network(NetworkId) of - {ok, Pid} when is_pid(Pid) -> - sdlan_network_sup:reallocate_bind_width(), - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {error, Reason} -> - logger:debug("[network_handler] start network: ~p, get error: ~p", [NetworkId, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"error">>)} - end; - NetworkPid when is_pid(NetworkPid) -> - case sdlan_network:reload(NetworkPid) of - ok -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {error, Reason} -> - logger:debug("[network_handler] reload network: ~p, get error: ~p", [NetworkId, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"error">>)} - end - end; - -handle_request("POST", "/network/delete", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> - case sdlan_network:get_pid(NetworkId) of - undefined -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - NetworkPid when is_pid(NetworkPid) -> - case sdlan_network_sup:delete_network(NetworkId) of - ok -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {error, Reason} -> - logger:debug("[network_handler] delete network: ~p, get error: ~p", [NetworkId, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"error">>)} - end - end; - -handle_request(_, Path, _, _) -> - Path1 = list_to_binary(Path), - {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. \ No newline at end of file diff --git a/apps/sdlan/src/http_handler/node_handler.erl b/apps/sdlan/src/http_handler/node_handler.erl deleted file mode 100644 index d00aff3..0000000 --- a/apps/sdlan/src/http_handler/node_handler.erl +++ /dev/null @@ -1,72 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 09. 4月 2024 14:28 -%%%------------------------------------------------------------------- --module(node_handler). --author("anlicheng"). --include("sdlan.hrl"). --include("sdlan_pb.hrl"). --include("sdlan_tables.hrl"). - -%% API --export([handle_request/4]). - -handle_request("POST", "/node/list", _, #{<<"network_id">> := NetworkId}) when NetworkId > 0 -> - Pid = sdlan_network:get_pid(NetworkId), - UsedMap = sdlan_network:get_used_map(Pid), - - Clients = client_model:get_clients(NetworkId), - ClientInfos = lists:map(fun(#client{client_id = ClientId, mac = Mac, ip = Ip, status = Status}) -> - Info = #{ - <<"client_id">> => ClientId, - <<"mac">> => Mac, - <<"ip">> => sdlan_ipaddr:int_to_ipv4(Ip), - <<"status">> => atom_to_binary(Status) - }, - maps:merge(Info, maps:get(Mac, UsedMap, #{})) - end, Clients), - - {ok, 200, sdlan_util:json_data(ClientInfos)}; - -handle_request("POST", "/node/disable", _, #{<<"network_id">> := NetworkId, <<"client_id">> := ClientId}) when NetworkId > 0 -> - case sdlan_network:get_pid(NetworkId) of - undefined -> - {ok, 200, sdlan_util:json_error(-1, <<"network not found">>)}; - Pid -> - sdlan_network:disable_client(Pid, ClientId), - {ok, 200, sdlan_util:json_data(<<"success">>)} - end; - -handle_request("POST", "/node/move", _, #{<<"client_id">> := ClientId, <<"from_network_id">> := FromNetworkId, <<"to_network_id">> := ToNetworkId, <<"timeout">> := Timeout}) -> - case {sdlan_network:get_pid(FromNetworkId), sdlan_network:get_pid(ToNetworkId)} of - {FromPid, ToPid} when is_pid(FromPid), is_pid(ToPid) -> - case sdlan_network:dropout_client(FromPid, ClientId) of - {ok, ChannelPid, HostName} -> - Ref = sdlan_channel:move_network(ChannelPid, self(), ToPid, HostName), - receive - {command_reply, Ref, {error, Reason}} -> - logger:warning("[node_handler] client_id: ~p, move network from: ~p, to: ~p, get error: ~p", [ClientId, FromPid, ToPid, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"move failed">>)}; - {command_reply, Ref, #sdl_command_ack{status = true}} -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {command_reply, Ref, #sdl_command_ack{status = false, message = ErrorMsg}} when is_binary(ErrorMsg) -> - {ok, 200, sdlan_util:json_error(-1, <<"move failed: ", ErrorMsg/binary>>)} - after Timeout * 1000 -> - {ok, 200, sdlan_util:json_error(-1, <<"move timeout">>)} - end; - error -> - {ok, 200, sdlan_util:json_error(-1, <<"dropout from from_network error">>)} - end; - {FromPid, undefined} when is_pid(FromPid) -> - {ok, 200, sdlan_util:json_error(-1, <<"to_network not found">>)}; - {undefined, ToPid} when is_pid(ToPid) -> - {ok, 200, sdlan_util:json_error(-1, <<"from_network not found">>)} - end; - -handle_request(_, Path, _, _) -> - Path1 = list_to_binary(Path), - {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. \ No newline at end of file diff --git a/apps/sdlan/src/mnesia/client_model.erl b/apps/sdlan/src/mnesia/client_model.erl deleted file mode 100644 index edb7d9c..0000000 --- a/apps/sdlan/src/mnesia/client_model.erl +++ /dev/null @@ -1,162 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author aresei -%%% @copyright (C) 2023, -%%% @doc -%%% -%%% @end -%%% Created : 04. 7月 2023 12:31 -%%%------------------------------------------------------------------- --module(client_model). --author("aresei"). --include("sdlan_tables.hrl"). --include_lib("stdlib/include/qlc.hrl"). - -%% API --export([create_table/1, get_table_name/1]). --export([get_clients/1, get_client/2, delete_clients/1, delete_client/2, disable_client/2, alloc_ip/6]). --export([debug/1]). - -create_table(Tab) when is_atom(Tab) -> - mnesia:create_table(Tab, [ - {attributes, record_info(fields, client)}, - {record_name, client}, - {disc_copies, [node()]}, - {type, set} - ]). - --spec get_table_name(NetworkId :: integer()) -> TableName :: atom(). -get_table_name(NetworkId) when is_integer(NetworkId) -> - list_to_atom("client_" ++ integer_to_list(NetworkId)). - --spec get_client(NetworkId :: integer(), ClientId :: binary()) -> error | {ok, Client :: #client{}} . -get_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) -> - Tab = get_table_name(NetworkId), - case mnesia:dirty_read(Tab, ClientId) of - [] -> - error; - [Client|_] -> - {ok, Client} - end. - --spec get_clients(NetworkId :: integer()) -> [Client :: #client{}]. -get_clients(NetworkId) when is_integer(NetworkId) -> - Tab = get_table_name(NetworkId), - case mnesia:transaction(fun() -> mnesia:foldl(fun(R, Acc0) -> [R|Acc0] end, [], Tab) end) of - {'atomic', Items} -> - lists:reverse(Items); - {'aborted', _} -> - [] - end. - --spec delete_clients(NetworkId :: integer()) -> ok | {error, Reason :: any()}. -delete_clients(NetworkId) when is_integer(NetworkId) -> - Tab = get_table_name(NetworkId), - case mnesia:transaction(fun() -> mnesia:clear_table(Tab) end) of - {'atomic', ok} -> - ok; - {'aborted', Reason} -> - {error, Reason} - end. - --spec delete_client(NetworkId :: integer(), ClientId :: binary()) -> {ok, Client :: #client{}} | {error, Reason :: any()}. -delete_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) -> - Tab = get_table_name(NetworkId), - - Fun = fun() -> - case mnesia:read(Tab, ClientId, write) of - [] -> - mnesia:abort(not_found); - [Record] -> - mnesia:delete(Tab, ClientId, write), - {ok, Record} - end - end, - - case mnesia:transaction(Fun) of - {'atomic', {ok, Client}} -> - {ok, Client}; - {'aborted', Reason} -> - {error, Reason} - end. - --spec disable_client(NetworkId :: integer(), ClientId :: binary()) -> ok | {error, Reason :: any()}. -disable_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) -> - Tab = get_table_name(NetworkId), - Fun = fun() -> - case mnesia:read(Tab, ClientId, read) of - [] -> - ok; - [Client] -> - mnesia:write(Tab, Client#client{status = disabled}, write) - end - end, - - case mnesia:transaction(Fun) of - {'atomic', ok} -> - ok; - {'aborted', Reason} -> - {error, Reason} - end. - -%% 分配ip地址的时候,以mac地址为唯一基准 --spec alloc_ip(NetworkId :: integer(), Ips :: list(), ClientId :: binary(), Mac :: binary(), NetAddr0 :: integer(), HostName :: binary()) -> - {ok, Ip :: integer()} | {error, Reason :: any()}. -alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) when is_binary(ClientId), is_integer(NetAddr0), is_binary(Mac), is_binary(HostName) -> - case mnesia:transaction(fun() -> alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) end) of - {'atomic', Res} -> - {ok, Res}; - {'aborted', Reason} -> - {error, Reason} - end. -alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) -> - Tab = get_table_name(NetworkId), - - case mnesia:read(Tab, ClientId) of - [Client=#client{ip = Ip, status = normal}] -> - ok = mnesia:write(Tab, Client#client{mac = Mac}, write), - Ip; - [#client{status = disabled}] -> - mnesia:abort(client_disabled); - [] -> - {UsedIps, UsedHostNames} = mnesia:foldl(fun(#client{ip = Ip0, host_name = HostName0}, {IpAcc, HostNameAcc}) -> - {[Ip0|IpAcc], [HostName0|HostNameAcc]} - end, {[], []}, Tab), - case HostName =/= <<>> andalso lists:member(HostName, UsedHostNames) of - true -> - mnesia:abort(host_name_used); - false -> - case lists:member(NetAddr0, Ips) andalso not lists:member(NetAddr0, UsedIps) of - true -> - %% 如果ip没有被占用,则分配給当前请求 - Client = #client{client_id = ClientId, mac = Mac, ip = NetAddr0, host_name = HostName, status = normal}, - ok = mnesia:write(Tab, Client, write), - NetAddr0; - false -> - case Ips -- UsedIps of - [] -> - mnesia:abort(no_ip); - [Ip|_] -> - Client = #client{client_id = ClientId, mac = Mac, ip = Ip, host_name = HostName, status = normal}, - ok = mnesia:write(Tab, Client, write), - Ip - end - end - end - end. - -%%%=================================================================== -%%% helper functions -%%%=================================================================== - -debug(NetworkId) when is_integer(NetworkId) -> - Tab = get_table_name(NetworkId), - F = fun() -> - Q = qlc:q([E || E <- mnesia:table(Tab)]), - qlc:e(Q) - end, - case mnesia:transaction(F) of - {'atomic', Records} -> - lists:foreach(fun(C) -> logger:debug("client: ~p", [C]) end, Records); - {'aborted', Reason} -> - logger:warning("read clients get error: ~p", [Reason]) - end. \ No newline at end of file diff --git a/apps/sdlan/src/mnesia/mnesia_id_generator.erl b/apps/sdlan/src/mnesia/mnesia_id_generator.erl deleted file mode 100644 index cab8586..0000000 --- a/apps/sdlan/src/mnesia/mnesia_id_generator.erl +++ /dev/null @@ -1,26 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author aresei -%%% @copyright (C) 2023, -%%% @doc -%%% -%%% @end -%%% Created : 04. 7月 2023 12:31 -%%%------------------------------------------------------------------- --module(mnesia_id_generator). --author("aresei"). --include("sdlan.hrl"). - -%% API --export([next_id/1, create_table/0]). - -create_table() -> - %% id生成器 - mnesia:create_table(id_generator, [ - {attributes, record_info(fields, id_generator)}, - {record_name, id_generator}, - {disc_copies, [node()]}, - {type, ordered_set} - ]). - -next_id(Tab) when is_atom(Tab) -> - mnesia:dirty_update_counter(id_generator, Tab, 1). \ No newline at end of file diff --git a/apps/sdlan/src/mnesia/mnesia_manager.erl b/apps/sdlan/src/mnesia/mnesia_manager.erl deleted file mode 100644 index 55e18bd..0000000 --- a/apps/sdlan/src/mnesia/mnesia_manager.erl +++ /dev/null @@ -1,43 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% TODO 数据库暂时不启用 -%%% @end -%%% Created : 28. 3月 2024 11:01 -%%%------------------------------------------------------------------- --module(mnesia_manager). --author("anlicheng"). --include("sdlan.hrl"). - -%% API --export([init_database/0, join/1, copy_database/1]). - -init_database() -> - %% 清理掉以前的schema - mnesia:stop(), - mnesia:delete_schema([node()]), - - %% 创建schema - ok = mnesia:create_schema([node()]), - ok = mnesia:start(), - ok. - -%% 加入集群 -join(MasterNode) when is_atom(MasterNode) -> - net_kernel:connect_node(MasterNode). - -%% 初始化slave数据库 -copy_database(MasterNode) when is_atom(MasterNode) -> - %% 清理旧的schema - mnesia:stop(), - mnesia:delete_schema([node()]), - %% 重新启动数据库 - mnesia:start(), - - rpc:call(MasterNode, mnesia, change_config, [extra_db_nodes, [node()]]), - mnesia:change_table_copy_type(schema, node(), disc_copies), - - %% 增加表的分区复制 - % mnesia:add_table_copy(client, node(), ram_copies), - ok. \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_api.erl b/apps/sdlan/src/sdlan_api.erl deleted file mode 100644 index 8b671a4..0000000 --- a/apps/sdlan/src/sdlan_api.erl +++ /dev/null @@ -1,184 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 27. 3月 2024 16:17 -%%%------------------------------------------------------------------- --module(sdlan_api). --author("anlicheng"). - --define(API_TOKEN, <<"wv6fGyBhl*7@AsD9">>). - -%% API --export([get_all_networks/0, get_network/1]). --export([auth_token/3, node_online/3, node_offline/2, flow_report/5, network_forward_report/2, auth_network_code/3]). - --spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}. -get_all_networks() -> - case catch do_get("get_all_networks", []) of - {ok, Resp} -> - case catch jiffy:decode(Resp, [return_maps]) of - #{<<"result">> := Networks} -> - {ok, Networks}; - #{<<"error">> := #{<<"code">> := Code, <<"message">> := Message}} -> - {error, {Code, Message}}; - _ -> - {error, <<"invalid json">>} - end; - Error -> - Error - end. - --spec get_network(Id :: integer()) -> {ok, Network :: map()} | {error, Reason :: any()}. -get_network(Id) when is_integer(Id) -> - case catch do_get("get_network", [{<<"id">>, integer_to_binary(Id)}]) of - {ok, Resp} -> - case catch jiffy:decode(Resp, [return_maps]) of - #{<<"result">> := Network} -> - {ok, Network}; - #{<<"error">> := #{<<"code">> := Code, <<"message">> := Message}} -> - {error, {Code, Message}}; - _ -> - {error, <<"invalid json">>} - end; - Error -> - Error - end. - --spec auth_token(ClientId :: binary(), Token :: binary(), Version :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -auth_token(ClientId, Token, Version) when is_binary(ClientId), is_binary(Token), is_integer(Version) -> - case catch do_post("auth_token", #{<<"client_id">> => ClientId, <<"token">> => Token, <<"version">> => Version}) of - {ok, Resp} -> - case catch jiffy:decode(Resp, [return_maps]) of - Result when is_map(Result) -> - {ok, Result}; - {error, Reason} -> - {error, Reason} - end; - Error -> - Error - end. - --spec auth_network_code(ClientId :: binary(), NetworkCode :: binary(), Version :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -auth_network_code(ClientId, NetworkCode, Version) when is_binary(ClientId), is_binary(NetworkCode), is_integer(Version) -> - case catch do_post("check_network", #{<<"client_id">> => ClientId, <<"code">> => NetworkCode, <<"version">> => Version}) of - {ok, Resp} -> - case catch jiffy:decode(Resp, [return_maps]) of - Result when is_map(Result) -> - {ok, Result}; - {error, Reason} -> - {error, Reason} - end; - Error -> - Error - end. - --spec node_online(ClientId :: binary(), NetworkId :: integer(), IpAddr :: binary()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -node_online(ClientId, NetworkId, IpAddr) when is_binary(ClientId), is_integer(NetworkId), is_binary(IpAddr) -> - case catch do_post("set_node_status", #{<<"client_id">> => ClientId, <<"network_id">> => NetworkId, <<"ip_addr">> => IpAddr, <<"status">> => 1}) of - {ok, Resp} -> - {ok, catch jiffy:decode(Resp, [return_maps])}; - Error -> - Error - end. - --spec node_offline(ClientId :: binary(), NetworkId :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -node_offline(ClientId, NetworkId) when is_binary(ClientId), is_integer(NetworkId) -> - case catch do_post("set_node_status", #{<<"client_id">> => ClientId, <<"network_id">> => NetworkId, <<"status">> => 0}) of - {ok, Resp} -> - {ok, catch jiffy:decode(Resp, [return_maps])}; - Error -> - Error - end. - --spec flow_report(ClientId :: binary(), NetworkId :: integer(), ForwardNum :: integer(), P2PNum :: integer(), InboundNum :: integer()) -> - {ok, Resp :: map()} | {error, Reason :: any()}. -flow_report(ClientId, NetworkId, ForwardNum, P2PNum, InboundNum) - when is_binary(ClientId), is_integer(NetworkId), is_integer(ForwardNum), is_integer(P2PNum), is_integer(InboundNum) -> - Params = #{ - <<"client_id">> => ClientId, - <<"network_id">> => NetworkId, - <<"forward_num">> => ForwardNum, - <<"p2p_num">> => P2PNum, - <<"inbound_num">> => InboundNum - }, - case catch do_post("client_flow_report", Params) of - {ok, Resp} -> - {ok, catch jiffy:decode(Resp, [return_maps])}; - Error -> - Error - end. - --spec network_forward_report(NetworkId :: integer(), ForwardNum :: integer()) -> - {ok, Resp :: map()} | {error, Reason :: any()}. -network_forward_report(NetworkId, ForwardNum) when is_integer(NetworkId), is_integer(ForwardNum) -> - Params = #{ - <<"network_id">> => NetworkId, - <<"forward_num">> => ForwardNum - }, - case catch do_post("network_forward_report", Params) of - {ok, Resp} -> - {ok, catch jiffy:decode(Resp, [return_maps])}; - Error -> - Error - end. - --spec do_get(Uri :: string(), Params :: [{K :: binary(), V :: binary()}]) -> {ok, Response :: binary()} | {error, Reason :: any()}. -do_get(Uri, Params) when is_list(Uri), is_list(Params) -> - Token = sdlan_util:md5(<>), - {ok, Url0} = application:get_env(sdlan, api_url), - - Headers = [ - {<<"content-type">>, <<"application/json">>}, - {<<"token">>, Token} - ], - - QS0 = uri_string:compose_query(Params), - QS = iolist_to_binary(QS0), - - Url = Url0 ++ Uri ++ "?" ++ binary_to_list(QS), - case catch hackney:request(get, Url, Headers, <<>>, [{pool, false}]) of - {ok, 200, _, ClientRef} -> - {ok, RespBody} = hackney:body(ClientRef), - hackney:close(ClientRef), - {ok, RespBody}; - {ok, HttpCode, _, ClientRef} -> - {ok, RespBody} = hackney:body(ClientRef), - hackney:close(ClientRef), - {error, {HttpCode, RespBody}}; - {error, Reason} -> - {error, Reason} - end. - --spec do_post(Uri :: string(), Params :: list() | map()) -> {ok, Resp :: binary()} | {error, Reason :: any()}. -do_post(Uri, Params) when is_list(Uri), is_map(Params); is_list(Params) -> - Token = sdlan_util:md5(<>), - {ok, Url0} = application:get_env(sdlan, api_url), - - Headers = [ - {<<"content-type">>, <<"application/json">>}, - {<<"token">>, Token} - ], - - Body = iolist_to_binary(jiffy:encode(Params, [force_utf8])), - Url = Url0 ++ Uri, - - case catch hackney:request(post, Url, Headers, Body, [{pool, false}]) of - {ok, 200, _, ClientRef} -> - {ok, RespBody} = hackney:body(ClientRef), - hackney:close(ClientRef), - {ok, RespBody}; - {ok, HttpCode, _, ClientRef} -> - {ok, RespBody} = hackney:body(ClientRef), - hackney:close(ClientRef), - {error, {HttpCode, RespBody}}; - {ok, HttpCode, _} -> - {error, {HttpCode, <<"empty response">>}}; - {ok, ClientRef} -> - hackney:close(ClientRef), - {error, <<"empty response">>}; - {error, Reason} -> - {error, Reason} - end. \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_app.erl b/apps/sdlan/src/sdlan_app.erl deleted file mode 100644 index f2bd1b8..0000000 --- a/apps/sdlan/src/sdlan_app.erl +++ /dev/null @@ -1,81 +0,0 @@ -%%%------------------------------------------------------------------- -%% @doc sdlan public API -%% @end -%%%------------------------------------------------------------------- - --module(sdlan_app). - --behaviour(application). - --export([start/2, stop/1]). - -start(_StartType, _StartArgs) -> - io:setopts([{encoding, unicode}]), - %% 启动mnesia数据库 - mnesia:start(), - %% 加速内存的回收 - erlang:system_flag(fullsweep_after, 16), - - %% 启动注册表 - sdlan_hostname_regedit:init(), - sdlan_domain_regedit:init(), - dns_pending_wheel:start(), - - start_http_server(), - start_tcp_server(), - sdlan_sup:start_link(). - -stop(_State) -> - ok. - -%% internal functions - -%% 启动http服务 -start_http_server() -> - {ok, Props} = application:get_env(sdlan, http_server), - Acceptors = proplists:get_value(acceptors, Props, 50), - MaxConnections = proplists:get_value(max_connections, Props, 10240), - Backlog = proplists:get_value(backlog, Props, 1024), - Port = proplists:get_value(port, Props), - - Dispatcher = cowboy_router:compile([ - {'_', [ - {"/file/[...]", file_handler, []}, - {"/api/[...]", http_protocol, [api_handler]}, - {"/network/[...]", http_protocol, [network_handler]}, - {"/node/[...]", http_protocol, [node_handler]}, - {"/test/[...]", http_protocol, [test_handler]} - ]} - ]), - - TransOpts = [ - {port, Port}, - {num_acceptors, Acceptors}, - {backlog, Backlog}, - {max_connections, MaxConnections} - ], - - {ok, Pid} = cowboy:start_clear(http_listener, TransOpts, #{env => #{dispatch => Dispatcher}}), - - logger:debug("[iot_app] the http server start at: ~p, pid is: ~p", [Port, Pid]). - -%% 启动tcp服务 -start_tcp_server() -> - {ok, Props} = application:get_env(sdlan, tcp_server), - Acceptors = proplists:get_value(acceptors, Props, 50), - MaxConnections = proplists:get_value(max_connections, Props, 10240), - Backlog = proplists:get_value(backlog, Props, 1024), - Port = proplists:get_value(port, Props), - - TransOpts = #{ - num_acceptors => Acceptors, - max_connections => MaxConnections, - socket_opts => [ - {port, Port}, - {nodelay, false}, - {backlog, Backlog} - ] - }, - {ok, _} = ranch:start_listener('sdlan/tcp_server', ranch_tcp, TransOpts, sdlan_channel, []), - - logger:debug("[sdlan_app] the tcp server start at: ~p", [Port]). \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_channel.erl b/apps/sdlan/src/sdlan_channel.erl deleted file mode 100644 index de01c2f..0000000 --- a/apps/sdlan/src/sdlan_channel.erl +++ /dev/null @@ -1,382 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author licheng5 -%%% @copyright (C) 2020, -%%% @doc -%%% -%%% @end -%%% Created : 10. 12月 2020 上午11:17 -%%%------------------------------------------------------------------- --module(sdlan_channel). --author("licheng5"). --behaviour(gen_server). - --include("sdlan.hrl"). --include("sdlan_pb.hrl"). - -%% 心跳包监测机制 --define(PING_TICKER, 15000). - -%% 注册失败的的错误码 - -%% token不存在 --define(NAK_INVALID_TOKEN, 1). -%% 节点被禁用 --define(NAK_NODE_DISABLE, 2). -%% 没有IP地址可以用 --define(NAK_NO_IP, 3). -%% 网络错误 --define(NAK_NETWORK_FAULT, 4). -%% 内部错误 --define(NAK_INTERNAL_FAULT, 5). -%% hostname被占用 --define(NAK_HOSTNAME_USED, 6). - -%% 升级策略 --define(UPGRADE_NONE, 0). --define(UPGRADE_NORMAL, 1). --define(UPGRADE_FORCE, 2). - -%% API --export([start_link/4]). --export([publish_command/4, send_event/3, stop/2, move_network/4]). - --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --record(state, { - transport, - socket, - - client_id :: undefined | binary(), - pub_key :: undefined | binary(), - token :: undefined | binary(), - - %% 分配的ip地址 - assign_ip :: undefined | integer(), - %% 网络相关信息id - network_pid :: undefined | pid(), - %% mac地址 - mac :: undefined | binary(), - - %% 标记是否已经注册 - is_registered = false, - - %% 记录ping的次数 - ping_counter = 0, - - %% 发送消息对应的id - packet_id = 1 :: integer(), - %% 请求响应的对应关系 - inflight = #{} -}). - -%% 向通道中写入消息 --spec publish_command(Pid :: pid(), ReceiverPid :: pid(), CommandType :: integer(), Msg :: binary()) -> Ref :: reference(). -publish_command(Pid, ReceiverPid, CommandType, Msg) when is_pid(Pid), is_pid(ReceiverPid), is_integer(CommandType), is_binary(Msg) -> - Ref = make_ref(), - Pid ! {publish_command, ReceiverPid, Ref, CommandType, Msg}, - Ref. - -%% 网络迁移是一种特殊的指令信息,需要单独处理 --spec move_network(Pid :: pid(), ReceiverPid :: pid(), NetworkPid :: pid(), HostName :: binary()) -> Ref :: reference(). -move_network(Pid, ReceiverPid, NetworkPid, HostName) when is_pid(Pid), is_pid(ReceiverPid), is_pid(NetworkPid), is_binary(HostName) -> - Ref = make_ref(), - Pid ! {move_network, ReceiverPid, Ref, NetworkPid, HostName}, - Ref. - -%% 向通道中写入消息 --spec send_event(Pid :: pid(), EventType :: integer(), Event :: binary()) -> no_return(). -send_event(Pid, EventType, Event) when is_pid(Pid), is_integer(EventType), is_binary(Event) -> - Pid ! {send_event, EventType, Event}. - -%% 关闭方法 --spec stop(Pid :: pid(), Reason :: any()) -> no_return(). -stop(undefined, _Reason) -> - ok; -stop(Pid, Reason) when is_pid(Pid) -> - Pid ! {stop, Reason}. - -%%-------------------------------------------------------------------- -%% esockd callback -%%-------------------------------------------------------------------- - -start_link(Ref, _Socket, Transport, Opts) -> - {ok, proc_lib:spawn_link(?MODULE, init, [[Ref, Transport, Opts]])}. - -init([Ref, Transport, _Opts = []]) -> - {ok, Socket} = ranch:handshake(Ref), - logger:debug("[sdlan_channel] get a new connection: ~p", [Socket]), - Transport:setopts(Socket, [{active, true}, {packet, 2}]), - erlang:start_timer(?PING_TICKER, self(), ping_ticker), - gen_server:enter_loop(?MODULE, [], #state{transport = Transport, socket = Socket}). - -handle_call(_Request, _From, State) -> - {reply, ok, State}. - -handle_cast(_Msg, State) -> - {noreply, State}. - -%% 带上token或者网络id来注册 -handle_info({tcp, Sock, <>}, State=#state{transport = Transport, socket = Sock}) -> - #sdl_register_super{version = Version, client_id = ClientId, hostname = HostName, dev_addr = #sdl_dev_addr{net_addr = NetAddr0, mac = Mac}, network_code = NetworkCode, token = Token, pub_key = PubKey} = sdlan_pb:decode_msg(Body, sdl_register_super), - - %% 参数检查 - logger:debug("[sdlan_channel] client_id: ~p, public_key: ~p, token: ~p, network_code: ~p", [ClientId, PubKey, Token, NetworkCode]), - true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>), - %% Mac地址不能是广播地址 - true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)), - - AuthResult = if - Token /= <<>> -> - logger:debug("[sdlan_channel] auth token: ~p", [Token]), - sdlan_api:auth_token(ClientId, Token, Version); - NetworkCode /= <<>> -> - logger:debug("[sdlan_channel] auth network code: ~p", [NetworkCode]), - sdlan_api:auth_network_code(ClientId, NetworkCode, Version) - end, - - case AuthResult of - {ok, #{<<"result">> := #{<<"network_id">> := NetworkId, <<"upgrade_type">> := UpgradeType, <<"upgrade_prompt">> := UpgradePrompt, <<"upgrade_address">> := UpgradeAddress}}} when is_integer(NetworkId) -> - logger:debug("[sdlan_channel] client_id: ~p, mac: ~p, token: ~p, version: ~p, registerd, alloc network_id: ~p", [ClientId, sdlan_util:format_mac(Mac), Token, Version, NetworkId]), - %% 建立到network的对应关系 - case sdlan_network:get_pid(NetworkId) of - NetworkPid when is_pid(NetworkPid) -> - try sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, NetAddr0, HostName) of - {ok, Domain, NetAddr, NetBitLen, AesKey} -> - RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), - EncodedAesKey = rsa_encode(AesKey, RsaPubKey), - - RegisterSuperAck = sdlan_pb:encode_msg(#sdl_register_super_ack { - dev_addr = #sdl_dev_addr{ - network_id = NetworkId, - net_addr = NetAddr, - mac = Mac, - net_bit_len = NetBitLen, - network_domain = Domain - }, - aes_key = EncodedAesKey, - upgrade_type = UpgradeType, - upgrade_prompt = UpgradePrompt, - upgrade_address = UpgradeAddress - }), - - %% 发送确认信息 - Reply = <>, - Transport:send(Sock, Reply), - logger:debug("[sdlan_channel] client_id: ~p, mac: ~p, alloc ip: ~p, register will send ack, aes_key: ~p, enc_aes_key: ~p", - [ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(NetAddr), AesKey, EncodedAesKey]), - - %% 设置节点的在线状态 - Result = sdlan_api:node_online(ClientId, NetworkId, sdlan_ipaddr:int_to_ipv4(NetAddr)), - logger:debug("[sdlan_channel] client_id: ~p, set none online, result is: ~p", [ClientId, Result]), - case UpgradeType =:= ?UPGRADE_FORCE of - true -> - logger:warning("[sdlan_channel] client_id: ~p, need upgrade force!", [ClientId]), - {stop, normal, State}; - false -> - {noreply, State#state{client_id = ClientId, mac = Mac, assign_ip = NetAddr, network_pid = NetworkPid, pub_key = PubKey, is_registered = true}} - end; - {error, no_ip} -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: no_ip", [ClientId, Token]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NO_IP, <<"No Ip address">>)), - {stop, normal, State}; - {error, host_name_used} -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: host_name_used", [ClientId, Token]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_HOSTNAME_USED, <<"Host Name Used">>)), - {stop, normal, State}; - {error, client_disabled} -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: client_disabled", [ClientId, Token]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NODE_DISABLE, <<"Client Connection Disable">>)), - {stop, normal, State} - catch _:Error:Stack -> - logger:warning("[sdlan_channel] get error: ~p, stack: ~p", [Error, Stack]) - end; - undefined -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: network not found", [ClientId, Token]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>)), - - {stop, normal, State} - end; - {ok, #{<<"error">> := #{<<"code">> := 1, <<"message">> := Message}}} -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~ts, error_code: 1", [ClientId, Token, Message]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_INVALID_TOKEN, Message)), - {stop, normal, State}; - - {ok, #{<<"error">> := #{<<"code">> := 2, <<"message">> := Message}}} -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p, error_code: 2", [ClientId, Token, Message]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NODE_DISABLE, Message)), - {stop, normal, State}; - - {error, Reason} -> - logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p", [ClientId, Token, Reason]), - Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NETWORK_FAULT, <<"Network Error">>)), - {stop, normal, State} - end; - -handle_info({tcp, Sock, <>}, State = #state{transport = Transport, socket = Sock, network_pid = NetworkPid, mac = SrcMac, is_registered = true}) when is_pid(NetworkPid) -> - #sdl_query_info{dst_mac = DstMac} = sdlan_pb:decode_msg(Body, sdl_query_info), - case sdlan_network:peer_info(NetworkPid, SrcMac, DstMac) of - error -> - logger:debug("[sdlan_channel] query_info src_mac is: ~p, dst_mac: ~p, nat_peer not found", - [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - - Transport:send(Sock, <>), - {noreply, State}; - {ok, {NatPeer = {{Ip0, Ip1, Ip2, Ip3}, NatPort}, NatType}, V6Info} -> - logger:debug("[sdlan_channel] query_info src_mac is: ~p, dst_mac: ~p, nat_peer: ~p", - [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), NatPeer]), - - PeerInfo = sdlan_pb:encode_msg(#sdl_peer_info{ - dst_mac = DstMac, - v4_info = #sdl_v4_info { - port = NatPort, - v4 = <>, - nat_type = NatType - }, - v6_info = V6Info - }), - Transport:send(Sock, <>), - {noreply, State} - end; - -handle_info({tcp, _Sock, <<0:32, ?PACKET_PING>>}, State = #state{transport = Transport, socket = Sock, ping_counter = PingCounter}) -> - %logger:debug("[sdlan_channel] client_id: ~p, get ping", [ClientId]), - Transport:send(Sock, <<0:32, ?PACKET_PONG>>), - {noreply, State#state{ping_counter = PingCounter + 1}}; - -handle_info({timeout, _, ping_ticker}, State = #state{client_id = ClientId, ping_counter = PingCounter}) -> - %% 等待下一次的心跳检测 - erlang:start_timer(?PING_TICKER, self(), ping_ticker), - case PingCounter > 0 of - true -> - {noreply, State#state{ping_counter = 0}}; - false -> - logger:debug("[sdlan_channel] client_id: ~p, ping losted", [ClientId]), - {stop, normal, State#state{ping_counter = 0}} - end; - -%% 重新加入网络 -handle_info({move_network, ReceiverPid, Ref, NetworkPid, HostName}, - State = #state{transport = Transport, socket = Sock, client_id = ClientId, mac = Mac, pub_key = PubKey, packet_id = PacketId, inflight = Inflight, is_registered = true}) -> - - %% 建立到network的对应关系 - case sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, 0, HostName) of - {ok, Domain, NetAddr, NetBitLen, AesKey} -> - RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), - EncodedAesKey = rsa_encode(AesKey, RsaPubKey), - - {ok, NetworkId} = sdlan_network:get_network_id(NetworkPid), - %% 发送确认信息 - ChangeNetworkCommand = sdlan_pb:encode_msg(#sdl_change_network_command { - dev_addr = #sdl_dev_addr { - network_id = NetworkId, - net_addr = NetAddr, - net_bit_len = NetBitLen, - network_domain = Domain - }, - aes_key = EncodedAesKey - }), - Command = <>, - Transport:send(Sock, Command), - - %% 设置节点的在线状态 - sdlan_api:node_online(ClientId, NetworkId, sdlan_ipaddr:int_to_ipv4(NetAddr)), - - logger:debug("[sdlan_channel] client_id: ~p, move_network will send command: ~p", [ClientId, Command]), - {noreply, State#state{packet_id = PacketId + 1, assign_ip = NetAddr, network_pid = NetworkPid, inflight = maps:put(PacketId, {ReceiverPid, Ref}, Inflight)}}; - {error, Reason} -> - logger:debug("[sdlan_channel] client_id: ~p, move_network get error: ~p", [ClientId, Reason]), - Transport:send(Sock, register_nak_reply(0, ?NAK_NO_IP, <<"No Ip address">>)), - ReceiverPid ! {command_reply, Ref, {error, <<"assign_ip error, no ip free">>}}, - {noreply, State} - end; - -%% 发送指令信息 -handle_info({send_event, EventType, Event}, State = #state{transport = Transport, socket = Sock, client_id = ClientId, is_registered = true}) -> - logger:debug("[sdlan_channel] client_id: ~p, will send eventType: ~p, event: ~p", [ClientId, EventType, Event]), - Transport:send(Sock, <<0:32, ?PACKET_EVENT, EventType, Event/binary>>), - {noreply, State}; - -%% 网络流量统计 -handle_info({tcp, _Sock, <<0:32, ?PACKET_FLOW_TRACER, Body/binary>>}, State = #state{client_id = ClientId, network_pid = NetworkPid, is_registered = true}) when is_pid(NetworkPid) -> - #sdl_flows{forward_num = ForwardNum, p2p_num = P2PNum, inbound_num = InboundNum} = sdlan_pb:decode_msg(Body, sdl_flows), - {ok, NetworkId} = sdlan_network:get_network_id(NetworkPid), - ReportResult = sdlan_api:flow_report(ClientId, NetworkId, ForwardNum, P2PNum, InboundNum), - logger:debug("[sdlan_channel] flow_tracer, forward: ~p, p2p: ~p, inbound: ~p, result: ~p", [ClientId, ForwardNum, P2PNum, InboundNum, ReportResult]), - {noreply, State}; - -%% 取消注册 -handle_info({tcp, _Sock, <<0:32, ?PACKET_UNREGISTER>>}, State = #state{client_id = ClientId, network_pid = NetworkPid, is_registered = true}) when is_pid(NetworkPid) -> - logger:warning("[sdlan_channel] unregister client_id: ~p", [ClientId]), - % sdlan_network:unregister(NetworkPid, ClientId), - {stop, normal, State}; - -%% 发送指令信息 -handle_info({publish_command, ReceiverPid, Ref, CommandType, Msg}, State = #state{transport = Transport, socket = Sock, client_id = ClientId, packet_id = PacketId, inflight = Inflight, is_registered = true}) -> - logger:warning("[sdlan_channel] client_id: ~p, will publish: ~p, message: ~p", [ClientId, CommandType, Msg]), - Transport:send(Sock, <>), - {noreply, State#state{packet_id = PacketId + 1, inflight = maps:put(PacketId, {ReceiverPid, Ref}, Inflight)}}; - -%% 主机端的消息响应 -handle_info({tcp, _Sock, <>}, State = #state{client_id = ClientId, inflight = Inflight}) when PacketId > 0 -> - CommandAck = #sdl_command_ack{} = sdlan_pb:decode_msg(Body, sdl_command_ack), - - logger:debug("[sdlan_channel] client_id: ~p, get publish response message: ~p, packet_id: ~p", [ClientId, CommandAck, PacketId]), - case maps:take(PacketId, Inflight) of - error -> - logger:warning("[sdlan_channel] get unknown publish response message: ~p, packet_id: ~p", [CommandAck, PacketId]), - {ok, State}; - {{ReceiverPid, Ref}, NInflight} -> - case is_pid(ReceiverPid) andalso is_process_alive(ReceiverPid) of - true -> - ReceiverPid ! {command_reply, Ref, CommandAck}; - false -> - logger:warning("[sdlan_channel] get publish response message: ~p, packet_id: ~p, but receiver_pid is deaded", [CommandAck, PacketId]) - end, - {noreply, State#state{inflight = NInflight}} - end; - -handle_info({tcp_error, Sock, Reason}, State = #state{socket = Sock, client_id = ClientId}) -> - logger:notice("[sdlan_channel] client_id: ~p, tcp_error: ~p", [ClientId, Reason]), - {stop, normal, State}; - -handle_info({tcp_closed, Sock}, State = #state{socket = Sock, client_id = ClientId}) -> - logger:notice("[sdlan_channel] client_id: ~p, tcp_closed", [ClientId]), - {stop, normal, State}; - -%% 关闭当前通道 -handle_info({stop, Reason}, State) -> - {stop, Reason, State}; - -handle_info(Info, State) -> - logger:warning("[sdlan_channel] get a unknown message: ~p, channel will closed", [Info]), - {noreply, State}. - -terminate(Reason, #state{client_id = ClientId, network_pid = NetworkPid}) -> - case ClientId /= undefined andalso is_pid(NetworkPid) of - true -> - {ok, NetworkId} = sdlan_network:get_network_id(NetworkPid), - Result = sdlan_api:node_offline(ClientId, NetworkId), - logger:debug("[sdlan_channel] client_id: ~p, set none offline, result is: ~p", [ClientId, Result]); - false -> - ok - end, - logger:warning("[sdlan_channel] client_id: ~p, stop with reason: ~p", [ClientId, Reason]), - ok. - -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% helper methods -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --spec register_nak_reply(PacketId :: integer(), ErrorCode :: integer(), ErrorMsg :: binary()) -> binary(). -register_nak_reply(PacketId, ErrorCode, ErrorMsg) when is_integer(PacketId), is_integer(ErrorCode), is_binary(ErrorMsg) -> - RegisterNakReply = sdlan_pb:encode_msg(#sdl_register_super_nak { - error_code = ErrorCode, - error_message = ErrorMsg - }), - <>. - -rsa_encode(PlainText, RsaPubKey) when is_binary(PlainText) -> - iolist_to_binary(sdlan_cipher:rsa_encrypt(PlainText, RsaPubKey)). \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_ipaddr.erl b/apps/sdlan/src/sdlan_ipaddr.erl deleted file mode 100644 index 019f54d..0000000 --- a/apps/sdlan/src/sdlan_ipaddr.erl +++ /dev/null @@ -1,55 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 27. 3月 2024 17:43 -%%%------------------------------------------------------------------- --module(sdlan_ipaddr). --author("anlicheng"). - -%% API --export([ipv4_to_int/1, int_to_ipv4/1, ips/2, format_ip/1]). --export([ipv6_bytes_to_binary/1]). - -format_ip(Ip) when is_integer(Ip) -> - int_to_ipv4(Ip); -format_ip(Ip) -> - Ip. - --spec ipv4_to_int(Ip :: integer() | binary() | inet:ip4_address()) -> integer(). -ipv4_to_int(Ip) when is_integer(Ip) -> - Ip; -ipv4_to_int({Ip0, Ip1, Ip2, Ip3}) -> - <> = <>, - Ip; -ipv4_to_int(Ip) when is_binary(Ip) -> - Parts0 = binary:split(Ip, <<".">>, [global]), - Parts = lists:map(fun binary_to_integer/1, Parts0), - <> = iolist_to_binary(Parts), - IpInt. - --spec int_to_ipv4(Ip :: integer()) -> binary(). -int_to_ipv4(Ip) when is_integer(Ip) -> - <> = <>, - <<(integer_to_binary(Ip0))/binary, $., (integer_to_binary(Ip1))/binary, $., (integer_to_binary(Ip2))/binary, $., (integer_to_binary(Ip3))/binary>>. - --spec ips(NetAddr :: binary(), MaskLen :: integer()) -> [Ip :: integer()]. -ips(NetAddr, MaskLen) when is_binary(NetAddr), is_integer(MaskLen) -> - Mask = 16#FFFFFFFF bsr MaskLen, - Net0 = ipv4_to_int(NetAddr), - %% 防止网络地址给得不对,比如: "192.168.1.101", - L = 32 - MaskLen, - Net = (Net0 bsr L) bsl L, - lists:map(fun(V) -> Net + V end, lists:seq(1, Mask - 1)). - --spec ipv6_bytes_to_binary(Bytes :: binary()) -> Bin :: binary(). -ipv6_bytes_to_binary(<>) -> - Segments = [integer_to_list(X, 16) || X <- [A, B, C, D, E, F, G, H]], - % 填充每个段以确保是4位 - Padded = [string:pad(S, 4, leading, $0) || S <- Segments], - % 合并成IPv6地址格式,这里没有处理最简化形式的缩写 - iolist_to_binary(lists:flatten(string:join(Padded, ":"))); -ipv6_bytes_to_binary(_) -> - <<"">>. diff --git a/apps/sdlan/src/sdlan_network.erl b/apps/sdlan/src/sdlan_network.erl deleted file mode 100644 index cda4855..0000000 --- a/apps/sdlan/src/sdlan_network.erl +++ /dev/null @@ -1,609 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 27. 3月 2024 15:13 -%%%------------------------------------------------------------------- --module(sdlan_network). --author("anlicheng"). --include("sdlan.hrl"). --include("sdlan_pb.hrl"). --include("sdlan_tables.hrl"). - --behaviour(gen_server). - --define(FLOW_REPORT_INTERVAL, 60 * 1000). - -%% broadcast, "FF-FF-FF-FF-FF-FF" --define(BROADCAST_MAC, <<16#FF,16#FF,16#FF,16#FF,16#FF,16#FF>>). - -%% API --export([start_link/2]). --export([get_name/1, get_pid/1, assign_ip_addr/6, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1]). --export([forward/5, update_hole/6, disable_client/2, get_channel/2, dropout_client/2, reload/1]). --export([test_event/1]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --record(hole, { - peer :: {Ip :: inet:ip4_address(), Port :: integer()}, - nat_type :: integer() -}). - -%% ip的使用信息, 记录主机的动态信息 --record(host, { - client_id :: binary(), - channel_pid :: undefined | pid(), - monitor_ref :: undefined | reference(), - hole :: undefined | #hole{}, - %% 记录ip和ip_v6的映射关系, #{ip_addr :: integer() => {}} - v6_info :: undefined | #sdl_v6_info{} -}). - --record(state, { - network_id :: integer(), - name :: binary(), - domain :: binary(), - ipaddr :: binary(), - mask_len :: integer(), - owner_id :: integer(), - - %% 设置网络带宽 - throttle_key :: atom(), - - %% 转发流量统计 - forward_bytes = 0, - - %% 同一个网络下公用的密钥, 采用AES-256加密算法;随机生成 - aes_key :: binary(), - - %% ip分配器 - %% 记录当前网络下的全部ip地址 - ips = [] :: [Ip :: integer()], - - %% 记录已经使用了的ip, #{mac :: integer() => Host :: #host{}} - used_map = #{} -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -%% -- MARK: 测试函数 -test_event(Pid) -> - gen_server:cast(Pid, test_event). - --spec get_pid(Id :: integer()) -> undefined | pid(). -get_pid(Id) when is_integer(Id) -> - whereis(get_name(Id)). - --spec get_name(Id :: integer()) -> atom(). -get_name(Id) when is_integer(Id) -> - list_to_atom("sdlan_network:" ++ integer_to_list(Id)). - --spec reload(Pid :: pid()) -> ok | {error, Reason :: any()}. -reload(Pid) when is_pid(Pid) -> - gen_server:call(Pid, reload). - --spec assign_ip_addr(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), NetAddr :: integer(), HostName :: binary()) -> - {ok, Domain :: binary(), NetAddr :: integer(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}. -assign_ip_addr(Pid, ChannelPid, ClientId, Mac, NetAddr, HostName) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(NetAddr) -> - gen_server:call(Pid, {assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr, HostName}). - --spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}. -get_network_id(Pid) when is_pid(Pid) -> - gen_server:call(Pid, get_network_id). - --spec unregister(Pid :: pid(), ClientId :: binary(), Mac :: binary()) -> no_return(). -unregister(Pid, ClientId, Mac) when is_pid(Pid), is_binary(ClientId), is_binary(Mac) -> - gen_server:cast(Pid, {unregister, ClientId, Mac}). - --spec peer_info(Pid :: pid(), SrcMac :: binary(), DstMac :: binary()) -> - error | {ok, {NatPeer :: {Ip :: inet:ip4_address(), Port :: integer()}, NatType :: integer()}, V6Info :: undefined | #sdl_v6_info{}}. -peer_info(Pid, SrcMac, DstMac) when is_pid(Pid), is_binary(SrcMac), is_binary(DstMac) -> - gen_server:call(Pid, {peer_info, SrcMac, DstMac}). - --spec forward(pid(), Sock :: any(), SrcMac :: binary(), DstMac :: binary(), Packet :: binary()) -> no_return(). -forward(Pid, Sock, SrcMac, DstMac, Packet) when is_pid(Pid), is_binary(SrcMac), is_binary(DstMac), is_binary(Packet) -> - gen_server:cast(Pid, {forward, Sock, SrcMac, DstMac, Packet}). - -%% 更新ip地址对应的nat关系 --spec update_hole(Pid :: pid(), ClientId :: binary(), Mac :: binary(), Peer :: tuple(), NatType :: integer(), V6Info :: undefined | #sdl_v6_info{}) -> no_return(). -update_hole(Pid, ClientId, Mac, Peer, NatType, V6Info) when is_pid(Pid), is_binary(ClientId), is_binary(Mac), is_integer(NatType) -> - gen_server:cast(Pid, {update_hole, ClientId, Mac, Peer, NatType, V6Info}). - --spec disable_client(Pid :: pid(), ClientId :: binary()) -> ok | error. -disable_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) -> - gen_server:call(Pid, {disable_client, ClientId}). - --spec get_channel(Pid :: pid(), ClientId :: binary()) -> error | {ok, ChannelPid :: pid()}. -get_channel(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) -> - gen_server:call(Pid, {get_channel, ClientId}). - -%% 剔除client_id,channel不关闭; channel会被重新绑定到其他的network里面 --spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid(), HostName :: binary()} | error. -dropout_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) -> - gen_server:call(Pid, {dropout_client, ClientId}). - --spec debug_info(Pid :: pid()) -> map(). -debug_info(Pid) when is_pid(Pid) -> - gen_server:call(Pid, debug_info). - --spec get_used_map(Pid :: pid()) -> map(). -get_used_map(Pid) when is_pid(Pid) -> - gen_server:call(Pid, get_used_map); -get_used_map(undefined) -> - #{}. - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link(Name :: atom(), Id :: integer()) -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link(Name, Id) when is_atom(Name), is_integer(Id) -> - gen_server:start_link({local, Name}, ?MODULE, [Id], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([Id]) when is_integer(Id) -> - erlang:process_flag(trap_exit, true), - case sdlan_api:get_network(Id) of - {ok, #{<<"ipaddr">> := Null}} when Null == <<"null">>; Null == <<"NULL">> -> - ignore; - {ok, #{<<"id">> := Id, <<"name">> := Name, <<"domain">> := Domain, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} -> - {IpAddr, MaskLen} = parse_ipaddr(IpAddr0), - Ips = sdlan_ipaddr:ips(IpAddr, MaskLen), - AesKey = sdlan_util:rand_byte(32), - %% 限流key - ThrottleKey = list_to_atom("network_throttle:" ++ integer_to_list(Id)), - %% 绑定到资源协调器 - sdlan_network_coordinator:attach(self(), ThrottleKey), - - %% 每分钟汇报一次转发的流量 - erlang:start_timer(?FLOW_REPORT_INTERVAL, self(), flow_report_ticker), - - %% 创建数据库表 - create_mnesia_table(Id), - - logger:debug("[sdlan_network] network: ~p, ips: ~p", [Id, lists:map(fun sdlan_ipaddr:int_to_ipv4/1, Ips)]), - - sdlan_domain_regedit:insert(Domain), - - {ok, #state{network_id = Id, name = Name, domain = Domain, ipaddr = IpAddr, owner_id = OwnerId, mask_len = MaskLen, ips = Ips, aes_key = AesKey, throttle_key = ThrottleKey}}; - {error, Reason} -> - logger:warning("[sdlan_network] load network: ~p, get error: ~p", [Id, Reason]), - ignore - end. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -%% 重新加载网络信息 -handle_call(reload, _From, State = #state{network_id = Id, ipaddr = OldIpAddr, mask_len = OldMarkLen, used_map = UsedMap}) -> - case sdlan_api:get_network(Id) of - {ok, #{<<"name">> := Name, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} -> - {IpAddr, MaskLen} = parse_ipaddr(IpAddr0), - case OldIpAddr =:= IpAddr andalso OldMarkLen =:= MaskLen of - true -> - {reply, ok, State#state{name = Name, owner_id = OwnerId}}; - false -> - logger:debug("[sdlan_networkd] network_id: ~p, reload will close all channels", [Id]), - Ips = sdlan_ipaddr:ips(IpAddr, MaskLen), - %% 整个网络下的设备都需要重新连接 - maps:foreach(fun(_, #host{channel_pid = ChannelPid, monitor_ref = MRef}) -> - is_reference(MRef) andalso demonitor(MRef), - is_process_alive(ChannelPid) andalso sdlan_channel:stop(ChannelPid, normal) - end, UsedMap), - %% 清理掉数据库中的数据 - ok = client_model:delete_clients(Id), - - {reply, ok, State#state{name = Name, ipaddr = IpAddr, - owner_id = OwnerId, mask_len = MaskLen, ips = Ips, used_map = maps:new()}} - end; - {error, Reason} -> - logger:warning("[sdlan_network] reload network: ~p, get error: ~p", [Id, Reason]), - {reply, {error, Reason}, State} - end; - -%% 给客户端分配ip地址 -handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0, HostName}, _From, - State = #state{network_id = NetworkId, domain = Domain, ips = Ips, used_map = UsedMap, mask_len = MaskLen, aes_key = AesKey}) -> - - %% 分配ip地址的时候,以mac地址为唯一基准 - logger:debug("[sdlan_network] alloc_ip, network_id: ~p, ips: ~p, client_id: ~p, mac: ~p, net_addr: ~p", - [NetworkId, Ips, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(NetAddr0)]), - - case client_model:alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) of - {ok, Ip} -> - %% 关闭之前的channel - maybe_close_channel(maps:get(Mac, UsedMap, undefined)), - - %% 添加域名->ip的映射关系 - case HostName =/= <<>> of - true -> - FullHostname = <>, - sdlan_hostname_regedit:insert(FullHostname, Ip); - false -> - ok - end, - - %% 建立到新的channel之间的关系 - MRef = monitor(process, ChannelPid), - NUsedMap = maps:put(Mac, #host{client_id = ClientId, channel_pid = ChannelPid, monitor_ref = MRef}, UsedMap), - - {reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{used_map = NUsedMap}}; - {error, Reason} -> - {reply, {error, Reason}, State} - end; - -handle_call(get_used_map, _From, State = #state{used_map = UsedMap}) -> - UsedInfos = maps:map(fun(_, #host{hole = Hole, v6_info = V6Info}) -> - HoleMap = case Hole of - #hole{peer = {NatIp, NatPort}} -> - #{ - <<"nat_ip">> => sdlan_ipaddr:int_to_ipv4(sdlan_ipaddr:ipv4_to_int(NatIp)), - <<"nat_port">> => NatPort - }; - _ -> - #{} - end, - - V6Map = case V6Info of - #sdl_v6_info{v6 = IpV6, port = Port} -> - #{ - <<"v6_ip">> => sdlan_ipaddr:ipv6_bytes_to_binary(IpV6), - <<"v6_port">> => Port - }; - _ -> - #{} - end, - #{<<"hole">> => HoleMap, <<"v6_info">> => V6Map} - end, UsedMap), - - {reply, {ok, UsedInfos}, State}; - -%% client设置为禁止状态,不允许重连 -handle_call({disable_client, ClientId}, _From, State = #state{network_id = NetworkId, used_map = UsedMap}) -> - case lists:search(fun({_, #host{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(UsedMap)) of - {value, {Mac, #host{channel_pid = ChannelPid, monitor_ref = MRef}}} -> - is_reference(MRef) andalso demonitor(MRef), - sdlan_channel:stop(ChannelPid, disable), - NUsedMap = maps:remove(Mac, UsedMap), - %% 将客户端设置为禁止状态 - client_model:disable_client(NetworkId, ClientId), - - {reply, ok, State#state{used_map = NUsedMap}}; - false -> - {reply, error, State} - end; - -handle_call({get_channel, ClientId}, _From, State = #state{used_map = UsedMap}) -> - case lists:search(fun({_, #host{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(UsedMap)) of - {value, {_Ip, #host{channel_pid = ChannelPid}}} -> - {reply, {ok, ChannelPid}, State}; - false -> - {reply, error, State} - end; - -%% 区别在于是否关闭掉channel, 这里是在网络迁移中的功能; drop的时候需要从当前网络中移除 -handle_call({dropout_client, ClientId}, _From, State = #state{network_id = NetworkId, used_map = UsedMap}) -> - case lists:search(fun({_, #host{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(UsedMap)) of - {value, {Mac, #host{channel_pid = ChannelPid, monitor_ref = MRef}}} -> - is_reference(MRef) andalso demonitor(MRef), - NUsedMap = maps:remove(Mac, UsedMap), - %% 从数据库删除 - case client_model:delete_client(NetworkId, ClientId) of - {ok, #client{host_name = HostName}} -> - {reply, {ok, ChannelPid, HostName}, State#state{used_map = NUsedMap}}; - {error, _} -> - {reply, error, State} - end; - false -> - {reply, error, State} - end; - -handle_call(get_network_id, _From, State = #state{network_id = NetworkId}) -> - {reply, {ok, NetworkId}, State}; - -%% 网络存在的nat_peer信息 -handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{used_map = UsedMap}) -> - case maps:find(DstMac, UsedMap) of - {ok, #host{channel_pid = DstChannelPid, hole = #hole{peer = DstNatPeer, nat_type = DstNatType}, v6_info = DstV6Info}} -> - %% 让目标服务器发送sendRegister事件(2024-06-25 新增,提高打洞的成功率) - case maps:get(SrcMac, UsedMap, undefined) of - #host{hole = #hole{peer = {SrcNatIp, SrcNatPort}, nat_type = NatType}, v6_info = SrcV6Info} -> - Event = sdlan_pb:encode_msg(#sdl_send_register_event { - dst_mac = SrcMac, - nat_ip = sdlan_ipaddr:ipv4_to_int(SrcNatIp), - nat_type = NatType, - nat_port = SrcNatPort, - v6_info = SrcV6Info - }), - sdlan_channel:send_event(DstChannelPid, ?PACKET_EVENT_SEND_REGISTER, Event); - _ -> - ok - end, - {reply, {ok, {DstNatPeer, DstNatType}, DstV6Info}, State}; - _ -> - {reply, error, State} - end; - -handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = IpAddr, mask_len = MaskLen, owner_id = OwnerId, ips = Ips, used_map = UsedMap}) -> - Reply = #{ - <<"network_id">> => NetworkId, - <<"ipaddr">> => IpAddr, - <<"mask_len">> => MaskLen, - <<"owner_id">> => OwnerId, - <<"ips">> => lists:map(fun sdlan_ipaddr:int_to_ipv4/1, Ips), - <<"used_ips">> => lists:map(fun({_, Host = #host{client_id = ClientId}}) -> - case client_model:get_client(NetworkId, ClientId) of - error -> - #{}; - {ok, #client{mac = Mac, ip = Ip}} -> - format_host(Host, Ip, Mac) - end - end, maps:to_list(UsedMap)) - }, - {reply, Reply, State}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -%% 网络数据转发, mac地址单播 -handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, used_map = UsedMap, throttle_key = ThrottleKey, forward_bytes = ForwardBytes}) - when is_map_key(SrcMac, UsedMap), is_map_key(DstMac, UsedMap) -> - - PacketBytes = byte_size(Packet), - case maps:find(DstMac, UsedMap) of - {ok, #host{hole = #hole{peer = Peer = {Ip, Port}}}} -> - case throttle:check(sdlan_network, ThrottleKey) of - {ok, _RestCount, _LeftToReset} -> - %% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat - logger:debug("[sdlan_network] forward data networkd_id: ~p, src_mac: ~p, dst_mac: ~p, hole: ~p", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), Peer]), - - gen_udp:send(Sock, Ip, Port, Packet), - {noreply, State#state{forward_bytes = ForwardBytes + PacketBytes}}; - {limit_exceeded, 0, _LeftToReset} -> - %% 尝试获取其他网络是否有让渡的资源 - case sdlan_network_coordinator:checkout() of - ok -> - logger:debug("[sdlan_network] use release forward data networkd_id: ~p, src_mac: ~p, dst_mac: ~p, hole: ~p", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), Peer]), - - gen_udp:send(Sock, Ip, Port, Packet), - {noreply, State#state{forward_bytes = ForwardBytes + PacketBytes}}; - error -> - logger:notice("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, rate limited, discard", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - {noreply, State} - end - end; - {ok, _} -> - logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, hole not found", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - {noreply, State}; - error -> - logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p not found", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - {noreply, State} - end; - -%% 网络数据转发, ip广播或组播, 不限流 -handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, used_map = UsedMap, forward_bytes = ForwardBytes}) - when is_map_key(SrcMac, UsedMap) -> - %% 广播地址和组播地址,需要转发到整个网络 - case sdlan_util:is_broadcast_mac(DstMac) orelse sdlan_util:is_multicast_mac(DstMac) of - true -> - PacketBytes = byte_size(Packet), - %% 消息广播 - maps:foreach(fun(Mac, #host{hole = Hole}) -> - case {Mac =/= SrcMac, Hole} of - {true, #hole{peer = {NatIp, NatPort}}} -> - logger:debug("[sdlan_network] call me here"), - gen_udp:send(Sock, NatIp, NatPort, Packet); - _ -> - ok - end - end, UsedMap), - - %% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat - logger:debug("[sdlan_network] broadcast data networkd_id: ~p, src_mac: ~p, dst_mac: ~p", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - - {noreply, State#state{forward_bytes = ForwardBytes + PacketBytes}}; - false -> - logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, forward discard 1", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - {noreply, State} - end; - -handle_cast({forward, _Sock, SrcMac, DstMac, _Packet}, State = #state{network_id = NetworkId}) -> - logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, forward discard 2", - [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - {noreply, State}; - -%% 删除ip的占用并关闭channel -handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId, used_map = UsedMap}) -> - logger:debug("[sdlan_network] networkd_id: ~p, unregister Mac: ~p", [NetworkId, sdlan_util:format_mac(Mac)]), - case maps:take(Mac, UsedMap) of - error -> - {noreply, State}; - {#host{channel_pid = ChannelPid, monitor_ref = MRef}, NUsedMap} -> - is_reference(MRef) andalso demonitor(MRef), - sdlan_channel:stop(ChannelPid, normal), - {noreply, State#state{used_map = NUsedMap}} - end; - -%% 需要判断,client是属于当前网络的 -handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{network_id = NetworkId, used_map = UsedMap}) -> - case {maps:find(Mac, UsedMap), client_model:get_client(NetworkId, ClientId)} of - {{ok, Host0 = #host{client_id = ClientId0, hole = OldHole}}, {ok, #client{ip = Ip}}} when ClientId =:= ClientId0 -> - case OldHole =:= undefined orelse (OldHole#hole.peer =/= Peer orelse OldHole#hole.nat_type =/= NatType) of - true -> - NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event{ - mac = Mac, - ip = Ip - }), - broadcast(?PACKET_EVENT_NAT_CHANGED, NatChangedEvent, Mac, UsedMap); - false -> - ok - end, - Host = Host0#host{hole = #hole{peer = Peer, nat_type = NatType}, v6_info = V6Info}, - - {noreply, State#state{used_map = maps:put(Mac, Host, UsedMap)}}; - _ -> - {noreply, State} - end. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({timeout, _, flow_report_ticker}, State = #state{network_id = NetworkId, forward_bytes = ForwardBytes}) -> - erlang:start_timer(?FLOW_REPORT_INTERVAL, self(), flow_report_ticker), - catch sdlan_api:network_forward_report(NetworkId, ForwardBytes), - {noreply, State#state{forward_bytes = 0}}; - -handle_info({'EXIT', _Pid, shutdown}, State = #state{network_id = NetworkId, used_map = UsedMap}) -> - logger:warning("[sdlan_network] network: ~p, get shutdown message", [NetworkId]), - broadcast_shutdown(UsedMap), - {stop, shutdown, State}; -%% Channel进程退出, hole里面的数据也需要清理 -handle_info({'DOWN', _MRef, process, ChannelPid, Reason}, State = #state{network_id = NetworkId, used_map = UsedMap}) -> - logger:notice("[sdlan_network] network_id: ~p, channel_pid: ~p, close with reason: ~p", [NetworkId, ChannelPid, Reason]), - NUsedMap = maps:filter(fun(_, #host{channel_pid = ChannelPid0}) -> ChannelPid =/= ChannelPid0 end, UsedMap), - {noreply, State#state{used_map = NUsedMap}}. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(Reason, #state{network_id = NetworkId, used_map = UsedMap}) -> - logger:debug("[sdlan_network] network: ~p, will terminate with reason: ~p", [NetworkId, Reason]), - broadcast_shutdown(UsedMap), - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== - -%% 创建数据库表 --spec create_mnesia_table(NetworkId :: integer()) -> no_return(). -create_mnesia_table(NetworkId) when is_integer(NetworkId) -> - Tab = client_model:get_table_name(NetworkId), - Tables = mnesia:system_info(tables), - case lists:member(Tab, Tables) of - true -> - ok; - false -> - Res = client_model:create_table(Tab), - logger:debug("[sdlan_network] create table result: ~p", [Res]) - end. - --spec maybe_close_channel(undefined | #host{}) -> no_return(). -maybe_close_channel(#host{channel_pid = ChannelPid0, monitor_ref = MRef0}) -> - case is_pid(ChannelPid0) andalso is_process_alive(ChannelPid0) of - true -> - is_reference(MRef0) andalso demonitor(MRef0), - sdlan_channel:stop(ChannelPid0, channel_rebind); - false -> - ok - end; -maybe_close_channel(_) -> - ok. - --spec broadcast(EventType :: integer(), Event :: binary(), ExcludeMac :: binary(), UsedMap :: map()) -> no_return(). -broadcast(EventType, Event, ExcludeMac, UsedMap) when is_map(UsedMap), is_binary(ExcludeMac), is_integer(EventType), is_binary(Event) -> - maps:foreach(fun(Mac, #host{channel_pid = ChannelPid}) -> - case is_process_alive(ChannelPid) andalso ExcludeMac /= Mac of - true -> - sdlan_channel:send_event(ChannelPid, EventType, Event); - false -> - ok - end - end, UsedMap). - -broadcast_shutdown(UsedMap) when is_map(UsedMap) -> - maps:foreach(fun(_, #host{channel_pid = ChannelPid}) -> - case is_process_alive(ChannelPid) of - true -> - NetworkShutdownEvent = sdlan_pb:encode_msg(#sdl_network_shutdown_event { - message = <<"Network shutdown">> - }), - sdlan_channel:send_event(ChannelPid, ?PACKET_EVENT_NETWORK_SHUTDOWN, NetworkShutdownEvent), - sdlan_channel:stop(ChannelPid, normal); - false -> - ok - end - end, UsedMap). - -%% 解析IpAddr: <<"192.168.172/24">> --spec parse_ipaddr(IpAddr0 :: binary()) -> {IpAddr :: binary(), MaskLen :: integer()}. -parse_ipaddr(IpAddr0) when is_binary(IpAddr0) -> - case binary:split(IpAddr0, <<"/">>) of - [IpAddr, MaskLen] -> - MaskLen1 = binary_to_integer(MaskLen), - {IpAddr, MaskLen1}; - _ -> - {IpAddr0, 24} - end. - --spec format_host(Host :: #host{}, Ip :: integer(), Mac :: binary()) -> map(). -format_host(#host{client_id = ClientId, hole = Hole, v6_info = V6Info}, Ip, Mac) when is_integer(Ip), is_binary(Mac) -> - HoleMap = case Hole of - undefined -> - #{}; - #hole{peer = {NatIp, NatPort}, nat_type = NatType} -> - #{ - nat_ip => NatIp, - nat_port => NatPort, - nat_type => NatType - } - end, - - V6InfoMap = case V6Info of - undefined -> - #{}; - #sdl_v6_info{v6 = V6, port = V6Port} -> - #{v6 => V6, port => V6Port} - end, - - #{ - client_id => ClientId, - mac => sdlan_util:format_mac(Mac), - ip => sdlan_ipaddr:int_to_ipv4(Ip), - hole_map => HoleMap, - v6_info => V6InfoMap - }. diff --git a/apps/sdlan/src/sdlan_network_sup.erl b/apps/sdlan/src/sdlan_network_sup.erl deleted file mode 100644 index 8dba1d7..0000000 --- a/apps/sdlan/src/sdlan_network_sup.erl +++ /dev/null @@ -1,119 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 27. 3月 2024 15:12 -%%%------------------------------------------------------------------- --module(sdlan_network_sup). --author("anlicheng"). - --behaviour(supervisor). - -%% API --export([start_link/0]). --export([ensured_network_started/1, delete_network/1, get_all_networks/0, start_network/1, reallocate_bind_width/0]). - -%% Supervisor callbacks --export([init/1]). - --define(SERVER, ?MODULE). - -%%%=================================================================== -%%% API functions -%%%=================================================================== - -%% @doc Starts the supervisor --spec(start_link() -> {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - supervisor:start_link({local, ?SERVER}, ?MODULE, []). - -%%%=================================================================== -%%% Supervisor callbacks -%%%=================================================================== - -%% @private -%% @doc Whenever a supervisor is started using supervisor:start_link/[2,3], -%% this function is called by the new process to find out about -%% restart strategy, maximum restart frequency and child -%% specifications. -init([]) -> - SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, - {ok, NetworkIds} = sdlan_api:get_all_networks(), - Specs = lists:map(fun child_spec/1, []), - - set_network_bind(length(Specs)), - - {ok, {SupFlags, Specs}}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== - --spec ensured_network_started(Id :: integer()) -> {ok, Pid :: pid()} | {error, Reason :: any()}. -ensured_network_started(Id) when is_integer(Id) -> - case sdlan_network:get_pid(Id) of - undefined -> - case supervisor:start_child(?MODULE, child_spec(Id)) of - {ok, Pid} when is_pid(Pid) -> - {ok, Pid}; - {error, {'already_started', Pid}} when is_pid(Pid) -> - {ok, Pid}; - {error, Error} -> - {error, Error} - end; - Pid when is_pid(Pid) -> - {ok, Pid} - end. - --spec start_network(Id :: integer()) -> {ok, Pid :: pid()} | {error, Reason :: any()}. -start_network(Id) when is_integer(Id) -> - case supervisor:start_child(?MODULE, child_spec(Id)) of - {ok, Pid} when is_pid(Pid) -> - {ok, Pid}; - {error, {'already_started', Pid}} when is_pid(Pid) -> - {ok, Pid}; - {error, Error} -> - {error, Error} - end. - --spec get_all_networks() -> [pid()]. -get_all_networks() -> - lists:map(fun({_Id, ChildPid, _Type, _Modules}) -> ChildPid end, supervisor:which_children(?MODULE)). - -%% 重新分配网络带宽 --spec reallocate_bind_width() -> no_return(). -reallocate_bind_width() -> - ChildPids = lists:map(fun({_Id, ChildPid, _Type, _Modules}) -> ChildPid end, supervisor:which_children(?MODULE)), - set_network_bind(length(ChildPids)). - --spec delete_network(NetworkId :: integer()) -> ok | {error, Reason :: any()}. -delete_network(NetworkId) when is_integer(NetworkId) -> - ChildId = sdlan_network:get_name(NetworkId), - case supervisor:terminate_child(?MODULE, ChildId) of - ok -> - supervisor:delete_child(?MODULE, ChildId); - Error -> - Error - end. - --spec child_spec(Id :: integer()) -> map(). -child_spec(Id) when is_integer(Id) -> - Name = sdlan_network:get_name(Id), - #{ - id => Name, - start => {sdlan_network, start_link, [Name, Id]}, - restart => permanent, - shutdown => 2000, - type => worker, - modules => ['sdlan_network'] - }. - -set_network_bind(0) -> - ok; -set_network_bind(Count) when is_integer(Count) -> - {ok, BindWidth} = application:get_env(sdlan, band_width), - NetworkBindWidth = BindWidth div Count, - application:set_env(sdlan, network_bind_width, NetworkBindWidth), - throttle:setup(sdlan_network, NetworkBindWidth, per_second). \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_pb.erl b/apps/sdlan/src/sdlan_pb.erl deleted file mode 100644 index a7c4c8c..0000000 --- a/apps/sdlan/src/sdlan_pb.erl +++ /dev/null @@ -1,3824 +0,0 @@ -%% -*- coding: utf-8 -*- -%% % this file is @generated -%% @private -%% Automatically generated, do not edit -%% Generated by gpb_compile version 4.21.1 -%% Version source: git --module(sdlan_pb). - --export([encode_msg/1, encode_msg/2, encode_msg/3]). --export([decode_msg/2, decode_msg/3]). --export([merge_msgs/2, merge_msgs/3, merge_msgs/4]). --export([verify_msg/1, verify_msg/2, verify_msg/3]). --export([get_msg_defs/0]). --export([get_msg_names/0]). --export([get_group_names/0]). --export([get_msg_or_group_names/0]). --export([get_enum_names/0]). --export([find_msg_def/1, fetch_msg_def/1]). --export([find_enum_def/1, fetch_enum_def/1]). --export([enum_symbol_by_value/2, enum_value_by_symbol/2]). --export([get_service_names/0]). --export([get_service_def/1]). --export([get_rpc_names/1]). --export([find_rpc_def/2, fetch_rpc_def/2]). --export([fqbin_to_service_name/1]). --export([service_name_to_fqbin/1]). --export([fqbins_to_service_and_rpc_name/2]). --export([service_and_rpc_name_to_fqbins/2]). --export([fqbin_to_msg_name/1]). --export([msg_name_to_fqbin/1]). --export([fqbin_to_enum_name/1]). --export([enum_name_to_fqbin/1]). --export([get_package_name/0]). --export([uses_packages/0]). --export([source_basename/0]). --export([get_all_source_basenames/0]). --export([get_all_proto_names/0]). --export([get_msg_containment/1]). --export([get_pkg_containment/1]). --export([get_service_containment/1]). --export([get_rpc_containment/1]). --export([get_enum_containment/1]). --export([get_proto_by_msg_name_as_fqbin/1]). --export([get_proto_by_service_name_as_fqbin/1]). --export([get_proto_by_enum_name_as_fqbin/1]). --export([get_protos_by_pkg_name_as_fqbin/1]). --export([gpb_version_as_string/0, gpb_version_as_list/0]). --export([gpb_version_source/0]). - --include("sdlan_pb.hrl"). --include_lib("gpb/include/gpb.hrl"). - -%% enumerated types - --export_type([]). - -%% message types --type sdl_v4_info() :: #sdl_v4_info{}. - --type sdl_v6_info() :: #sdl_v6_info{}. - --type sdl_dev_addr() :: #sdl_dev_addr{}. - --type sdl_empty() :: #sdl_empty{}. - --type sdl_register_super() :: #sdl_register_super{}. - --type sdl_register_super_ack() :: #sdl_register_super_ack{}. - --type sdl_register_super_nak() :: #sdl_register_super_nak{}. - --type sdl_query_info() :: #sdl_query_info{}. - --type sdl_peer_info() :: #sdl_peer_info{}. - --type sdl_nat_changed_event() :: #sdl_nat_changed_event{}. - --type sdl_send_register_event() :: #sdl_send_register_event{}. - --type sdl_network_shutdown_event() :: #sdl_network_shutdown_event{}. - --type sdl_change_network_command() :: #sdl_change_network_command{}. - --type sdl_command_ack() :: #sdl_command_ack{}. - --type sdl_flows() :: #sdl_flows{}. - --type sdl_stun_request() :: #sdl_stun_request{}. - --type sdl_stun_reply() :: #sdl_stun_reply{}. - --type sdl_data() :: #sdl_data{}. - --type sdl_register() :: #sdl_register{}. - --type sdl_register_ack() :: #sdl_register_ack{}. - --type sdl_stun_probe() :: #sdl_stun_probe{}. - --type sdl_stun_probe_reply() :: #sdl_stun_probe_reply{}. - --export_type(['sdl_v4_info'/0, 'sdl_v6_info'/0, 'sdl_dev_addr'/0, 'sdl_empty'/0, 'sdl_register_super'/0, 'sdl_register_super_ack'/0, 'sdl_register_super_nak'/0, 'sdl_query_info'/0, 'sdl_peer_info'/0, 'sdl_nat_changed_event'/0, 'sdl_send_register_event'/0, 'sdl_network_shutdown_event'/0, 'sdl_change_network_command'/0, 'sdl_command_ack'/0, 'sdl_flows'/0, 'sdl_stun_request'/0, 'sdl_stun_reply'/0, 'sdl_data'/0, 'sdl_register'/0, 'sdl_register_ack'/0, 'sdl_stun_probe'/0, 'sdl_stun_probe_reply'/0]). --type '$msg_name'() :: sdl_v4_info | sdl_v6_info | sdl_dev_addr | sdl_empty | sdl_register_super | sdl_register_super_ack | sdl_register_super_nak | sdl_query_info | sdl_peer_info | sdl_nat_changed_event | sdl_send_register_event | sdl_network_shutdown_event | sdl_change_network_command | sdl_command_ack | sdl_flows | sdl_stun_request | sdl_stun_reply | sdl_data | sdl_register | sdl_register_ack | sdl_stun_probe | sdl_stun_probe_reply. --type '$msg'() :: sdl_v4_info() | sdl_v6_info() | sdl_dev_addr() | sdl_empty() | sdl_register_super() | sdl_register_super_ack() | sdl_register_super_nak() | sdl_query_info() | sdl_peer_info() | sdl_nat_changed_event() | sdl_send_register_event() | sdl_network_shutdown_event() | sdl_change_network_command() | sdl_command_ack() | sdl_flows() | sdl_stun_request() | sdl_stun_reply() | sdl_data() | sdl_register() | sdl_register_ack() | sdl_stun_probe() | sdl_stun_probe_reply(). --export_type(['$msg_name'/0, '$msg'/0]). - --if(?OTP_RELEASE >= 24). --dialyzer({no_underspecs, encode_msg/1}). --endif. --spec encode_msg('$msg'()) -> binary(). -encode_msg(Msg) when tuple_size(Msg) >= 1 -> encode_msg(Msg, element(1, Msg), []). - --if(?OTP_RELEASE >= 24). --dialyzer({no_underspecs, encode_msg/2}). --endif. --spec encode_msg('$msg'(), '$msg_name'() | list()) -> binary(). -encode_msg(Msg, MsgName) when is_atom(MsgName) -> encode_msg(Msg, MsgName, []); -encode_msg(Msg, Opts) when tuple_size(Msg) >= 1, is_list(Opts) -> encode_msg(Msg, element(1, Msg), Opts). - --if(?OTP_RELEASE >= 24). --dialyzer({no_underspecs, encode_msg/3}). --endif. --spec encode_msg('$msg'(), '$msg_name'(), list()) -> binary(). -encode_msg(Msg, MsgName, Opts) -> - case proplists:get_bool(verify, Opts) of - true -> verify_msg(Msg, MsgName, Opts); - false -> ok - end, - TrUserData = proplists:get_value(user_data, Opts), - case MsgName of - sdl_v4_info -> encode_msg_sdl_v4_info(id(Msg, TrUserData), TrUserData); - sdl_v6_info -> encode_msg_sdl_v6_info(id(Msg, TrUserData), TrUserData); - sdl_dev_addr -> encode_msg_sdl_dev_addr(id(Msg, TrUserData), TrUserData); - sdl_empty -> encode_msg_sdl_empty(id(Msg, TrUserData), TrUserData); - sdl_register_super -> encode_msg_sdl_register_super(id(Msg, TrUserData), TrUserData); - sdl_register_super_ack -> encode_msg_sdl_register_super_ack(id(Msg, TrUserData), TrUserData); - sdl_register_super_nak -> encode_msg_sdl_register_super_nak(id(Msg, TrUserData), TrUserData); - sdl_query_info -> encode_msg_sdl_query_info(id(Msg, TrUserData), TrUserData); - sdl_peer_info -> encode_msg_sdl_peer_info(id(Msg, TrUserData), TrUserData); - sdl_nat_changed_event -> encode_msg_sdl_nat_changed_event(id(Msg, TrUserData), TrUserData); - sdl_send_register_event -> encode_msg_sdl_send_register_event(id(Msg, TrUserData), TrUserData); - sdl_network_shutdown_event -> encode_msg_sdl_network_shutdown_event(id(Msg, TrUserData), TrUserData); - sdl_change_network_command -> encode_msg_sdl_change_network_command(id(Msg, TrUserData), TrUserData); - sdl_command_ack -> encode_msg_sdl_command_ack(id(Msg, TrUserData), TrUserData); - sdl_flows -> encode_msg_sdl_flows(id(Msg, TrUserData), TrUserData); - sdl_stun_request -> encode_msg_sdl_stun_request(id(Msg, TrUserData), TrUserData); - sdl_stun_reply -> encode_msg_sdl_stun_reply(id(Msg, TrUserData), TrUserData); - sdl_data -> encode_msg_sdl_data(id(Msg, TrUserData), TrUserData); - sdl_register -> encode_msg_sdl_register(id(Msg, TrUserData), TrUserData); - sdl_register_ack -> encode_msg_sdl_register_ack(id(Msg, TrUserData), TrUserData); - sdl_stun_probe -> encode_msg_sdl_stun_probe(id(Msg, TrUserData), TrUserData); - sdl_stun_probe_reply -> encode_msg_sdl_stun_probe_reply(id(Msg, TrUserData), TrUserData) - end. - - -encode_msg_sdl_v4_info(Msg, TrUserData) -> encode_msg_sdl_v4_info(Msg, <<>>, TrUserData). - - -encode_msg_sdl_v4_info(#sdl_v4_info{port = F1, v4 = F2, nat_type = F3}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end, - if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end. - -encode_msg_sdl_v6_info(Msg, TrUserData) -> encode_msg_sdl_v6_info(Msg, <<>>, TrUserData). - - -encode_msg_sdl_v6_info(#sdl_v6_info{port = F1, v6 = F2}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end. - -encode_msg_sdl_dev_addr(Msg, TrUserData) -> encode_msg_sdl_dev_addr(Msg, <<>>, TrUserData). - - -encode_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_bit_len = F4, network_domain = F5}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end, - B3 = if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end, - B4 = if F4 == undefined -> B3; - true -> - begin - TrF4 = id(F4, TrUserData), - if TrF4 =:= 0 -> B3; - true -> e_varint(TrF4, <>, TrUserData) - end - end - end, - if F5 == undefined -> B4; - true -> - begin - TrF5 = id(F5, TrUserData), - case is_empty_string(TrF5) of - true -> B4; - false -> e_type_string(TrF5, <>, TrUserData) - end - end - end. - -encode_msg_sdl_empty(_Msg, _TrUserData) -> <<>>. - -encode_msg_sdl_register_super(Msg, TrUserData) -> encode_msg_sdl_register_super(Msg, <<>>, TrUserData). - - -encode_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F2, client_id = F3, dev_addr = F4, pub_key = F5, token = F6, network_code = F7, hostname = F8}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case is_empty_string(TrF2) of - true -> B1; - false -> e_type_string(TrF2, <>, TrUserData) - end - end - end, - B3 = if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - case is_empty_string(TrF3) of - true -> B2; - false -> e_type_string(TrF3, <>, TrUserData) - end - end - end, - B4 = if F4 == undefined -> B3; - true -> - begin - TrF4 = id(F4, TrUserData), - if TrF4 =:= undefined -> B3; - true -> e_mfield_sdl_register_super_dev_addr(TrF4, <>, TrUserData) - end - end - end, - B5 = if F5 == undefined -> B4; - true -> - begin - TrF5 = id(F5, TrUserData), - case is_empty_string(TrF5) of - true -> B4; - false -> e_type_string(TrF5, <>, TrUserData) - end - end - end, - B6 = if F6 == undefined -> B5; - true -> - begin - TrF6 = id(F6, TrUserData), - case is_empty_string(TrF6) of - true -> B5; - false -> e_type_string(TrF6, <>, TrUserData) - end - end - end, - B7 = if F7 == undefined -> B6; - true -> - begin - TrF7 = id(F7, TrUserData), - case is_empty_string(TrF7) of - true -> B6; - false -> e_type_string(TrF7, <>, TrUserData) - end - end - end, - if F8 == undefined -> B7; - true -> - begin - TrF8 = id(F8, TrUserData), - case is_empty_string(TrF8) of - true -> B7; - false -> e_type_string(TrF8, <>, TrUserData) - end - end - end. - -encode_msg_sdl_register_super_ack(Msg, TrUserData) -> encode_msg_sdl_register_super_ack(Msg, <<>>, TrUserData). - - -encode_msg_sdl_register_super_ack(#sdl_register_super_ack{dev_addr = F1, aes_key = F2, upgrade_type = F3, upgrade_prompt = F4, upgrade_address = F5}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= undefined -> Bin; - true -> e_mfield_sdl_register_super_ack_dev_addr(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end, - B3 = if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end, - B4 = if F4 == undefined -> B3; - true -> begin TrF4 = id(F4, TrUserData), e_type_string(TrF4, <>, TrUserData) end - end, - if F5 == undefined -> B4; - true -> begin TrF5 = id(F5, TrUserData), e_type_string(TrF5, <>, TrUserData) end - end. - -encode_msg_sdl_register_super_nak(Msg, TrUserData) -> encode_msg_sdl_register_super_nak(Msg, <<>>, TrUserData). - - -encode_msg_sdl_register_super_nak(#sdl_register_super_nak{error_code = F1, error_message = F2}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case is_empty_string(TrF2) of - true -> B1; - false -> e_type_string(TrF2, <>, TrUserData) - end - end - end. - -encode_msg_sdl_query_info(Msg, TrUserData) -> encode_msg_sdl_query_info(Msg, <<>>, TrUserData). - - -encode_msg_sdl_query_info(#sdl_query_info{dst_mac = F1}, Bin, TrUserData) -> - if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - case iolist_size(TrF1) of - 0 -> Bin; - _ -> e_type_bytes(TrF1, <>, TrUserData) - end - end - end. - -encode_msg_sdl_peer_info(Msg, TrUserData) -> encode_msg_sdl_peer_info(Msg, <<>>, TrUserData). - - -encode_msg_sdl_peer_info(#sdl_peer_info{dst_mac = F1, v4_info = F2, v6_info = F3}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - case iolist_size(TrF1) of - 0 -> Bin; - _ -> e_type_bytes(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - if TrF2 =:= undefined -> B1; - true -> e_mfield_sdl_peer_info_v4_info(TrF2, <>, TrUserData) - end - end - end, - if F3 == undefined -> B2; - true -> begin TrF3 = id(F3, TrUserData), e_mfield_sdl_peer_info_v6_info(TrF3, <>, TrUserData) end - end. - -encode_msg_sdl_nat_changed_event(Msg, TrUserData) -> encode_msg_sdl_nat_changed_event(Msg, <<>>, TrUserData). - - -encode_msg_sdl_nat_changed_event(#sdl_nat_changed_event{mac = F1, ip = F2}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - case iolist_size(TrF1) of - 0 -> Bin; - _ -> e_type_bytes(TrF1, <>, TrUserData) - end - end - end, - if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - if TrF2 =:= 0 -> B1; - true -> e_varint(TrF2, <>, TrUserData) - end - end - end. - -encode_msg_sdl_send_register_event(Msg, TrUserData) -> encode_msg_sdl_send_register_event(Msg, <<>>, TrUserData). - - -encode_msg_sdl_send_register_event(#sdl_send_register_event{dst_mac = F1, nat_ip = F2, nat_port = F3, nat_type = F4, v6_info = F5}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - case iolist_size(TrF1) of - 0 -> Bin; - _ -> e_type_bytes(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - if TrF2 =:= 0 -> B1; - true -> e_varint(TrF2, <>, TrUserData) - end - end - end, - B3 = if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end, - B4 = if F4 == undefined -> B3; - true -> - begin - TrF4 = id(F4, TrUserData), - if TrF4 =:= 0 -> B3; - true -> e_varint(TrF4, <>, TrUserData) - end - end - end, - if F5 == undefined -> B4; - true -> begin TrF5 = id(F5, TrUserData), e_mfield_sdl_send_register_event_v6_info(TrF5, <>, TrUserData) end - end. - -encode_msg_sdl_network_shutdown_event(Msg, TrUserData) -> encode_msg_sdl_network_shutdown_event(Msg, <<>>, TrUserData). - - -encode_msg_sdl_network_shutdown_event(#sdl_network_shutdown_event{message = F1}, Bin, TrUserData) -> - if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - case is_empty_string(TrF1) of - true -> Bin; - false -> e_type_string(TrF1, <>, TrUserData) - end - end - end. - -encode_msg_sdl_change_network_command(Msg, TrUserData) -> encode_msg_sdl_change_network_command(Msg, <<>>, TrUserData). - - -encode_msg_sdl_change_network_command(#sdl_change_network_command{dev_addr = F1, aes_key = F2}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= undefined -> Bin; - true -> e_mfield_sdl_change_network_command_dev_addr(TrF1, <>, TrUserData) - end - end - end, - if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end. - -encode_msg_sdl_command_ack(Msg, TrUserData) -> encode_msg_sdl_command_ack(Msg, <<>>, TrUserData). - - -encode_msg_sdl_command_ack(#sdl_command_ack{status = F1, message = F2}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= false -> Bin; - true -> e_type_bool(TrF1, <>, TrUserData) - end - end - end, - if F2 == undefined -> B1; - true -> begin TrF2 = id(F2, TrUserData), e_type_string(TrF2, <>, TrUserData) end - end. - -encode_msg_sdl_flows(Msg, TrUserData) -> encode_msg_sdl_flows(Msg, <<>>, TrUserData). - - -encode_msg_sdl_flows(#sdl_flows{forward_num = F1, p2p_num = F2, inbound_num = F3}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - if TrF2 =:= 0 -> B1; - true -> e_varint(TrF2, <>, TrUserData) - end - end - end, - if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end. - -encode_msg_sdl_stun_request(Msg, TrUserData) -> encode_msg_sdl_stun_request(Msg, <<>>, TrUserData). - - -encode_msg_sdl_stun_request(#sdl_stun_request{cookie = F1, client_id = F2, network_id = F3, mac = F4, ip = F5, nat_type = F6, v6_info = F7}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case is_empty_string(TrF2) of - true -> B1; - false -> e_type_string(TrF2, <>, TrUserData) - end - end - end, - B3 = if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end, - B4 = if F4 == undefined -> B3; - true -> - begin - TrF4 = id(F4, TrUserData), - case iolist_size(TrF4) of - 0 -> B3; - _ -> e_type_bytes(TrF4, <>, TrUserData) - end - end - end, - B5 = if F5 == undefined -> B4; - true -> - begin - TrF5 = id(F5, TrUserData), - if TrF5 =:= 0 -> B4; - true -> e_varint(TrF5, <>, TrUserData) - end - end - end, - B6 = if F6 == undefined -> B5; - true -> - begin - TrF6 = id(F6, TrUserData), - if TrF6 =:= 0 -> B5; - true -> e_varint(TrF6, <>, TrUserData) - end - end - end, - if F7 == undefined -> B6; - true -> begin TrF7 = id(F7, TrUserData), e_mfield_sdl_stun_request_v6_info(TrF7, <>, TrUserData) end - end. - -encode_msg_sdl_stun_reply(Msg, TrUserData) -> encode_msg_sdl_stun_reply(Msg, <<>>, TrUserData). - - -encode_msg_sdl_stun_reply(#sdl_stun_reply{cookie = F1}, Bin, TrUserData) -> - if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end. - -encode_msg_sdl_data(Msg, TrUserData) -> encode_msg_sdl_data(Msg, <<>>, TrUserData). - - -encode_msg_sdl_data(#sdl_data{network_id = F1, src_mac = F2, dst_mac = F3, is_p2p = F4, ttl = F5, data = F6}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end, - B3 = if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - case iolist_size(TrF3) of - 0 -> B2; - _ -> e_type_bytes(TrF3, <>, TrUserData) - end - end - end, - B4 = if F4 == undefined -> B3; - true -> - begin - TrF4 = id(F4, TrUserData), - if TrF4 =:= false -> B3; - true -> e_type_bool(TrF4, <>, TrUserData) - end - end - end, - B5 = if F5 == undefined -> B4; - true -> - begin - TrF5 = id(F5, TrUserData), - if TrF5 =:= 0 -> B4; - true -> e_varint(TrF5, <>, TrUserData) - end - end - end, - if F6 == undefined -> B5; - true -> - begin - TrF6 = id(F6, TrUserData), - case iolist_size(TrF6) of - 0 -> B5; - _ -> e_type_bytes(TrF6, <>, TrUserData) - end - end - end. - -encode_msg_sdl_register(Msg, TrUserData) -> encode_msg_sdl_register(Msg, <<>>, TrUserData). - - -encode_msg_sdl_register(#sdl_register{network_id = F1, src_mac = F2, dst_mac = F3}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end, - if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - case iolist_size(TrF3) of - 0 -> B2; - _ -> e_type_bytes(TrF3, <>, TrUserData) - end - end - end. - -encode_msg_sdl_register_ack(Msg, TrUserData) -> encode_msg_sdl_register_ack(Msg, <<>>, TrUserData). - - -encode_msg_sdl_register_ack(#sdl_register_ack{network_id = F1, src_mac = F2, dst_mac = F3}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - case iolist_size(TrF2) of - 0 -> B1; - _ -> e_type_bytes(TrF2, <>, TrUserData) - end - end - end, - if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - case iolist_size(TrF3) of - 0 -> B2; - _ -> e_type_bytes(TrF3, <>, TrUserData) - end - end - end. - -encode_msg_sdl_stun_probe(Msg, TrUserData) -> encode_msg_sdl_stun_probe(Msg, <<>>, TrUserData). - - -encode_msg_sdl_stun_probe(#sdl_stun_probe{cookie = F1, attr = F2}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - if TrF2 =:= 0 -> B1; - true -> e_varint(TrF2, <>, TrUserData) - end - end - end. - -encode_msg_sdl_stun_probe_reply(Msg, TrUserData) -> encode_msg_sdl_stun_probe_reply(Msg, <<>>, TrUserData). - - -encode_msg_sdl_stun_probe_reply(#sdl_stun_probe_reply{cookie = F1, port = F2, ip = F3}, Bin, TrUserData) -> - B1 = if F1 == undefined -> Bin; - true -> - begin - TrF1 = id(F1, TrUserData), - if TrF1 =:= 0 -> Bin; - true -> e_varint(TrF1, <>, TrUserData) - end - end - end, - B2 = if F2 == undefined -> B1; - true -> - begin - TrF2 = id(F2, TrUserData), - if TrF2 =:= 0 -> B1; - true -> e_varint(TrF2, <>, TrUserData) - end - end - end, - if F3 == undefined -> B2; - true -> - begin - TrF3 = id(F3, TrUserData), - if TrF3 =:= 0 -> B2; - true -> e_varint(TrF3, <>, TrUserData) - end - end - end. - -e_mfield_sdl_register_super_dev_addr(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_dev_addr(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - -e_mfield_sdl_register_super_ack_dev_addr(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_dev_addr(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - -e_mfield_sdl_peer_info_v4_info(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_v4_info(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - -e_mfield_sdl_peer_info_v6_info(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_v6_info(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - -e_mfield_sdl_send_register_event_v6_info(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_v6_info(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - -e_mfield_sdl_change_network_command_dev_addr(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_dev_addr(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - -e_mfield_sdl_stun_request_v6_info(Msg, Bin, TrUserData) -> - SubBin = encode_msg_sdl_v6_info(Msg, <<>>, TrUserData), - Bin2 = e_varint(byte_size(SubBin), Bin), - <>. - --compile({nowarn_unused_function,e_type_sint/3}). -e_type_sint(Value, Bin, _TrUserData) when Value >= 0 -> e_varint(Value * 2, Bin); -e_type_sint(Value, Bin, _TrUserData) -> e_varint(Value * -2 - 1, Bin). - --compile({nowarn_unused_function,e_type_int32/3}). -e_type_int32(Value, Bin, _TrUserData) when 0 =< Value, Value =< 127 -> <>; -e_type_int32(Value, Bin, _TrUserData) -> - <> = <>, - e_varint(N, Bin). - --compile({nowarn_unused_function,e_type_int64/3}). -e_type_int64(Value, Bin, _TrUserData) when 0 =< Value, Value =< 127 -> <>; -e_type_int64(Value, Bin, _TrUserData) -> - <> = <>, - e_varint(N, Bin). - --compile({nowarn_unused_function,e_type_bool/3}). -e_type_bool(true, Bin, _TrUserData) -> <>; -e_type_bool(false, Bin, _TrUserData) -> <>; -e_type_bool(1, Bin, _TrUserData) -> <>; -e_type_bool(0, Bin, _TrUserData) -> <>. - --compile({nowarn_unused_function,e_type_string/3}). -e_type_string(S, Bin, _TrUserData) -> - Utf8 = unicode:characters_to_binary(S), - Bin2 = e_varint(byte_size(Utf8), Bin), - <>. - --compile({nowarn_unused_function,e_type_bytes/3}). -e_type_bytes(Bytes, Bin, _TrUserData) when is_binary(Bytes) -> - Bin2 = e_varint(byte_size(Bytes), Bin), - <>; -e_type_bytes(Bytes, Bin, _TrUserData) when is_list(Bytes) -> - BytesBin = iolist_to_binary(Bytes), - Bin2 = e_varint(byte_size(BytesBin), Bin), - <>. - --compile({nowarn_unused_function,e_type_fixed32/3}). -e_type_fixed32(Value, Bin, _TrUserData) -> <>. - --compile({nowarn_unused_function,e_type_sfixed32/3}). -e_type_sfixed32(Value, Bin, _TrUserData) -> <>. - --compile({nowarn_unused_function,e_type_fixed64/3}). -e_type_fixed64(Value, Bin, _TrUserData) -> <>. - --compile({nowarn_unused_function,e_type_sfixed64/3}). -e_type_sfixed64(Value, Bin, _TrUserData) -> <>. - --compile({nowarn_unused_function,e_type_float/3}). -e_type_float(V, Bin, _) when is_number(V) -> <>; -e_type_float(infinity, Bin, _) -> <>; -e_type_float('-infinity', Bin, _) -> <>; -e_type_float(nan, Bin, _) -> <>. - --compile({nowarn_unused_function,e_type_double/3}). -e_type_double(V, Bin, _) when is_number(V) -> <>; -e_type_double(infinity, Bin, _) -> <>; -e_type_double('-infinity', Bin, _) -> <>; -e_type_double(nan, Bin, _) -> <>. - --compile({nowarn_unused_function,e_unknown_elems/2}). -e_unknown_elems([Elem | Rest], Bin) -> - BinR = case Elem of - {varint, FNum, N} -> - BinF = e_varint(FNum bsl 3, Bin), - e_varint(N, BinF); - {length_delimited, FNum, Data} -> - BinF = e_varint(FNum bsl 3 bor 2, Bin), - BinL = e_varint(byte_size(Data), BinF), - <>; - {group, FNum, GroupFields} -> - Bin1 = e_varint(FNum bsl 3 bor 3, Bin), - Bin2 = e_unknown_elems(GroupFields, Bin1), - e_varint(FNum bsl 3 bor 4, Bin2); - {fixed32, FNum, V} -> - BinF = e_varint(FNum bsl 3 bor 5, Bin), - <>; - {fixed64, FNum, V} -> - BinF = e_varint(FNum bsl 3 bor 1, Bin), - <> - end, - e_unknown_elems(Rest, BinR); -e_unknown_elems([], Bin) -> Bin. - --compile({nowarn_unused_function,e_varint/3}). -e_varint(N, Bin, _TrUserData) -> e_varint(N, Bin). - --compile({nowarn_unused_function,e_varint/2}). -e_varint(N, Bin) when N =< 127 -> <>; -e_varint(N, Bin) -> - Bin2 = <>, - e_varint(N bsr 7, Bin2). - -is_empty_string("") -> true; -is_empty_string(<<>>) -> true; -is_empty_string(L) when is_list(L) -> not string_has_chars(L); -is_empty_string(B) when is_binary(B) -> false. - -string_has_chars([C | _]) when is_integer(C) -> true; -string_has_chars([H | T]) -> - case string_has_chars(H) of - true -> true; - false -> string_has_chars(T) - end; -string_has_chars(B) when is_binary(B), byte_size(B) =/= 0 -> true; -string_has_chars(C) when is_integer(C) -> true; -string_has_chars(<<>>) -> false; -string_has_chars([]) -> false. - - -decode_msg(Bin, MsgName) when is_binary(Bin) -> decode_msg(Bin, MsgName, []). - -decode_msg(Bin, MsgName, Opts) when is_binary(Bin) -> - TrUserData = proplists:get_value(user_data, Opts), - decode_msg_1_catch(Bin, MsgName, TrUserData). - --ifdef('OTP_RELEASE'). -decode_msg_1_catch(Bin, MsgName, TrUserData) -> - try decode_msg_2_doit(MsgName, Bin, TrUserData) - catch - error:{gpb_error,_}=Reason:StackTrace -> - erlang:raise(error, Reason, StackTrace); - Class:Reason:StackTrace -> error({gpb_error,{decoding_failure, {Bin, MsgName, {Class, Reason, StackTrace}}}}) - end. --else. -decode_msg_1_catch(Bin, MsgName, TrUserData) -> - try decode_msg_2_doit(MsgName, Bin, TrUserData) - catch - error:{gpb_error,_}=Reason -> - erlang:raise(error, Reason, - erlang:get_stacktrace()); - Class:Reason -> - StackTrace = erlang:get_stacktrace(), - error({gpb_error,{decoding_failure, {Bin, MsgName, {Class, Reason, StackTrace}}}}) - end. --endif. - -decode_msg_2_doit(sdl_v4_info, Bin, TrUserData) -> id(decode_msg_sdl_v4_info(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_v6_info, Bin, TrUserData) -> id(decode_msg_sdl_v6_info(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_dev_addr, Bin, TrUserData) -> id(decode_msg_sdl_dev_addr(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_empty, Bin, TrUserData) -> id(decode_msg_sdl_empty(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_register_super, Bin, TrUserData) -> id(decode_msg_sdl_register_super(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_register_super_ack, Bin, TrUserData) -> id(decode_msg_sdl_register_super_ack(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_register_super_nak, Bin, TrUserData) -> id(decode_msg_sdl_register_super_nak(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_query_info, Bin, TrUserData) -> id(decode_msg_sdl_query_info(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_peer_info, Bin, TrUserData) -> id(decode_msg_sdl_peer_info(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_nat_changed_event, Bin, TrUserData) -> id(decode_msg_sdl_nat_changed_event(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_send_register_event, Bin, TrUserData) -> id(decode_msg_sdl_send_register_event(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_network_shutdown_event, Bin, TrUserData) -> id(decode_msg_sdl_network_shutdown_event(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_change_network_command, Bin, TrUserData) -> id(decode_msg_sdl_change_network_command(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_command_ack, Bin, TrUserData) -> id(decode_msg_sdl_command_ack(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_flows, Bin, TrUserData) -> id(decode_msg_sdl_flows(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_stun_request, Bin, TrUserData) -> id(decode_msg_sdl_stun_request(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_stun_reply, Bin, TrUserData) -> id(decode_msg_sdl_stun_reply(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_data, Bin, TrUserData) -> id(decode_msg_sdl_data(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_register, Bin, TrUserData) -> id(decode_msg_sdl_register(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_register_ack, Bin, TrUserData) -> id(decode_msg_sdl_register_ack(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_stun_probe, Bin, TrUserData) -> id(decode_msg_sdl_stun_probe(Bin, TrUserData), TrUserData); -decode_msg_2_doit(sdl_stun_probe_reply, Bin, TrUserData) -> id(decode_msg_sdl_stun_probe_reply(Bin, TrUserData), TrUserData). - - - -decode_msg_sdl_v4_info(Bin, TrUserData) -> dfp_read_field_def_sdl_v4_info(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), TrUserData). - -dfp_read_field_def_sdl_v4_info(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_v4_info_port(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_v4_info(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_v4_info_v4(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_v4_info(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_v4_info_nat_type(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_v4_info(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_v4_info{port = F@_1, v4 = F@_2, nat_type = F@_3}; -dfp_read_field_def_sdl_v4_info(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_sdl_v4_info(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -dg_read_field_def_sdl_v4_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_v4_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -dg_read_field_def_sdl_v4_info(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_v4_info_port(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 18 -> d_field_sdl_v4_info_v4(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 24 -> d_field_sdl_v4_info_nat_type(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_v4_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 1 -> skip_64_sdl_v4_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 2 -> skip_length_delimited_sdl_v4_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 3 -> skip_group_sdl_v4_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 5 -> skip_32_sdl_v4_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) - end - end; -dg_read_field_def_sdl_v4_info(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_v4_info{port = F@_1, v4 = F@_2, nat_type = F@_3}. - -d_field_sdl_v4_info_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_v4_info_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_v4_info_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_v4_info(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). - -d_field_sdl_v4_info_v4(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_v4_info_v4(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_v4_info_v4(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_v4_info(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). - -d_field_sdl_v4_info_nat_type(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_v4_info_nat_type(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_v4_info_nat_type(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_v4_info(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). - -skip_varint_sdl_v4_info(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_sdl_v4_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -skip_varint_sdl_v4_info(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_v4_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_length_delimited_sdl_v4_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_sdl_v4_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -skip_length_delimited_sdl_v4_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_v4_info(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). - -skip_group_sdl_v4_info(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_v4_info(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). - -skip_32_sdl_v4_info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_v4_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_64_sdl_v4_info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_v4_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -decode_msg_sdl_v6_info(Bin, TrUserData) -> dfp_read_field_def_sdl_v6_info(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_v6_info(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_v6_info_port(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_v6_info(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_v6_info_v6(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_v6_info(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_v6_info{port = F@_1, v6 = F@_2}; -dfp_read_field_def_sdl_v6_info(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_sdl_v6_info(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). - -dg_read_field_def_sdl_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -dg_read_field_def_sdl_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_v6_info_port(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - 18 -> d_field_sdl_v6_info_v6(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_v6_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 1 -> skip_64_sdl_v6_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 2 -> skip_length_delimited_sdl_v6_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 3 -> skip_group_sdl_v6_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 5 -> skip_32_sdl_v6_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) - end - end; -dg_read_field_def_sdl_v6_info(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_v6_info{port = F@_1, v6 = F@_2}. - -d_field_sdl_v6_info_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_v6_info_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_v6_info_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_v6_info(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). - -d_field_sdl_v6_info_v6(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_v6_info_v6(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_v6_info_v6(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_v6_info(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). - -skip_varint_sdl_v6_info(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_sdl_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -skip_varint_sdl_v6_info(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_length_delimited_sdl_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_sdl_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -skip_length_delimited_sdl_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_v6_info(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). - -skip_group_sdl_v6_info(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_v6_info(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). - -skip_32_sdl_v6_info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_64_sdl_v6_info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -decode_msg_sdl_dev_addr(Bin, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_dev_addr(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_dev_addr(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_dev_addr(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_net_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_dev_addr(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_net_bit_len(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_dev_addr(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_network_domain(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_dev_addr(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_dev_addr{network_id = F@_1, mac = F@_2, net_addr = F@_3, net_bit_len = F@_4, network_domain = F@_5}; -dfp_read_field_def_sdl_dev_addr(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dg_read_field_def_sdl_dev_addr(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -dg_read_field_def_sdl_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dg_read_field_def_sdl_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_dev_addr_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 18 -> d_field_sdl_dev_addr_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 24 -> d_field_sdl_dev_addr_net_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 32 -> d_field_sdl_dev_addr_net_bit_len(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 42 -> d_field_sdl_dev_addr_network_domain(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 1 -> skip_64_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 2 -> skip_length_delimited_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 3 -> skip_group_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 5 -> skip_32_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) - end - end; -dg_read_field_def_sdl_dev_addr(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_dev_addr{network_id = F@_1, mac = F@_2, net_addr = F@_3, net_bit_len = F@_4, network_domain = F@_5}. - -d_field_sdl_dev_addr_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_dev_addr_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, TrUserData). - -d_field_sdl_dev_addr_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_dev_addr_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData). - -d_field_sdl_dev_addr_net_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_net_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_dev_addr_net_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData). - -d_field_sdl_dev_addr_net_bit_len(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_net_bit_len(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_dev_addr_net_bit_len(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData). - -d_field_sdl_dev_addr_network_domain(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_network_domain(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_dev_addr_network_domain(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, TrUserData). - -skip_varint_sdl_dev_addr(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> skip_varint_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -skip_varint_sdl_dev_addr(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_length_delimited_sdl_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> skip_length_delimited_sdl_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -skip_length_delimited_sdl_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_dev_addr(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_group_sdl_dev_addr(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_dev_addr(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_32_sdl_dev_addr(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_64_sdl_dev_addr(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -decode_msg_sdl_empty(Bin, TrUserData) -> dfp_read_field_def_sdl_empty(Bin, 0, 0, 0, TrUserData). - -dfp_read_field_def_sdl_empty(<<>>, 0, 0, _, _) -> #sdl_empty{}; -dfp_read_field_def_sdl_empty(Other, Z1, Z2, F, TrUserData) -> dg_read_field_def_sdl_empty(Other, Z1, Z2, F, TrUserData). - -dg_read_field_def_sdl_empty(<<1:1, X:7, Rest/binary>>, N, Acc, F, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_empty(Rest, N + 7, X bsl N + Acc, F, TrUserData); -dg_read_field_def_sdl_empty(<<0:1, X:7, Rest/binary>>, N, Acc, _, TrUserData) -> - Key = X bsl N + Acc, - case Key band 7 of - 0 -> skip_varint_sdl_empty(Rest, 0, 0, Key bsr 3, TrUserData); - 1 -> skip_64_sdl_empty(Rest, 0, 0, Key bsr 3, TrUserData); - 2 -> skip_length_delimited_sdl_empty(Rest, 0, 0, Key bsr 3, TrUserData); - 3 -> skip_group_sdl_empty(Rest, 0, 0, Key bsr 3, TrUserData); - 5 -> skip_32_sdl_empty(Rest, 0, 0, Key bsr 3, TrUserData) - end; -dg_read_field_def_sdl_empty(<<>>, 0, 0, _, _) -> #sdl_empty{}. - -skip_varint_sdl_empty(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, TrUserData) -> skip_varint_sdl_empty(Rest, Z1, Z2, F, TrUserData); -skip_varint_sdl_empty(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_sdl_empty(Rest, Z1, Z2, F, TrUserData). - -skip_length_delimited_sdl_empty(<<1:1, X:7, Rest/binary>>, N, Acc, F, TrUserData) when N < 57 -> skip_length_delimited_sdl_empty(Rest, N + 7, X bsl N + Acc, F, TrUserData); -skip_length_delimited_sdl_empty(<<0:1, X:7, Rest/binary>>, N, Acc, F, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_empty(Rest2, 0, 0, F, TrUserData). - -skip_group_sdl_empty(Bin, _, Z2, FNum, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_empty(Rest, 0, Z2, FNum, TrUserData). - -skip_32_sdl_empty(<<_:32, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_sdl_empty(Rest, Z1, Z2, F, TrUserData). - -skip_64_sdl_empty(<<_:64, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_sdl_empty(Rest, Z1, Z2, F, TrUserData). - -decode_msg_sdl_register_super(Bin, TrUserData) -> - dfp_read_field_def_sdl_register_super(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(undefined, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_register_super(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_version(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - d_field_sdl_register_super_installed_channel(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_client_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_pub_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<50, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<58, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_network_code(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<66, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_hostname(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> - #sdl_register_super{version = F@_1, installed_channel = F@_2, client_id = F@_3, dev_addr = F@_4, pub_key = F@_5, token = F@_6, network_code = F@_7, hostname = F@_8}; -dfp_read_field_def_sdl_register_super(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dg_read_field_def_sdl_register_super(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -dg_read_field_def_sdl_register_super(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 32 - 7 -> - dg_read_field_def_sdl_register_super(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dg_read_field_def_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_register_super_version(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 18 -> d_field_sdl_register_super_installed_channel(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 26 -> d_field_sdl_register_super_client_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 34 -> d_field_sdl_register_super_dev_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 42 -> d_field_sdl_register_super_pub_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 50 -> d_field_sdl_register_super_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 58 -> d_field_sdl_register_super_network_code(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 66 -> d_field_sdl_register_super_hostname(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 1 -> skip_64_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 2 -> skip_length_delimited_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 3 -> skip_group_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 5 -> skip_32_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) - end - end; -dg_read_field_def_sdl_register_super(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> - #sdl_register_super{version = F@_1, installed_channel = F@_2, client_id = F@_3, dev_addr = F@_4, pub_key = F@_5, token = F@_6, network_code = F@_7, hostname = F@_8}. - -d_field_sdl_register_super_version(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_version(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_version(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -d_field_sdl_register_super_installed_channel(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_installed_channel(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_installed_channel(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -d_field_sdl_register_super_client_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_client_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_client_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -d_field_sdl_register_super_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, Prev, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_dev_addr(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, - 0, - 0, - F, - F@_1, - F@_2, - F@_3, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_dev_addr(Prev, NewFValue, TrUserData) - end, - F@_5, - F@_6, - F@_7, - F@_8, - TrUserData). - -d_field_sdl_register_super_pub_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_pub_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_pub_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, F@_7, F@_8, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, F@_7, F@_8, TrUserData). - -d_field_sdl_register_super_token(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_token(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, F@_7, F@_8, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, NewFValue, F@_7, F@_8, TrUserData). - -d_field_sdl_register_super_network_code(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_network_code(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_network_code(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _, F@_8, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, NewFValue, F@_8, TrUserData). - -d_field_sdl_register_super_hostname(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_hostname(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_hostname(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, NewFValue, TrUserData). - -skip_varint_sdl_register_super(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> skip_varint_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -skip_varint_sdl_register_super(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -skip_length_delimited_sdl_register_super(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - skip_length_delimited_sdl_register_super(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -skip_length_delimited_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_register_super(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -skip_group_sdl_register_super(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_register_super(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -skip_32_sdl_register_super(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -skip_64_sdl_register_super(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). - -decode_msg_sdl_register_super_ack(Bin, TrUserData) -> dfp_read_field_def_sdl_register_super_ack(Bin, 0, 0, 0, id(undefined, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(undefined, TrUserData), id(undefined, TrUserData), TrUserData). - -dfp_read_field_def_sdl_register_super_ack(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_register_super_ack_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_register_super_ack(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_register_super_ack_aes_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_register_super_ack(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_register_super_ack_upgrade_type(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_register_super_ack(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_register_super_ack_upgrade_prompt(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_register_super_ack(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_register_super_ack_upgrade_address(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_register_super_ack(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_register_super_ack{dev_addr = F@_1, aes_key = F@_2, upgrade_type = F@_3, upgrade_prompt = F@_4, upgrade_address = F@_5}; -dfp_read_field_def_sdl_register_super_ack(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dg_read_field_def_sdl_register_super_ack(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -dg_read_field_def_sdl_register_super_ack(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> - dg_read_field_def_sdl_register_super_ack(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dg_read_field_def_sdl_register_super_ack(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_register_super_ack_dev_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 18 -> d_field_sdl_register_super_ack_aes_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 24 -> d_field_sdl_register_super_ack_upgrade_type(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 34 -> d_field_sdl_register_super_ack_upgrade_prompt(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 42 -> d_field_sdl_register_super_ack_upgrade_address(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_register_super_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 1 -> skip_64_sdl_register_super_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 2 -> skip_length_delimited_sdl_register_super_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 3 -> skip_group_sdl_register_super_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 5 -> skip_32_sdl_register_super_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) - end - end; -dg_read_field_def_sdl_register_super_ack(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_register_super_ack{dev_addr = F@_1, aes_key = F@_2, upgrade_type = F@_3, upgrade_prompt = F@_4, upgrade_address = F@_5}. - -d_field_sdl_register_super_ack_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_register_super_ack_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_register_super_ack_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_dev_addr(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super_ack(RestF, - 0, - 0, - F, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_dev_addr(Prev, NewFValue, TrUserData) - end, - F@_2, - F@_3, - F@_4, - F@_5, - TrUserData). - -d_field_sdl_register_super_ack_aes_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_register_super_ack_aes_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_register_super_ack_aes_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super_ack(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData). - -d_field_sdl_register_super_ack_upgrade_type(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> - d_field_sdl_register_super_ack_upgrade_type(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_register_super_ack_upgrade_type(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_register_super_ack(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData). - -d_field_sdl_register_super_ack_upgrade_prompt(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> - d_field_sdl_register_super_ack_upgrade_prompt(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_register_super_ack_upgrade_prompt(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super_ack(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData). - -d_field_sdl_register_super_ack_upgrade_address(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> - d_field_sdl_register_super_ack_upgrade_address(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_register_super_ack_upgrade_address(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super_ack(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, TrUserData). - -skip_varint_sdl_register_super_ack(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> skip_varint_sdl_register_super_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -skip_varint_sdl_register_super_ack(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_register_super_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_length_delimited_sdl_register_super_ack(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> - skip_length_delimited_sdl_register_super_ack(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -skip_length_delimited_sdl_register_super_ack(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_register_super_ack(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_group_sdl_register_super_ack(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_register_super_ack(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_32_sdl_register_super_ack(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_register_super_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_64_sdl_register_super_ack(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_register_super_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -decode_msg_sdl_register_super_nak(Bin, TrUserData) -> dfp_read_field_def_sdl_register_super_nak(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_register_super_nak(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_register_super_nak_error_code(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_register_super_nak(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_register_super_nak_error_message(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_register_super_nak(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_register_super_nak{error_code = F@_1, error_message = F@_2}; -dfp_read_field_def_sdl_register_super_nak(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_sdl_register_super_nak(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). - -dg_read_field_def_sdl_register_super_nak(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_register_super_nak(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -dg_read_field_def_sdl_register_super_nak(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_register_super_nak_error_code(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - 18 -> d_field_sdl_register_super_nak_error_message(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_register_super_nak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 1 -> skip_64_sdl_register_super_nak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 2 -> skip_length_delimited_sdl_register_super_nak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 3 -> skip_group_sdl_register_super_nak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 5 -> skip_32_sdl_register_super_nak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) - end - end; -dg_read_field_def_sdl_register_super_nak(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_register_super_nak{error_code = F@_1, error_message = F@_2}. - -d_field_sdl_register_super_nak_error_code(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_register_super_nak_error_code(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_register_super_nak_error_code(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_register_super_nak(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). - -d_field_sdl_register_super_nak_error_message(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_register_super_nak_error_message(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_register_super_nak_error_message(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_super_nak(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). - -skip_varint_sdl_register_super_nak(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_sdl_register_super_nak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -skip_varint_sdl_register_super_nak(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_register_super_nak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_length_delimited_sdl_register_super_nak(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_sdl_register_super_nak(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -skip_length_delimited_sdl_register_super_nak(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_register_super_nak(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). - -skip_group_sdl_register_super_nak(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_register_super_nak(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). - -skip_32_sdl_register_super_nak(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_register_super_nak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_64_sdl_register_super_nak(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_register_super_nak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -decode_msg_sdl_query_info(Bin, TrUserData) -> dfp_read_field_def_sdl_query_info(Bin, 0, 0, 0, id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_query_info(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_sdl_query_info_dst_mac(Rest, Z1, Z2, F, F@_1, TrUserData); -dfp_read_field_def_sdl_query_info(<<>>, 0, 0, _, F@_1, _) -> #sdl_query_info{dst_mac = F@_1}; -dfp_read_field_def_sdl_query_info(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_sdl_query_info(Other, Z1, Z2, F, F@_1, TrUserData). - -dg_read_field_def_sdl_query_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_query_info(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -dg_read_field_def_sdl_query_info(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_query_info_dst_mac(Rest, 0, 0, 0, F@_1, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_query_info(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 1 -> skip_64_sdl_query_info(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 2 -> skip_length_delimited_sdl_query_info(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 3 -> skip_group_sdl_query_info(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 5 -> skip_32_sdl_query_info(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) - end - end; -dg_read_field_def_sdl_query_info(<<>>, 0, 0, _, F@_1, _) -> #sdl_query_info{dst_mac = F@_1}. - -d_field_sdl_query_info_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_sdl_query_info_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -d_field_sdl_query_info_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_query_info(RestF, 0, 0, F, NewFValue, TrUserData). - -skip_varint_sdl_query_info(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_sdl_query_info(Rest, Z1, Z2, F, F@_1, TrUserData); -skip_varint_sdl_query_info(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_query_info(Rest, Z1, Z2, F, F@_1, TrUserData). - -skip_length_delimited_sdl_query_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> skip_length_delimited_sdl_query_info(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -skip_length_delimited_sdl_query_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_query_info(Rest2, 0, 0, F, F@_1, TrUserData). - -skip_group_sdl_query_info(Bin, _, Z2, FNum, F@_1, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_query_info(Rest, 0, Z2, FNum, F@_1, TrUserData). - -skip_32_sdl_query_info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_query_info(Rest, Z1, Z2, F, F@_1, TrUserData). - -skip_64_sdl_query_info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_query_info(Rest, Z1, Z2, F, F@_1, TrUserData). - -decode_msg_sdl_peer_info(Bin, TrUserData) -> dfp_read_field_def_sdl_peer_info(Bin, 0, 0, 0, id(<<>>, TrUserData), id(undefined, TrUserData), id(undefined, TrUserData), TrUserData). - -dfp_read_field_def_sdl_peer_info(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_peer_info_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_peer_info(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_peer_info_v4_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_peer_info(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_peer_info_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_peer_info(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_peer_info{dst_mac = F@_1, v4_info = F@_2, v6_info = F@_3}; -dfp_read_field_def_sdl_peer_info(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_sdl_peer_info(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -dg_read_field_def_sdl_peer_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_peer_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -dg_read_field_def_sdl_peer_info(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_peer_info_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 18 -> d_field_sdl_peer_info_v4_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 26 -> d_field_sdl_peer_info_v6_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_peer_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 1 -> skip_64_sdl_peer_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 2 -> skip_length_delimited_sdl_peer_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 3 -> skip_group_sdl_peer_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 5 -> skip_32_sdl_peer_info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) - end - end; -dg_read_field_def_sdl_peer_info(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_peer_info{dst_mac = F@_1, v4_info = F@_2, v6_info = F@_3}. - -d_field_sdl_peer_info_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_peer_info_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_peer_info_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_peer_info(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). - -d_field_sdl_peer_info_v4_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_peer_info_v4_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_peer_info_v4_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, Prev, F@_3, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_v4_info(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_peer_info(RestF, - 0, - 0, - F, - F@_1, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_v4_info(Prev, NewFValue, TrUserData) - end, - F@_3, - TrUserData). - -d_field_sdl_peer_info_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_peer_info_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_peer_info_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, Prev, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_v6_info(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_peer_info(RestF, - 0, - 0, - F, - F@_1, - F@_2, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_v6_info(Prev, NewFValue, TrUserData) - end, - TrUserData). - -skip_varint_sdl_peer_info(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_sdl_peer_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -skip_varint_sdl_peer_info(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_peer_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_length_delimited_sdl_peer_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_sdl_peer_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -skip_length_delimited_sdl_peer_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_peer_info(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). - -skip_group_sdl_peer_info(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_peer_info(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). - -skip_32_sdl_peer_info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_peer_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_64_sdl_peer_info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_peer_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -decode_msg_sdl_nat_changed_event(Bin, TrUserData) -> dfp_read_field_def_sdl_nat_changed_event(Bin, 0, 0, 0, id(<<>>, TrUserData), id(0, TrUserData), TrUserData). - -dfp_read_field_def_sdl_nat_changed_event(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_nat_changed_event_mac(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_nat_changed_event(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_nat_changed_event_ip(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_nat_changed_event(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_nat_changed_event{mac = F@_1, ip = F@_2}; -dfp_read_field_def_sdl_nat_changed_event(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_sdl_nat_changed_event(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). - -dg_read_field_def_sdl_nat_changed_event(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_nat_changed_event(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -dg_read_field_def_sdl_nat_changed_event(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_nat_changed_event_mac(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - 16 -> d_field_sdl_nat_changed_event_ip(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_nat_changed_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 1 -> skip_64_sdl_nat_changed_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 2 -> skip_length_delimited_sdl_nat_changed_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 3 -> skip_group_sdl_nat_changed_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 5 -> skip_32_sdl_nat_changed_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) - end - end; -dg_read_field_def_sdl_nat_changed_event(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_nat_changed_event{mac = F@_1, ip = F@_2}. - -d_field_sdl_nat_changed_event_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_nat_changed_event_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_nat_changed_event_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_nat_changed_event(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). - -d_field_sdl_nat_changed_event_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_nat_changed_event_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_nat_changed_event_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_nat_changed_event(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). - -skip_varint_sdl_nat_changed_event(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_sdl_nat_changed_event(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -skip_varint_sdl_nat_changed_event(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_nat_changed_event(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_length_delimited_sdl_nat_changed_event(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_sdl_nat_changed_event(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -skip_length_delimited_sdl_nat_changed_event(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_nat_changed_event(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). - -skip_group_sdl_nat_changed_event(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_nat_changed_event(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). - -skip_32_sdl_nat_changed_event(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_nat_changed_event(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_64_sdl_nat_changed_event(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_nat_changed_event(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -decode_msg_sdl_send_register_event(Bin, TrUserData) -> dfp_read_field_def_sdl_send_register_event(Bin, 0, 0, 0, id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), id(undefined, TrUserData), TrUserData). - -dfp_read_field_def_sdl_send_register_event(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_send_register_event_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_send_register_event(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_send_register_event_nat_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_send_register_event(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_send_register_event_nat_port(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_send_register_event(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_send_register_event_nat_type(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_send_register_event(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_send_register_event_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_sdl_send_register_event(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_send_register_event{dst_mac = F@_1, nat_ip = F@_2, nat_port = F@_3, nat_type = F@_4, v6_info = F@_5}; -dfp_read_field_def_sdl_send_register_event(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dg_read_field_def_sdl_send_register_event(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -dg_read_field_def_sdl_send_register_event(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> - dg_read_field_def_sdl_send_register_event(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dg_read_field_def_sdl_send_register_event(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_send_register_event_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 16 -> d_field_sdl_send_register_event_nat_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 24 -> d_field_sdl_send_register_event_nat_port(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 32 -> d_field_sdl_send_register_event_nat_type(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 42 -> d_field_sdl_send_register_event_v6_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_send_register_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 1 -> skip_64_sdl_send_register_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 2 -> skip_length_delimited_sdl_send_register_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 3 -> skip_group_sdl_send_register_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 5 -> skip_32_sdl_send_register_event(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) - end - end; -dg_read_field_def_sdl_send_register_event(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_send_register_event{dst_mac = F@_1, nat_ip = F@_2, nat_port = F@_3, nat_type = F@_4, v6_info = F@_5}. - -d_field_sdl_send_register_event_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_send_register_event_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_send_register_event_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_send_register_event(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, TrUserData). - -d_field_sdl_send_register_event_nat_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_send_register_event_nat_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_send_register_event_nat_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_send_register_event(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData). - -d_field_sdl_send_register_event_nat_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_send_register_event_nat_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_send_register_event_nat_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_send_register_event(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData). - -d_field_sdl_send_register_event_nat_type(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_send_register_event_nat_type(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_send_register_event_nat_type(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_send_register_event(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData). - -d_field_sdl_send_register_event_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_send_register_event_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_sdl_send_register_event_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, Prev, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_v6_info(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_send_register_event(RestF, - 0, - 0, - F, - F@_1, - F@_2, - F@_3, - F@_4, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_v6_info(Prev, NewFValue, TrUserData) - end, - TrUserData). - -skip_varint_sdl_send_register_event(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> skip_varint_sdl_send_register_event(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -skip_varint_sdl_send_register_event(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_send_register_event(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_length_delimited_sdl_send_register_event(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> - skip_length_delimited_sdl_send_register_event(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -skip_length_delimited_sdl_send_register_event(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_send_register_event(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_group_sdl_send_register_event(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_send_register_event(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_32_sdl_send_register_event(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_send_register_event(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -skip_64_sdl_send_register_event(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_send_register_event(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). - -decode_msg_sdl_network_shutdown_event(Bin, TrUserData) -> dfp_read_field_def_sdl_network_shutdown_event(Bin, 0, 0, 0, id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_network_shutdown_event(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_sdl_network_shutdown_event_message(Rest, Z1, Z2, F, F@_1, TrUserData); -dfp_read_field_def_sdl_network_shutdown_event(<<>>, 0, 0, _, F@_1, _) -> #sdl_network_shutdown_event{message = F@_1}; -dfp_read_field_def_sdl_network_shutdown_event(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_sdl_network_shutdown_event(Other, Z1, Z2, F, F@_1, TrUserData). - -dg_read_field_def_sdl_network_shutdown_event(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_network_shutdown_event(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -dg_read_field_def_sdl_network_shutdown_event(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_network_shutdown_event_message(Rest, 0, 0, 0, F@_1, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_network_shutdown_event(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 1 -> skip_64_sdl_network_shutdown_event(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 2 -> skip_length_delimited_sdl_network_shutdown_event(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 3 -> skip_group_sdl_network_shutdown_event(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 5 -> skip_32_sdl_network_shutdown_event(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) - end - end; -dg_read_field_def_sdl_network_shutdown_event(<<>>, 0, 0, _, F@_1, _) -> #sdl_network_shutdown_event{message = F@_1}. - -d_field_sdl_network_shutdown_event_message(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_sdl_network_shutdown_event_message(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -d_field_sdl_network_shutdown_event_message(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_network_shutdown_event(RestF, 0, 0, F, NewFValue, TrUserData). - -skip_varint_sdl_network_shutdown_event(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_sdl_network_shutdown_event(Rest, Z1, Z2, F, F@_1, TrUserData); -skip_varint_sdl_network_shutdown_event(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_network_shutdown_event(Rest, Z1, Z2, F, F@_1, TrUserData). - -skip_length_delimited_sdl_network_shutdown_event(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> skip_length_delimited_sdl_network_shutdown_event(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -skip_length_delimited_sdl_network_shutdown_event(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_network_shutdown_event(Rest2, 0, 0, F, F@_1, TrUserData). - -skip_group_sdl_network_shutdown_event(Bin, _, Z2, FNum, F@_1, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_network_shutdown_event(Rest, 0, Z2, FNum, F@_1, TrUserData). - -skip_32_sdl_network_shutdown_event(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_network_shutdown_event(Rest, Z1, Z2, F, F@_1, TrUserData). - -skip_64_sdl_network_shutdown_event(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_network_shutdown_event(Rest, Z1, Z2, F, F@_1, TrUserData). - -decode_msg_sdl_change_network_command(Bin, TrUserData) -> dfp_read_field_def_sdl_change_network_command(Bin, 0, 0, 0, id(undefined, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_change_network_command(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_change_network_command_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_change_network_command(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_change_network_command_aes_key(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_change_network_command(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_change_network_command{dev_addr = F@_1, aes_key = F@_2}; -dfp_read_field_def_sdl_change_network_command(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_sdl_change_network_command(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). - -dg_read_field_def_sdl_change_network_command(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_change_network_command(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -dg_read_field_def_sdl_change_network_command(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 10 -> d_field_sdl_change_network_command_dev_addr(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - 18 -> d_field_sdl_change_network_command_aes_key(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_change_network_command(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 1 -> skip_64_sdl_change_network_command(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 2 -> skip_length_delimited_sdl_change_network_command(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 3 -> skip_group_sdl_change_network_command(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 5 -> skip_32_sdl_change_network_command(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) - end - end; -dg_read_field_def_sdl_change_network_command(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_change_network_command{dev_addr = F@_1, aes_key = F@_2}. - -d_field_sdl_change_network_command_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_change_network_command_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_change_network_command_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, F@_2, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_dev_addr(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_change_network_command(RestF, - 0, - 0, - F, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_dev_addr(Prev, NewFValue, TrUserData) - end, - F@_2, - TrUserData). - -d_field_sdl_change_network_command_aes_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_change_network_command_aes_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_change_network_command_aes_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_change_network_command(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). - -skip_varint_sdl_change_network_command(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_sdl_change_network_command(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -skip_varint_sdl_change_network_command(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_change_network_command(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_length_delimited_sdl_change_network_command(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_sdl_change_network_command(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -skip_length_delimited_sdl_change_network_command(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_change_network_command(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). - -skip_group_sdl_change_network_command(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_change_network_command(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). - -skip_32_sdl_change_network_command(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_change_network_command(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_64_sdl_change_network_command(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_change_network_command(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -decode_msg_sdl_command_ack(Bin, TrUserData) -> dfp_read_field_def_sdl_command_ack(Bin, 0, 0, 0, id(false, TrUserData), id(undefined, TrUserData), TrUserData). - -dfp_read_field_def_sdl_command_ack(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_command_ack_status(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_command_ack(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_command_ack_message(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_command_ack(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_command_ack{status = F@_1, message = F@_2}; -dfp_read_field_def_sdl_command_ack(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_sdl_command_ack(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). - -dg_read_field_def_sdl_command_ack(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_command_ack(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -dg_read_field_def_sdl_command_ack(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_command_ack_status(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - 18 -> d_field_sdl_command_ack_message(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_command_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 1 -> skip_64_sdl_command_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 2 -> skip_length_delimited_sdl_command_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 3 -> skip_group_sdl_command_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 5 -> skip_32_sdl_command_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) - end - end; -dg_read_field_def_sdl_command_ack(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_command_ack{status = F@_1, message = F@_2}. - -d_field_sdl_command_ack_status(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_command_ack_status(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_command_ack_status(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> - {NewFValue, RestF} = {id(X bsl N + Acc =/= 0, TrUserData), Rest}, - dfp_read_field_def_sdl_command_ack(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). - -d_field_sdl_command_ack_message(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_command_ack_message(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_command_ack_message(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_command_ack(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). - -skip_varint_sdl_command_ack(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_sdl_command_ack(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -skip_varint_sdl_command_ack(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_command_ack(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_length_delimited_sdl_command_ack(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_sdl_command_ack(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -skip_length_delimited_sdl_command_ack(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_command_ack(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). - -skip_group_sdl_command_ack(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_command_ack(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). - -skip_32_sdl_command_ack(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_command_ack(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_64_sdl_command_ack(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_command_ack(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -decode_msg_sdl_flows(Bin, TrUserData) -> dfp_read_field_def_sdl_flows(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), TrUserData). - -dfp_read_field_def_sdl_flows(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_flows_forward_num(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_flows(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_flows_p2p_num(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_flows(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_flows_inbound_num(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_flows(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_flows{forward_num = F@_1, p2p_num = F@_2, inbound_num = F@_3}; -dfp_read_field_def_sdl_flows(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_sdl_flows(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -dg_read_field_def_sdl_flows(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_flows(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -dg_read_field_def_sdl_flows(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_flows_forward_num(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 16 -> d_field_sdl_flows_p2p_num(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 24 -> d_field_sdl_flows_inbound_num(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_flows(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 1 -> skip_64_sdl_flows(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 2 -> skip_length_delimited_sdl_flows(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 3 -> skip_group_sdl_flows(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 5 -> skip_32_sdl_flows(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) - end - end; -dg_read_field_def_sdl_flows(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_flows{forward_num = F@_1, p2p_num = F@_2, inbound_num = F@_3}. - -d_field_sdl_flows_forward_num(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_flows_forward_num(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_flows_forward_num(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_flows(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). - -d_field_sdl_flows_p2p_num(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_flows_p2p_num(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_flows_p2p_num(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_flows(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). - -d_field_sdl_flows_inbound_num(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_flows_inbound_num(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_flows_inbound_num(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_flows(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). - -skip_varint_sdl_flows(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_sdl_flows(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -skip_varint_sdl_flows(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_flows(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_length_delimited_sdl_flows(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_sdl_flows(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -skip_length_delimited_sdl_flows(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_flows(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). - -skip_group_sdl_flows(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_flows(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). - -skip_32_sdl_flows(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_flows(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_64_sdl_flows(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_flows(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -decode_msg_sdl_stun_request(Bin, TrUserData) -> - dfp_read_field_def_sdl_stun_request(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(undefined, TrUserData), TrUserData). - -dfp_read_field_def_sdl_stun_request(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_cookie(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_client_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<40, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<48, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_nat_type(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<58, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_sdl_stun_request_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dfp_read_field_def_sdl_stun_request(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _) -> #sdl_stun_request{cookie = F@_1, client_id = F@_2, network_id = F@_3, mac = F@_4, ip = F@_5, nat_type = F@_6, v6_info = F@_7}; -dfp_read_field_def_sdl_stun_request(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dg_read_field_def_sdl_stun_request(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -dg_read_field_def_sdl_stun_request(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 32 - 7 -> - dg_read_field_def_sdl_stun_request(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -dg_read_field_def_sdl_stun_request(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_stun_request_cookie(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 18 -> d_field_sdl_stun_request_client_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 24 -> d_field_sdl_stun_request_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 34 -> d_field_sdl_stun_request_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 40 -> d_field_sdl_stun_request_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 48 -> d_field_sdl_stun_request_nat_type(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 58 -> d_field_sdl_stun_request_v6_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_stun_request(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 1 -> skip_64_sdl_stun_request(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 2 -> skip_length_delimited_sdl_stun_request(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 3 -> skip_group_sdl_stun_request(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); - 5 -> skip_32_sdl_stun_request(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) - end - end; -dg_read_field_def_sdl_stun_request(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _) -> #sdl_stun_request{cookie = F@_1, client_id = F@_2, network_id = F@_3, mac = F@_4, ip = F@_5, nat_type = F@_6, v6_info = F@_7}. - -d_field_sdl_stun_request_cookie(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> - d_field_sdl_stun_request_cookie(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_cookie(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_request(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -d_field_sdl_stun_request_client_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> - d_field_sdl_stun_request_client_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_client_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_stun_request(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -d_field_sdl_stun_request_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> - d_field_sdl_stun_request_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, F@_7, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_request(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, F@_7, TrUserData). - -d_field_sdl_stun_request_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> d_field_sdl_stun_request_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, F@_6, F@_7, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_stun_request(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, F@_6, F@_7, TrUserData). - -d_field_sdl_stun_request_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> d_field_sdl_stun_request_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, F@_7, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_request(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, F@_7, TrUserData). - -d_field_sdl_stun_request_nat_type(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> - d_field_sdl_stun_request_nat_type(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_nat_type(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, F@_7, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_request(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, NewFValue, F@_7, TrUserData). - -d_field_sdl_stun_request_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> - d_field_sdl_stun_request_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -d_field_sdl_stun_request_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, Prev, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_sdl_v6_info(Bs, TrUserData), TrUserData), Rest2} end, - dfp_read_field_def_sdl_stun_request(RestF, - 0, - 0, - F, - F@_1, - F@_2, - F@_3, - F@_4, - F@_5, - F@_6, - if Prev == undefined -> NewFValue; - true -> merge_msg_sdl_v6_info(Prev, NewFValue, TrUserData) - end, - TrUserData). - -skip_varint_sdl_stun_request(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> skip_varint_sdl_stun_request(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -skip_varint_sdl_stun_request(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dfp_read_field_def_sdl_stun_request(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -skip_length_delimited_sdl_stun_request(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> - skip_length_delimited_sdl_stun_request(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); -skip_length_delimited_sdl_stun_request(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_stun_request(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -skip_group_sdl_stun_request(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_stun_request(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -skip_32_sdl_stun_request(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dfp_read_field_def_sdl_stun_request(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -skip_64_sdl_stun_request(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dfp_read_field_def_sdl_stun_request(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). - -decode_msg_sdl_stun_reply(Bin, TrUserData) -> dfp_read_field_def_sdl_stun_reply(Bin, 0, 0, 0, id(0, TrUserData), TrUserData). - -dfp_read_field_def_sdl_stun_reply(<<8, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_sdl_stun_reply_cookie(Rest, Z1, Z2, F, F@_1, TrUserData); -dfp_read_field_def_sdl_stun_reply(<<>>, 0, 0, _, F@_1, _) -> #sdl_stun_reply{cookie = F@_1}; -dfp_read_field_def_sdl_stun_reply(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_sdl_stun_reply(Other, Z1, Z2, F, F@_1, TrUserData). - -dg_read_field_def_sdl_stun_reply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_stun_reply(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -dg_read_field_def_sdl_stun_reply(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_stun_reply_cookie(Rest, 0, 0, 0, F@_1, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_stun_reply(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 1 -> skip_64_sdl_stun_reply(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 2 -> skip_length_delimited_sdl_stun_reply(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 3 -> skip_group_sdl_stun_reply(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); - 5 -> skip_32_sdl_stun_reply(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) - end - end; -dg_read_field_def_sdl_stun_reply(<<>>, 0, 0, _, F@_1, _) -> #sdl_stun_reply{cookie = F@_1}. - -d_field_sdl_stun_reply_cookie(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_sdl_stun_reply_cookie(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -d_field_sdl_stun_reply_cookie(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_reply(RestF, 0, 0, F, NewFValue, TrUserData). - -skip_varint_sdl_stun_reply(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_sdl_stun_reply(Rest, Z1, Z2, F, F@_1, TrUserData); -skip_varint_sdl_stun_reply(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_stun_reply(Rest, Z1, Z2, F, F@_1, TrUserData). - -skip_length_delimited_sdl_stun_reply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> skip_length_delimited_sdl_stun_reply(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -skip_length_delimited_sdl_stun_reply(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_stun_reply(Rest2, 0, 0, F, F@_1, TrUserData). - -skip_group_sdl_stun_reply(Bin, _, Z2, FNum, F@_1, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_stun_reply(Rest, 0, Z2, FNum, F@_1, TrUserData). - -skip_32_sdl_stun_reply(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_stun_reply(Rest, Z1, Z2, F, F@_1, TrUserData). - -skip_64_sdl_stun_reply(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_sdl_stun_reply(Rest, Z1, Z2, F, F@_1, TrUserData). - -decode_msg_sdl_data(Bin, TrUserData) -> dfp_read_field_def_sdl_data(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(false, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_data(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_data_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dfp_read_field_def_sdl_data(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_data_src_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dfp_read_field_def_sdl_data(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_data_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dfp_read_field_def_sdl_data(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_data_is_p2p(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dfp_read_field_def_sdl_data(<<40, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_data_ttl(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dfp_read_field_def_sdl_data(<<50, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_data_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dfp_read_field_def_sdl_data(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _) -> #sdl_data{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3, is_p2p = F@_4, ttl = F@_5, data = F@_6}; -dfp_read_field_def_sdl_data(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dg_read_field_def_sdl_data(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -dg_read_field_def_sdl_data(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_data(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -dg_read_field_def_sdl_data(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_data_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 18 -> d_field_sdl_data_src_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 26 -> d_field_sdl_data_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 32 -> d_field_sdl_data_is_p2p(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 40 -> d_field_sdl_data_ttl(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 50 -> d_field_sdl_data_data(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 1 -> skip_64_sdl_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 2 -> skip_length_delimited_sdl_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 3 -> skip_group_sdl_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); - 5 -> skip_32_sdl_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) - end - end; -dg_read_field_def_sdl_data(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _) -> #sdl_data{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3, is_p2p = F@_4, ttl = F@_5, data = F@_6}. - -d_field_sdl_data_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_data_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -d_field_sdl_data_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_data(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -d_field_sdl_data_src_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_data_src_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -d_field_sdl_data_src_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_data(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, TrUserData). - -d_field_sdl_data_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_data_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -d_field_sdl_data_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_data(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, TrUserData). - -d_field_sdl_data_is_p2p(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_data_is_p2p(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -d_field_sdl_data_is_p2p(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, F@_6, TrUserData) -> - {NewFValue, RestF} = {id(X bsl N + Acc =/= 0, TrUserData), Rest}, - dfp_read_field_def_sdl_data(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, F@_6, TrUserData). - -d_field_sdl_data_ttl(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_data_ttl(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -d_field_sdl_data_ttl(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_data(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, TrUserData). - -d_field_sdl_data_data(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_data_data(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -d_field_sdl_data_data(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_data(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, NewFValue, TrUserData). - -skip_varint_sdl_data(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> skip_varint_sdl_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -skip_varint_sdl_data(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dfp_read_field_def_sdl_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -skip_length_delimited_sdl_data(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> skip_length_delimited_sdl_data(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData); -skip_length_delimited_sdl_data(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_data(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -skip_group_sdl_data(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_data(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -skip_32_sdl_data(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dfp_read_field_def_sdl_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -skip_64_sdl_data(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dfp_read_field_def_sdl_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData). - -decode_msg_sdl_register(Bin, TrUserData) -> dfp_read_field_def_sdl_register(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_register(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_register_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_register(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_register_src_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_register(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_register_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_register(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_register{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}; -dfp_read_field_def_sdl_register(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_sdl_register(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -dg_read_field_def_sdl_register(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_register(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -dg_read_field_def_sdl_register(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_register_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 18 -> d_field_sdl_register_src_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 26 -> d_field_sdl_register_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_register(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 1 -> skip_64_sdl_register(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 2 -> skip_length_delimited_sdl_register(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 3 -> skip_group_sdl_register(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 5 -> skip_32_sdl_register(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) - end - end; -dg_read_field_def_sdl_register(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_register{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}. - -d_field_sdl_register_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_register_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_register_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_register(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). - -d_field_sdl_register_src_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_register_src_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_register_src_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). - -d_field_sdl_register_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_register_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_register_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). - -skip_varint_sdl_register(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_sdl_register(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -skip_varint_sdl_register(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_register(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_length_delimited_sdl_register(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_sdl_register(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -skip_length_delimited_sdl_register(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_register(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). - -skip_group_sdl_register(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_register(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). - -skip_32_sdl_register(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_register(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_64_sdl_register(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_register(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -decode_msg_sdl_register_ack(Bin, TrUserData) -> dfp_read_field_def_sdl_register_ack(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). - -dfp_read_field_def_sdl_register_ack(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_register_ack_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_register_ack(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_register_ack_src_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_register_ack(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_register_ack_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_register_ack(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_register_ack{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}; -dfp_read_field_def_sdl_register_ack(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_sdl_register_ack(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -dg_read_field_def_sdl_register_ack(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_register_ack(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -dg_read_field_def_sdl_register_ack(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_register_ack_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 18 -> d_field_sdl_register_ack_src_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 26 -> d_field_sdl_register_ack_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_register_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 1 -> skip_64_sdl_register_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 2 -> skip_length_delimited_sdl_register_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 3 -> skip_group_sdl_register_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 5 -> skip_32_sdl_register_ack(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) - end - end; -dg_read_field_def_sdl_register_ack(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_register_ack{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}. - -d_field_sdl_register_ack_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_register_ack_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_register_ack_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_register_ack(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). - -d_field_sdl_register_ack_src_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_register_ack_src_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_register_ack_src_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_ack(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). - -d_field_sdl_register_ack_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_register_ack_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_register_ack_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_sdl_register_ack(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). - -skip_varint_sdl_register_ack(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_sdl_register_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -skip_varint_sdl_register_ack(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_register_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_length_delimited_sdl_register_ack(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_sdl_register_ack(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -skip_length_delimited_sdl_register_ack(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_register_ack(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). - -skip_group_sdl_register_ack(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_register_ack(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). - -skip_32_sdl_register_ack(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_register_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_64_sdl_register_ack(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_register_ack(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -decode_msg_sdl_stun_probe(Bin, TrUserData) -> dfp_read_field_def_sdl_stun_probe(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), TrUserData). - -dfp_read_field_def_sdl_stun_probe(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_stun_probe_cookie(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_stun_probe(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_sdl_stun_probe_attr(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -dfp_read_field_def_sdl_stun_probe(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_stun_probe{cookie = F@_1, attr = F@_2}; -dfp_read_field_def_sdl_stun_probe(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_sdl_stun_probe(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). - -dg_read_field_def_sdl_stun_probe(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_stun_probe(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -dg_read_field_def_sdl_stun_probe(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_stun_probe_cookie(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - 16 -> d_field_sdl_stun_probe_attr(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_stun_probe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 1 -> skip_64_sdl_stun_probe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 2 -> skip_length_delimited_sdl_stun_probe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 3 -> skip_group_sdl_stun_probe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); - 5 -> skip_32_sdl_stun_probe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) - end - end; -dg_read_field_def_sdl_stun_probe(<<>>, 0, 0, _, F@_1, F@_2, _) -> #sdl_stun_probe{cookie = F@_1, attr = F@_2}. - -d_field_sdl_stun_probe_cookie(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_stun_probe_cookie(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_stun_probe_cookie(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_probe(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). - -d_field_sdl_stun_probe_attr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_sdl_stun_probe_attr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -d_field_sdl_stun_probe_attr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_probe(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). - -skip_varint_sdl_stun_probe(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_sdl_stun_probe(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); -skip_varint_sdl_stun_probe(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_stun_probe(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_length_delimited_sdl_stun_probe(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_sdl_stun_probe(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); -skip_length_delimited_sdl_stun_probe(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_stun_probe(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). - -skip_group_sdl_stun_probe(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_stun_probe(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). - -skip_32_sdl_stun_probe(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_stun_probe(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -skip_64_sdl_stun_probe(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_stun_probe(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). - -decode_msg_sdl_stun_probe_reply(Bin, TrUserData) -> dfp_read_field_def_sdl_stun_probe_reply(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), TrUserData). - -dfp_read_field_def_sdl_stun_probe_reply(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_stun_probe_reply_cookie(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_stun_probe_reply(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_stun_probe_reply_port(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_stun_probe_reply(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_sdl_stun_probe_reply_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -dfp_read_field_def_sdl_stun_probe_reply(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_stun_probe_reply{cookie = F@_1, port = F@_2, ip = F@_3}; -dfp_read_field_def_sdl_stun_probe_reply(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_sdl_stun_probe_reply(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -dg_read_field_def_sdl_stun_probe_reply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_stun_probe_reply(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -dg_read_field_def_sdl_stun_probe_reply(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> - Key = X bsl N + Acc, - case Key of - 8 -> d_field_sdl_stun_probe_reply_cookie(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 16 -> d_field_sdl_stun_probe_reply_port(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - 24 -> d_field_sdl_stun_probe_reply_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); - _ -> - case Key band 7 of - 0 -> skip_varint_sdl_stun_probe_reply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 1 -> skip_64_sdl_stun_probe_reply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 2 -> skip_length_delimited_sdl_stun_probe_reply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 3 -> skip_group_sdl_stun_probe_reply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); - 5 -> skip_32_sdl_stun_probe_reply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) - end - end; -dg_read_field_def_sdl_stun_probe_reply(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #sdl_stun_probe_reply{cookie = F@_1, port = F@_2, ip = F@_3}. - -d_field_sdl_stun_probe_reply_cookie(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_stun_probe_reply_cookie(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_stun_probe_reply_cookie(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_probe_reply(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). - -d_field_sdl_stun_probe_reply_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_stun_probe_reply_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_stun_probe_reply_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_probe_reply(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). - -d_field_sdl_stun_probe_reply_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_sdl_stun_probe_reply_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -d_field_sdl_stun_probe_reply_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> - {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, - dfp_read_field_def_sdl_stun_probe_reply(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). - -skip_varint_sdl_stun_probe_reply(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_sdl_stun_probe_reply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); -skip_varint_sdl_stun_probe_reply(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_stun_probe_reply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_length_delimited_sdl_stun_probe_reply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_sdl_stun_probe_reply(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); -skip_length_delimited_sdl_stun_probe_reply(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> - Length = X bsl N + Acc, - <<_:Length/binary, Rest2/binary>> = Rest, - dfp_read_field_def_sdl_stun_probe_reply(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). - -skip_group_sdl_stun_probe_reply(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> - {_, Rest} = read_group(Bin, FNum), - dfp_read_field_def_sdl_stun_probe_reply(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). - -skip_32_sdl_stun_probe_reply(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_stun_probe_reply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -skip_64_sdl_stun_probe_reply(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_sdl_stun_probe_reply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). - -read_group(Bin, FieldNum) -> - {NumBytes, EndTagLen} = read_gr_b(Bin, 0, 0, 0, 0, FieldNum), - <> = Bin, - {Group, Rest}. - -%% Like skipping over fields, but record the total length, -%% Each field is <(FieldNum bsl 3) bor FieldType> ++ -%% Record the length because varints may be non-optimally encoded. -%% -%% Groups can be nested, but assume the same FieldNum cannot be nested -%% because group field numbers are shared with the rest of the fields -%% numbers. Thus we can search just for an group-end with the same -%% field number. -%% -%% (The only time the same group field number could occur would -%% be in a nested sub message, but then it would be inside a -%% length-delimited entry, which we skip-read by length.) -read_gr_b(<<1:1, X:7, Tl/binary>>, N, Acc, NumBytes, TagLen, FieldNum) - when N < (32-7) -> - read_gr_b(Tl, N+7, X bsl N + Acc, NumBytes, TagLen+1, FieldNum); -read_gr_b(<<0:1, X:7, Tl/binary>>, N, Acc, NumBytes, TagLen, - FieldNum) -> - Key = X bsl N + Acc, - TagLen1 = TagLen + 1, - case {Key bsr 3, Key band 7} of - {FieldNum, 4} -> % 4 = group_end - {NumBytes, TagLen1}; - {_, 0} -> % 0 = varint - read_gr_vi(Tl, 0, NumBytes + TagLen1, FieldNum); - {_, 1} -> % 1 = bits64 - <<_:64, Tl2/binary>> = Tl, - read_gr_b(Tl2, 0, 0, NumBytes + TagLen1 + 8, 0, FieldNum); - {_, 2} -> % 2 = length_delimited - read_gr_ld(Tl, 0, 0, NumBytes + TagLen1, FieldNum); - {_, 3} -> % 3 = group_start - read_gr_b(Tl, 0, 0, NumBytes + TagLen1, 0, FieldNum); - {_, 4} -> % 4 = group_end - read_gr_b(Tl, 0, 0, NumBytes + TagLen1, 0, FieldNum); - {_, 5} -> % 5 = bits32 - <<_:32, Tl2/binary>> = Tl, - read_gr_b(Tl2, 0, 0, NumBytes + TagLen1 + 4, 0, FieldNum) - end. - -read_gr_vi(<<1:1, _:7, Tl/binary>>, N, NumBytes, FieldNum) - when N < (64-7) -> - read_gr_vi(Tl, N+7, NumBytes+1, FieldNum); -read_gr_vi(<<0:1, _:7, Tl/binary>>, _, NumBytes, FieldNum) -> - read_gr_b(Tl, 0, 0, NumBytes+1, 0, FieldNum). - -read_gr_ld(<<1:1, X:7, Tl/binary>>, N, Acc, NumBytes, FieldNum) - when N < (64-7) -> - read_gr_ld(Tl, N+7, X bsl N + Acc, NumBytes+1, FieldNum); -read_gr_ld(<<0:1, X:7, Tl/binary>>, N, Acc, NumBytes, FieldNum) -> - Len = X bsl N + Acc, - NumBytes1 = NumBytes + 1, - <<_:Len/binary, Tl2/binary>> = Tl, - read_gr_b(Tl2, 0, 0, NumBytes1 + Len, 0, FieldNum). - -merge_msgs(Prev, New) when element(1, Prev) =:= element(1, New) -> merge_msgs(Prev, New, element(1, Prev), []). - -merge_msgs(Prev, New, MsgName) when is_atom(MsgName) -> merge_msgs(Prev, New, MsgName, []); -merge_msgs(Prev, New, Opts) when element(1, Prev) =:= element(1, New), is_list(Opts) -> merge_msgs(Prev, New, element(1, Prev), Opts). - -merge_msgs(Prev, New, MsgName, Opts) -> - TrUserData = proplists:get_value(user_data, Opts), - case MsgName of - sdl_v4_info -> merge_msg_sdl_v4_info(Prev, New, TrUserData); - sdl_v6_info -> merge_msg_sdl_v6_info(Prev, New, TrUserData); - sdl_dev_addr -> merge_msg_sdl_dev_addr(Prev, New, TrUserData); - sdl_empty -> merge_msg_sdl_empty(Prev, New, TrUserData); - sdl_register_super -> merge_msg_sdl_register_super(Prev, New, TrUserData); - sdl_register_super_ack -> merge_msg_sdl_register_super_ack(Prev, New, TrUserData); - sdl_register_super_nak -> merge_msg_sdl_register_super_nak(Prev, New, TrUserData); - sdl_query_info -> merge_msg_sdl_query_info(Prev, New, TrUserData); - sdl_peer_info -> merge_msg_sdl_peer_info(Prev, New, TrUserData); - sdl_nat_changed_event -> merge_msg_sdl_nat_changed_event(Prev, New, TrUserData); - sdl_send_register_event -> merge_msg_sdl_send_register_event(Prev, New, TrUserData); - sdl_network_shutdown_event -> merge_msg_sdl_network_shutdown_event(Prev, New, TrUserData); - sdl_change_network_command -> merge_msg_sdl_change_network_command(Prev, New, TrUserData); - sdl_command_ack -> merge_msg_sdl_command_ack(Prev, New, TrUserData); - sdl_flows -> merge_msg_sdl_flows(Prev, New, TrUserData); - sdl_stun_request -> merge_msg_sdl_stun_request(Prev, New, TrUserData); - sdl_stun_reply -> merge_msg_sdl_stun_reply(Prev, New, TrUserData); - sdl_data -> merge_msg_sdl_data(Prev, New, TrUserData); - sdl_register -> merge_msg_sdl_register(Prev, New, TrUserData); - sdl_register_ack -> merge_msg_sdl_register_ack(Prev, New, TrUserData); - sdl_stun_probe -> merge_msg_sdl_stun_probe(Prev, New, TrUserData); - sdl_stun_probe_reply -> merge_msg_sdl_stun_probe_reply(Prev, New, TrUserData) - end. - --compile({nowarn_unused_function,merge_msg_sdl_v4_info/3}). -merge_msg_sdl_v4_info(#sdl_v4_info{port = PFport, v4 = PFv4, nat_type = PFnat_type}, #sdl_v4_info{port = NFport, v4 = NFv4, nat_type = NFnat_type}, _) -> - #sdl_v4_info{port = - if NFport =:= undefined -> PFport; - true -> NFport - end, - v4 = - if NFv4 =:= undefined -> PFv4; - true -> NFv4 - end, - nat_type = - if NFnat_type =:= undefined -> PFnat_type; - true -> NFnat_type - end}. - --compile({nowarn_unused_function,merge_msg_sdl_v6_info/3}). -merge_msg_sdl_v6_info(#sdl_v6_info{port = PFport, v6 = PFv6}, #sdl_v6_info{port = NFport, v6 = NFv6}, _) -> - #sdl_v6_info{port = - if NFport =:= undefined -> PFport; - true -> NFport - end, - v6 = - if NFv6 =:= undefined -> PFv6; - true -> NFv6 - end}. - --compile({nowarn_unused_function,merge_msg_sdl_dev_addr/3}). -merge_msg_sdl_dev_addr(#sdl_dev_addr{network_id = PFnetwork_id, mac = PFmac, net_addr = PFnet_addr, net_bit_len = PFnet_bit_len, network_domain = PFnetwork_domain}, - #sdl_dev_addr{network_id = NFnetwork_id, mac = NFmac, net_addr = NFnet_addr, net_bit_len = NFnet_bit_len, network_domain = NFnetwork_domain}, _) -> - #sdl_dev_addr{network_id = - if NFnetwork_id =:= undefined -> PFnetwork_id; - true -> NFnetwork_id - end, - mac = - if NFmac =:= undefined -> PFmac; - true -> NFmac - end, - net_addr = - if NFnet_addr =:= undefined -> PFnet_addr; - true -> NFnet_addr - end, - net_bit_len = - if NFnet_bit_len =:= undefined -> PFnet_bit_len; - true -> NFnet_bit_len - end, - network_domain = - if NFnetwork_domain =:= undefined -> PFnetwork_domain; - true -> NFnetwork_domain - end}. - --compile({nowarn_unused_function,merge_msg_sdl_empty/3}). -merge_msg_sdl_empty(_Prev, New, _TrUserData) -> New. - --compile({nowarn_unused_function,merge_msg_sdl_register_super/3}). -merge_msg_sdl_register_super(#sdl_register_super{version = PFversion, installed_channel = PFinstalled_channel, client_id = PFclient_id, dev_addr = PFdev_addr, pub_key = PFpub_key, token = PFtoken, network_code = PFnetwork_code, - hostname = PFhostname}, - #sdl_register_super{version = NFversion, installed_channel = NFinstalled_channel, client_id = NFclient_id, dev_addr = NFdev_addr, pub_key = NFpub_key, token = NFtoken, network_code = NFnetwork_code, hostname = NFhostname}, TrUserData) -> - #sdl_register_super{version = - if NFversion =:= undefined -> PFversion; - true -> NFversion - end, - installed_channel = - if NFinstalled_channel =:= undefined -> PFinstalled_channel; - true -> NFinstalled_channel - end, - client_id = - if NFclient_id =:= undefined -> PFclient_id; - true -> NFclient_id - end, - dev_addr = - if PFdev_addr /= undefined, NFdev_addr /= undefined -> merge_msg_sdl_dev_addr(PFdev_addr, NFdev_addr, TrUserData); - PFdev_addr == undefined -> NFdev_addr; - NFdev_addr == undefined -> PFdev_addr - end, - pub_key = - if NFpub_key =:= undefined -> PFpub_key; - true -> NFpub_key - end, - token = - if NFtoken =:= undefined -> PFtoken; - true -> NFtoken - end, - network_code = - if NFnetwork_code =:= undefined -> PFnetwork_code; - true -> NFnetwork_code - end, - hostname = - if NFhostname =:= undefined -> PFhostname; - true -> NFhostname - end}. - --compile({nowarn_unused_function,merge_msg_sdl_register_super_ack/3}). -merge_msg_sdl_register_super_ack(#sdl_register_super_ack{dev_addr = PFdev_addr, aes_key = PFaes_key, upgrade_type = PFupgrade_type, upgrade_prompt = PFupgrade_prompt, upgrade_address = PFupgrade_address}, - #sdl_register_super_ack{dev_addr = NFdev_addr, aes_key = NFaes_key, upgrade_type = NFupgrade_type, upgrade_prompt = NFupgrade_prompt, upgrade_address = NFupgrade_address}, TrUserData) -> - #sdl_register_super_ack{dev_addr = - if PFdev_addr /= undefined, NFdev_addr /= undefined -> merge_msg_sdl_dev_addr(PFdev_addr, NFdev_addr, TrUserData); - PFdev_addr == undefined -> NFdev_addr; - NFdev_addr == undefined -> PFdev_addr - end, - aes_key = - if NFaes_key =:= undefined -> PFaes_key; - true -> NFaes_key - end, - upgrade_type = - if NFupgrade_type =:= undefined -> PFupgrade_type; - true -> NFupgrade_type - end, - upgrade_prompt = - if NFupgrade_prompt =:= undefined -> PFupgrade_prompt; - true -> NFupgrade_prompt - end, - upgrade_address = - if NFupgrade_address =:= undefined -> PFupgrade_address; - true -> NFupgrade_address - end}. - --compile({nowarn_unused_function,merge_msg_sdl_register_super_nak/3}). -merge_msg_sdl_register_super_nak(#sdl_register_super_nak{error_code = PFerror_code, error_message = PFerror_message}, #sdl_register_super_nak{error_code = NFerror_code, error_message = NFerror_message}, _) -> - #sdl_register_super_nak{error_code = - if NFerror_code =:= undefined -> PFerror_code; - true -> NFerror_code - end, - error_message = - if NFerror_message =:= undefined -> PFerror_message; - true -> NFerror_message - end}. - --compile({nowarn_unused_function,merge_msg_sdl_query_info/3}). -merge_msg_sdl_query_info(#sdl_query_info{dst_mac = PFdst_mac}, #sdl_query_info{dst_mac = NFdst_mac}, _) -> - #sdl_query_info{dst_mac = - if NFdst_mac =:= undefined -> PFdst_mac; - true -> NFdst_mac - end}. - --compile({nowarn_unused_function,merge_msg_sdl_peer_info/3}). -merge_msg_sdl_peer_info(#sdl_peer_info{dst_mac = PFdst_mac, v4_info = PFv4_info, v6_info = PFv6_info}, #sdl_peer_info{dst_mac = NFdst_mac, v4_info = NFv4_info, v6_info = NFv6_info}, TrUserData) -> - #sdl_peer_info{dst_mac = - if NFdst_mac =:= undefined -> PFdst_mac; - true -> NFdst_mac - end, - v4_info = - if PFv4_info /= undefined, NFv4_info /= undefined -> merge_msg_sdl_v4_info(PFv4_info, NFv4_info, TrUserData); - PFv4_info == undefined -> NFv4_info; - NFv4_info == undefined -> PFv4_info - end, - v6_info = - if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_sdl_v6_info(PFv6_info, NFv6_info, TrUserData); - PFv6_info == undefined -> NFv6_info; - NFv6_info == undefined -> PFv6_info - end}. - --compile({nowarn_unused_function,merge_msg_sdl_nat_changed_event/3}). -merge_msg_sdl_nat_changed_event(#sdl_nat_changed_event{mac = PFmac, ip = PFip}, #sdl_nat_changed_event{mac = NFmac, ip = NFip}, _) -> - #sdl_nat_changed_event{mac = - if NFmac =:= undefined -> PFmac; - true -> NFmac - end, - ip = - if NFip =:= undefined -> PFip; - true -> NFip - end}. - --compile({nowarn_unused_function,merge_msg_sdl_send_register_event/3}). -merge_msg_sdl_send_register_event(#sdl_send_register_event{dst_mac = PFdst_mac, nat_ip = PFnat_ip, nat_port = PFnat_port, nat_type = PFnat_type, v6_info = PFv6_info}, - #sdl_send_register_event{dst_mac = NFdst_mac, nat_ip = NFnat_ip, nat_port = NFnat_port, nat_type = NFnat_type, v6_info = NFv6_info}, TrUserData) -> - #sdl_send_register_event{dst_mac = - if NFdst_mac =:= undefined -> PFdst_mac; - true -> NFdst_mac - end, - nat_ip = - if NFnat_ip =:= undefined -> PFnat_ip; - true -> NFnat_ip - end, - nat_port = - if NFnat_port =:= undefined -> PFnat_port; - true -> NFnat_port - end, - nat_type = - if NFnat_type =:= undefined -> PFnat_type; - true -> NFnat_type - end, - v6_info = - if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_sdl_v6_info(PFv6_info, NFv6_info, TrUserData); - PFv6_info == undefined -> NFv6_info; - NFv6_info == undefined -> PFv6_info - end}. - --compile({nowarn_unused_function,merge_msg_sdl_network_shutdown_event/3}). -merge_msg_sdl_network_shutdown_event(#sdl_network_shutdown_event{message = PFmessage}, #sdl_network_shutdown_event{message = NFmessage}, _) -> - #sdl_network_shutdown_event{message = - if NFmessage =:= undefined -> PFmessage; - true -> NFmessage - end}. - --compile({nowarn_unused_function,merge_msg_sdl_change_network_command/3}). -merge_msg_sdl_change_network_command(#sdl_change_network_command{dev_addr = PFdev_addr, aes_key = PFaes_key}, #sdl_change_network_command{dev_addr = NFdev_addr, aes_key = NFaes_key}, TrUserData) -> - #sdl_change_network_command{dev_addr = - if PFdev_addr /= undefined, NFdev_addr /= undefined -> merge_msg_sdl_dev_addr(PFdev_addr, NFdev_addr, TrUserData); - PFdev_addr == undefined -> NFdev_addr; - NFdev_addr == undefined -> PFdev_addr - end, - aes_key = - if NFaes_key =:= undefined -> PFaes_key; - true -> NFaes_key - end}. - --compile({nowarn_unused_function,merge_msg_sdl_command_ack/3}). -merge_msg_sdl_command_ack(#sdl_command_ack{status = PFstatus, message = PFmessage}, #sdl_command_ack{status = NFstatus, message = NFmessage}, _) -> - #sdl_command_ack{status = - if NFstatus =:= undefined -> PFstatus; - true -> NFstatus - end, - message = - if NFmessage =:= undefined -> PFmessage; - true -> NFmessage - end}. - --compile({nowarn_unused_function,merge_msg_sdl_flows/3}). -merge_msg_sdl_flows(#sdl_flows{forward_num = PFforward_num, p2p_num = PFp2p_num, inbound_num = PFinbound_num}, #sdl_flows{forward_num = NFforward_num, p2p_num = NFp2p_num, inbound_num = NFinbound_num}, _) -> - #sdl_flows{forward_num = - if NFforward_num =:= undefined -> PFforward_num; - true -> NFforward_num - end, - p2p_num = - if NFp2p_num =:= undefined -> PFp2p_num; - true -> NFp2p_num - end, - inbound_num = - if NFinbound_num =:= undefined -> PFinbound_num; - true -> NFinbound_num - end}. - --compile({nowarn_unused_function,merge_msg_sdl_stun_request/3}). -merge_msg_sdl_stun_request(#sdl_stun_request{cookie = PFcookie, client_id = PFclient_id, network_id = PFnetwork_id, mac = PFmac, ip = PFip, nat_type = PFnat_type, v6_info = PFv6_info}, - #sdl_stun_request{cookie = NFcookie, client_id = NFclient_id, network_id = NFnetwork_id, mac = NFmac, ip = NFip, nat_type = NFnat_type, v6_info = NFv6_info}, TrUserData) -> - #sdl_stun_request{cookie = - if NFcookie =:= undefined -> PFcookie; - true -> NFcookie - end, - client_id = - if NFclient_id =:= undefined -> PFclient_id; - true -> NFclient_id - end, - network_id = - if NFnetwork_id =:= undefined -> PFnetwork_id; - true -> NFnetwork_id - end, - mac = - if NFmac =:= undefined -> PFmac; - true -> NFmac - end, - ip = - if NFip =:= undefined -> PFip; - true -> NFip - end, - nat_type = - if NFnat_type =:= undefined -> PFnat_type; - true -> NFnat_type - end, - v6_info = - if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_sdl_v6_info(PFv6_info, NFv6_info, TrUserData); - PFv6_info == undefined -> NFv6_info; - NFv6_info == undefined -> PFv6_info - end}. - --compile({nowarn_unused_function,merge_msg_sdl_stun_reply/3}). -merge_msg_sdl_stun_reply(#sdl_stun_reply{cookie = PFcookie}, #sdl_stun_reply{cookie = NFcookie}, _) -> - #sdl_stun_reply{cookie = - if NFcookie =:= undefined -> PFcookie; - true -> NFcookie - end}. - --compile({nowarn_unused_function,merge_msg_sdl_data/3}). -merge_msg_sdl_data(#sdl_data{network_id = PFnetwork_id, src_mac = PFsrc_mac, dst_mac = PFdst_mac, is_p2p = PFis_p2p, ttl = PFttl, data = PFdata}, - #sdl_data{network_id = NFnetwork_id, src_mac = NFsrc_mac, dst_mac = NFdst_mac, is_p2p = NFis_p2p, ttl = NFttl, data = NFdata}, _) -> - #sdl_data{network_id = - if NFnetwork_id =:= undefined -> PFnetwork_id; - true -> NFnetwork_id - end, - src_mac = - if NFsrc_mac =:= undefined -> PFsrc_mac; - true -> NFsrc_mac - end, - dst_mac = - if NFdst_mac =:= undefined -> PFdst_mac; - true -> NFdst_mac - end, - is_p2p = - if NFis_p2p =:= undefined -> PFis_p2p; - true -> NFis_p2p - end, - ttl = - if NFttl =:= undefined -> PFttl; - true -> NFttl - end, - data = - if NFdata =:= undefined -> PFdata; - true -> NFdata - end}. - --compile({nowarn_unused_function,merge_msg_sdl_register/3}). -merge_msg_sdl_register(#sdl_register{network_id = PFnetwork_id, src_mac = PFsrc_mac, dst_mac = PFdst_mac}, #sdl_register{network_id = NFnetwork_id, src_mac = NFsrc_mac, dst_mac = NFdst_mac}, _) -> - #sdl_register{network_id = - if NFnetwork_id =:= undefined -> PFnetwork_id; - true -> NFnetwork_id - end, - src_mac = - if NFsrc_mac =:= undefined -> PFsrc_mac; - true -> NFsrc_mac - end, - dst_mac = - if NFdst_mac =:= undefined -> PFdst_mac; - true -> NFdst_mac - end}. - --compile({nowarn_unused_function,merge_msg_sdl_register_ack/3}). -merge_msg_sdl_register_ack(#sdl_register_ack{network_id = PFnetwork_id, src_mac = PFsrc_mac, dst_mac = PFdst_mac}, #sdl_register_ack{network_id = NFnetwork_id, src_mac = NFsrc_mac, dst_mac = NFdst_mac}, _) -> - #sdl_register_ack{network_id = - if NFnetwork_id =:= undefined -> PFnetwork_id; - true -> NFnetwork_id - end, - src_mac = - if NFsrc_mac =:= undefined -> PFsrc_mac; - true -> NFsrc_mac - end, - dst_mac = - if NFdst_mac =:= undefined -> PFdst_mac; - true -> NFdst_mac - end}. - --compile({nowarn_unused_function,merge_msg_sdl_stun_probe/3}). -merge_msg_sdl_stun_probe(#sdl_stun_probe{cookie = PFcookie, attr = PFattr}, #sdl_stun_probe{cookie = NFcookie, attr = NFattr}, _) -> - #sdl_stun_probe{cookie = - if NFcookie =:= undefined -> PFcookie; - true -> NFcookie - end, - attr = - if NFattr =:= undefined -> PFattr; - true -> NFattr - end}. - --compile({nowarn_unused_function,merge_msg_sdl_stun_probe_reply/3}). -merge_msg_sdl_stun_probe_reply(#sdl_stun_probe_reply{cookie = PFcookie, port = PFport, ip = PFip}, #sdl_stun_probe_reply{cookie = NFcookie, port = NFport, ip = NFip}, _) -> - #sdl_stun_probe_reply{cookie = - if NFcookie =:= undefined -> PFcookie; - true -> NFcookie - end, - port = - if NFport =:= undefined -> PFport; - true -> NFport - end, - ip = - if NFip =:= undefined -> PFip; - true -> NFip - end}. - - -verify_msg(Msg) when tuple_size(Msg) >= 1 -> verify_msg(Msg, element(1, Msg), []); -verify_msg(X) -> mk_type_error(not_a_known_message, X, []). - -verify_msg(Msg, MsgName) when is_atom(MsgName) -> verify_msg(Msg, MsgName, []); -verify_msg(Msg, Opts) when tuple_size(Msg) >= 1 -> verify_msg(Msg, element(1, Msg), Opts); -verify_msg(X, _Opts) -> mk_type_error(not_a_known_message, X, []). - -verify_msg(Msg, MsgName, Opts) -> - TrUserData = proplists:get_value(user_data, Opts), - case MsgName of - sdl_v4_info -> v_msg_sdl_v4_info(Msg, [MsgName], TrUserData); - sdl_v6_info -> v_msg_sdl_v6_info(Msg, [MsgName], TrUserData); - sdl_dev_addr -> v_msg_sdl_dev_addr(Msg, [MsgName], TrUserData); - sdl_empty -> v_msg_sdl_empty(Msg, [MsgName], TrUserData); - sdl_register_super -> v_msg_sdl_register_super(Msg, [MsgName], TrUserData); - sdl_register_super_ack -> v_msg_sdl_register_super_ack(Msg, [MsgName], TrUserData); - sdl_register_super_nak -> v_msg_sdl_register_super_nak(Msg, [MsgName], TrUserData); - sdl_query_info -> v_msg_sdl_query_info(Msg, [MsgName], TrUserData); - sdl_peer_info -> v_msg_sdl_peer_info(Msg, [MsgName], TrUserData); - sdl_nat_changed_event -> v_msg_sdl_nat_changed_event(Msg, [MsgName], TrUserData); - sdl_send_register_event -> v_msg_sdl_send_register_event(Msg, [MsgName], TrUserData); - sdl_network_shutdown_event -> v_msg_sdl_network_shutdown_event(Msg, [MsgName], TrUserData); - sdl_change_network_command -> v_msg_sdl_change_network_command(Msg, [MsgName], TrUserData); - sdl_command_ack -> v_msg_sdl_command_ack(Msg, [MsgName], TrUserData); - sdl_flows -> v_msg_sdl_flows(Msg, [MsgName], TrUserData); - sdl_stun_request -> v_msg_sdl_stun_request(Msg, [MsgName], TrUserData); - sdl_stun_reply -> v_msg_sdl_stun_reply(Msg, [MsgName], TrUserData); - sdl_data -> v_msg_sdl_data(Msg, [MsgName], TrUserData); - sdl_register -> v_msg_sdl_register(Msg, [MsgName], TrUserData); - sdl_register_ack -> v_msg_sdl_register_ack(Msg, [MsgName], TrUserData); - sdl_stun_probe -> v_msg_sdl_stun_probe(Msg, [MsgName], TrUserData); - sdl_stun_probe_reply -> v_msg_sdl_stun_probe_reply(Msg, [MsgName], TrUserData); - _ -> mk_type_error(not_a_known_message, Msg, []) - end. - - --compile({nowarn_unused_function,v_submsg_sdl_v4_info/3}). --dialyzer({nowarn_function,v_submsg_sdl_v4_info/3}). -v_submsg_sdl_v4_info(Msg, Path, TrUserData) -> v_msg_sdl_v4_info(Msg, Path, TrUserData). - --compile({nowarn_unused_function,v_msg_sdl_v4_info/3}). --dialyzer({nowarn_function,v_msg_sdl_v4_info/3}). -v_msg_sdl_v4_info(#sdl_v4_info{port = F1, v4 = F2, nat_type = F3}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [port | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [v4 | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [nat_type | Path], TrUserData) - end, - ok; -v_msg_sdl_v4_info(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_v4_info}, X, Path). - --compile({nowarn_unused_function,v_submsg_sdl_v6_info/3}). --dialyzer({nowarn_function,v_submsg_sdl_v6_info/3}). -v_submsg_sdl_v6_info(Msg, Path, TrUserData) -> v_msg_sdl_v6_info(Msg, Path, TrUserData). - --compile({nowarn_unused_function,v_msg_sdl_v6_info/3}). --dialyzer({nowarn_function,v_msg_sdl_v6_info/3}). -v_msg_sdl_v6_info(#sdl_v6_info{port = F1, v6 = F2}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [port | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [v6 | Path], TrUserData) - end, - ok; -v_msg_sdl_v6_info(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_v6_info}, X, Path). - --compile({nowarn_unused_function,v_submsg_sdl_dev_addr/3}). --dialyzer({nowarn_function,v_submsg_sdl_dev_addr/3}). -v_submsg_sdl_dev_addr(Msg, Path, TrUserData) -> v_msg_sdl_dev_addr(Msg, Path, TrUserData). - --compile({nowarn_unused_function,v_msg_sdl_dev_addr/3}). --dialyzer({nowarn_function,v_msg_sdl_dev_addr/3}). -v_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_bit_len = F4, network_domain = F5}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [network_id | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [mac | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [net_addr | Path], TrUserData) - end, - if F4 == undefined -> ok; - true -> v_type_uint32(F4, [net_bit_len | Path], TrUserData) - end, - if F5 == undefined -> ok; - true -> v_type_string(F5, [network_domain | Path], TrUserData) - end, - ok; -v_msg_sdl_dev_addr(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_dev_addr}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_empty/3}). --dialyzer({nowarn_function,v_msg_sdl_empty/3}). -v_msg_sdl_empty(#sdl_empty{}, _Path, _) -> ok; -v_msg_sdl_empty(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_empty}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_register_super/3}). --dialyzer({nowarn_function,v_msg_sdl_register_super/3}). -v_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F2, client_id = F3, dev_addr = F4, pub_key = F5, token = F6, network_code = F7, hostname = F8}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [version | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_string(F2, [installed_channel | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_string(F3, [client_id | Path], TrUserData) - end, - if F4 == undefined -> ok; - true -> v_submsg_sdl_dev_addr(F4, [dev_addr | Path], TrUserData) - end, - if F5 == undefined -> ok; - true -> v_type_string(F5, [pub_key | Path], TrUserData) - end, - if F6 == undefined -> ok; - true -> v_type_string(F6, [token | Path], TrUserData) - end, - if F7 == undefined -> ok; - true -> v_type_string(F7, [network_code | Path], TrUserData) - end, - if F8 == undefined -> ok; - true -> v_type_string(F8, [hostname | Path], TrUserData) - end, - ok; -v_msg_sdl_register_super(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_register_super}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_register_super_ack/3}). --dialyzer({nowarn_function,v_msg_sdl_register_super_ack/3}). -v_msg_sdl_register_super_ack(#sdl_register_super_ack{dev_addr = F1, aes_key = F2, upgrade_type = F3, upgrade_prompt = F4, upgrade_address = F5}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_submsg_sdl_dev_addr(F1, [dev_addr | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [aes_key | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [upgrade_type | Path], TrUserData) - end, - if F4 == undefined -> ok; - true -> v_type_string(F4, [upgrade_prompt | Path], TrUserData) - end, - if F5 == undefined -> ok; - true -> v_type_string(F5, [upgrade_address | Path], TrUserData) - end, - ok; -v_msg_sdl_register_super_ack(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_register_super_ack}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_register_super_nak/3}). --dialyzer({nowarn_function,v_msg_sdl_register_super_nak/3}). -v_msg_sdl_register_super_nak(#sdl_register_super_nak{error_code = F1, error_message = F2}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [error_code | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_string(F2, [error_message | Path], TrUserData) - end, - ok; -v_msg_sdl_register_super_nak(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_register_super_nak}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_query_info/3}). --dialyzer({nowarn_function,v_msg_sdl_query_info/3}). -v_msg_sdl_query_info(#sdl_query_info{dst_mac = F1}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_bytes(F1, [dst_mac | Path], TrUserData) - end, - ok; -v_msg_sdl_query_info(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_query_info}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_peer_info/3}). --dialyzer({nowarn_function,v_msg_sdl_peer_info/3}). -v_msg_sdl_peer_info(#sdl_peer_info{dst_mac = F1, v4_info = F2, v6_info = F3}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_bytes(F1, [dst_mac | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_submsg_sdl_v4_info(F2, [v4_info | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_submsg_sdl_v6_info(F3, [v6_info | Path], TrUserData) - end, - ok; -v_msg_sdl_peer_info(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_peer_info}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_nat_changed_event/3}). --dialyzer({nowarn_function,v_msg_sdl_nat_changed_event/3}). -v_msg_sdl_nat_changed_event(#sdl_nat_changed_event{mac = F1, ip = F2}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_bytes(F1, [mac | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_uint32(F2, [ip | Path], TrUserData) - end, - ok; -v_msg_sdl_nat_changed_event(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_nat_changed_event}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_send_register_event/3}). --dialyzer({nowarn_function,v_msg_sdl_send_register_event/3}). -v_msg_sdl_send_register_event(#sdl_send_register_event{dst_mac = F1, nat_ip = F2, nat_port = F3, nat_type = F4, v6_info = F5}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_bytes(F1, [dst_mac | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_uint32(F2, [nat_ip | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [nat_port | Path], TrUserData) - end, - if F4 == undefined -> ok; - true -> v_type_uint32(F4, [nat_type | Path], TrUserData) - end, - if F5 == undefined -> ok; - true -> v_submsg_sdl_v6_info(F5, [v6_info | Path], TrUserData) - end, - ok; -v_msg_sdl_send_register_event(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_send_register_event}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_network_shutdown_event/3}). --dialyzer({nowarn_function,v_msg_sdl_network_shutdown_event/3}). -v_msg_sdl_network_shutdown_event(#sdl_network_shutdown_event{message = F1}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_string(F1, [message | Path], TrUserData) - end, - ok; -v_msg_sdl_network_shutdown_event(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_network_shutdown_event}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_change_network_command/3}). --dialyzer({nowarn_function,v_msg_sdl_change_network_command/3}). -v_msg_sdl_change_network_command(#sdl_change_network_command{dev_addr = F1, aes_key = F2}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_submsg_sdl_dev_addr(F1, [dev_addr | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [aes_key | Path], TrUserData) - end, - ok; -v_msg_sdl_change_network_command(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_change_network_command}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_command_ack/3}). --dialyzer({nowarn_function,v_msg_sdl_command_ack/3}). -v_msg_sdl_command_ack(#sdl_command_ack{status = F1, message = F2}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_bool(F1, [status | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_string(F2, [message | Path], TrUserData) - end, - ok; -v_msg_sdl_command_ack(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_command_ack}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_flows/3}). --dialyzer({nowarn_function,v_msg_sdl_flows/3}). -v_msg_sdl_flows(#sdl_flows{forward_num = F1, p2p_num = F2, inbound_num = F3}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [forward_num | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_uint32(F2, [p2p_num | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [inbound_num | Path], TrUserData) - end, - ok; -v_msg_sdl_flows(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_flows}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_stun_request/3}). --dialyzer({nowarn_function,v_msg_sdl_stun_request/3}). -v_msg_sdl_stun_request(#sdl_stun_request{cookie = F1, client_id = F2, network_id = F3, mac = F4, ip = F5, nat_type = F6, v6_info = F7}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [cookie | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_string(F2, [client_id | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [network_id | Path], TrUserData) - end, - if F4 == undefined -> ok; - true -> v_type_bytes(F4, [mac | Path], TrUserData) - end, - if F5 == undefined -> ok; - true -> v_type_uint32(F5, [ip | Path], TrUserData) - end, - if F6 == undefined -> ok; - true -> v_type_uint32(F6, [nat_type | Path], TrUserData) - end, - if F7 == undefined -> ok; - true -> v_submsg_sdl_v6_info(F7, [v6_info | Path], TrUserData) - end, - ok; -v_msg_sdl_stun_request(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_stun_request}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_stun_reply/3}). --dialyzer({nowarn_function,v_msg_sdl_stun_reply/3}). -v_msg_sdl_stun_reply(#sdl_stun_reply{cookie = F1}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [cookie | Path], TrUserData) - end, - ok; -v_msg_sdl_stun_reply(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_stun_reply}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_data/3}). --dialyzer({nowarn_function,v_msg_sdl_data/3}). -v_msg_sdl_data(#sdl_data{network_id = F1, src_mac = F2, dst_mac = F3, is_p2p = F4, ttl = F5, data = F6}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [network_id | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [src_mac | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_bytes(F3, [dst_mac | Path], TrUserData) - end, - if F4 == undefined -> ok; - true -> v_type_bool(F4, [is_p2p | Path], TrUserData) - end, - if F5 == undefined -> ok; - true -> v_type_uint32(F5, [ttl | Path], TrUserData) - end, - if F6 == undefined -> ok; - true -> v_type_bytes(F6, [data | Path], TrUserData) - end, - ok; -v_msg_sdl_data(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_data}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_register/3}). --dialyzer({nowarn_function,v_msg_sdl_register/3}). -v_msg_sdl_register(#sdl_register{network_id = F1, src_mac = F2, dst_mac = F3}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [network_id | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [src_mac | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_bytes(F3, [dst_mac | Path], TrUserData) - end, - ok; -v_msg_sdl_register(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_register}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_register_ack/3}). --dialyzer({nowarn_function,v_msg_sdl_register_ack/3}). -v_msg_sdl_register_ack(#sdl_register_ack{network_id = F1, src_mac = F2, dst_mac = F3}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [network_id | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_bytes(F2, [src_mac | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_bytes(F3, [dst_mac | Path], TrUserData) - end, - ok; -v_msg_sdl_register_ack(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_register_ack}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_stun_probe/3}). --dialyzer({nowarn_function,v_msg_sdl_stun_probe/3}). -v_msg_sdl_stun_probe(#sdl_stun_probe{cookie = F1, attr = F2}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [cookie | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_uint32(F2, [attr | Path], TrUserData) - end, - ok; -v_msg_sdl_stun_probe(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_stun_probe}, X, Path). - --compile({nowarn_unused_function,v_msg_sdl_stun_probe_reply/3}). --dialyzer({nowarn_function,v_msg_sdl_stun_probe_reply/3}). -v_msg_sdl_stun_probe_reply(#sdl_stun_probe_reply{cookie = F1, port = F2, ip = F3}, Path, TrUserData) -> - if F1 == undefined -> ok; - true -> v_type_uint32(F1, [cookie | Path], TrUserData) - end, - if F2 == undefined -> ok; - true -> v_type_uint32(F2, [port | Path], TrUserData) - end, - if F3 == undefined -> ok; - true -> v_type_uint32(F3, [ip | Path], TrUserData) - end, - ok; -v_msg_sdl_stun_probe_reply(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_stun_probe_reply}, X, Path). - --compile({nowarn_unused_function,v_type_uint32/3}). --dialyzer({nowarn_function,v_type_uint32/3}). -v_type_uint32(N, _Path, _TrUserData) when is_integer(N), 0 =< N, N =< 4294967295 -> ok; -v_type_uint32(N, Path, _TrUserData) when is_integer(N) -> mk_type_error({value_out_of_range, uint32, unsigned, 32}, N, Path); -v_type_uint32(X, Path, _TrUserData) -> mk_type_error({bad_integer, uint32, unsigned, 32}, X, Path). - --compile({nowarn_unused_function,v_type_bool/3}). --dialyzer({nowarn_function,v_type_bool/3}). -v_type_bool(false, _Path, _TrUserData) -> ok; -v_type_bool(true, _Path, _TrUserData) -> ok; -v_type_bool(0, _Path, _TrUserData) -> ok; -v_type_bool(1, _Path, _TrUserData) -> ok; -v_type_bool(X, Path, _TrUserData) -> mk_type_error(bad_boolean_value, X, Path). - --compile({nowarn_unused_function,v_type_string/3}). --dialyzer({nowarn_function,v_type_string/3}). -v_type_string(S, Path, _TrUserData) when is_list(S); is_binary(S) -> - try unicode:characters_to_binary(S) of - B when is_binary(B) -> ok; - {error, _, _} -> mk_type_error(bad_unicode_string, S, Path) - catch - error:badarg -> mk_type_error(bad_unicode_string, S, Path) - end; -v_type_string(X, Path, _TrUserData) -> mk_type_error(bad_unicode_string, X, Path). - --compile({nowarn_unused_function,v_type_bytes/3}). --dialyzer({nowarn_function,v_type_bytes/3}). -v_type_bytes(B, _Path, _TrUserData) when is_binary(B) -> ok; -v_type_bytes(B, _Path, _TrUserData) when is_list(B) -> ok; -v_type_bytes(X, Path, _TrUserData) -> mk_type_error(bad_binary_value, X, Path). - --compile({nowarn_unused_function,mk_type_error/3}). --spec mk_type_error(_, _, list()) -> no_return(). -mk_type_error(Error, ValueSeen, Path) -> - Path2 = prettify_path(Path), - erlang:error({gpb_type_error, {Error, [{value, ValueSeen}, {path, Path2}]}}). - - --compile({nowarn_unused_function,prettify_path/1}). --dialyzer({nowarn_function,prettify_path/1}). -prettify_path([]) -> top_level; -prettify_path(PathR) -> lists:append(lists:join(".", lists:map(fun atom_to_list/1, lists:reverse(PathR)))). - - --compile({nowarn_unused_function,id/2}). --compile({inline,id/2}). -id(X, _TrUserData) -> X. - --compile({nowarn_unused_function,v_ok/3}). --compile({inline,v_ok/3}). -v_ok(_Value, _Path, _TrUserData) -> ok. - --compile({nowarn_unused_function,m_overwrite/3}). --compile({inline,m_overwrite/3}). -m_overwrite(_Prev, New, _TrUserData) -> New. - --compile({nowarn_unused_function,cons/3}). --compile({inline,cons/3}). -cons(Elem, Acc, _TrUserData) -> [Elem | Acc]. - --compile({nowarn_unused_function,lists_reverse/2}). --compile({inline,lists_reverse/2}). -'lists_reverse'(L, _TrUserData) -> lists:reverse(L). --compile({nowarn_unused_function,'erlang_++'/3}). --compile({inline,'erlang_++'/3}). -'erlang_++'(A, B, _TrUserData) -> A ++ B. - - -get_msg_defs() -> - [{{msg, sdl_v4_info}, - [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = v4, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = nat_type, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]}, - {{msg, sdl_v6_info}, [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = v6, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}]}, - {{msg, sdl_dev_addr}, - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = net_addr, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = net_bit_len, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, - #field{name = network_domain, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}]}, - {{msg, sdl_empty}, []}, - {{msg, sdl_register_super}, - [#field{name = version, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = installed_channel, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}, - #field{name = client_id, fnum = 3, rnum = 4, type = string, occurrence = defaulty, opts = []}, - #field{name = dev_addr, fnum = 4, rnum = 5, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, - #field{name = pub_key, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}, - #field{name = token, fnum = 6, rnum = 7, type = string, occurrence = defaulty, opts = []}, - #field{name = network_code, fnum = 7, rnum = 8, type = string, occurrence = defaulty, opts = []}, - #field{name = hostname, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]}, - {{msg, sdl_register_super_ack}, - [#field{name = dev_addr, fnum = 1, rnum = 2, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, - #field{name = aes_key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = upgrade_type, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = upgrade_prompt, fnum = 4, rnum = 5, type = string, occurrence = optional, opts = []}, - #field{name = upgrade_address, fnum = 5, rnum = 6, type = string, occurrence = optional, opts = []}]}, - {{msg, sdl_register_super_nak}, [#field{name = error_code, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = error_message, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}]}, - {{msg, sdl_query_info}, [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}]}, - {{msg, sdl_peer_info}, - [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, - #field{name = v4_info, fnum = 2, rnum = 3, type = {msg, sdl_v4_info}, occurrence = defaulty, opts = []}, - #field{name = v6_info, fnum = 3, rnum = 4, type = {msg, sdl_v6_info}, occurrence = optional, opts = []}]}, - {{msg, sdl_nat_changed_event}, [#field{name = mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, #field{name = ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}]}, - {{msg, sdl_send_register_event}, - [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, - #field{name = nat_ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, - #field{name = nat_port, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = nat_type, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, - #field{name = v6_info, fnum = 5, rnum = 6, type = {msg, sdl_v6_info}, occurrence = optional, opts = []}]}, - {{msg, sdl_network_shutdown_event}, [#field{name = message, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}]}, - {{msg, sdl_change_network_command}, [#field{name = dev_addr, fnum = 1, rnum = 2, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, #field{name = aes_key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}]}, - {{msg, sdl_command_ack}, [#field{name = status, fnum = 1, rnum = 2, type = bool, occurrence = defaulty, opts = []}, #field{name = message, fnum = 2, rnum = 3, type = string, occurrence = optional, opts = []}]}, - {{msg, sdl_flows}, - [#field{name = forward_num, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = p2p_num, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, - #field{name = inbound_num, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]}, - {{msg, sdl_stun_request}, - [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = client_id, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}, - #field{name = network_id, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = mac, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}, - #field{name = ip, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, - #field{name = nat_type, fnum = 6, rnum = 7, type = uint32, occurrence = defaulty, opts = []}, - #field{name = v6_info, fnum = 7, rnum = 8, type = {msg, sdl_v6_info}, occurrence = optional, opts = []}]}, - {{msg, sdl_stun_reply}, [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}]}, - {{msg, sdl_data}, - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, - #field{name = is_p2p, fnum = 4, rnum = 5, type = bool, occurrence = defaulty, opts = []}, - #field{name = ttl, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, - #field{name = data, fnum = 6, rnum = 7, type = bytes, occurrence = defaulty, opts = []}]}, - {{msg, sdl_register}, - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]}, - {{msg, sdl_register_ack}, - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]}, - {{msg, sdl_stun_probe}, [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = attr, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}]}, - {{msg, sdl_stun_probe_reply}, - [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = port, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, - #field{name = ip, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]}]. - - -get_msg_names() -> - [sdl_v4_info, - sdl_v6_info, - sdl_dev_addr, - sdl_empty, - sdl_register_super, - sdl_register_super_ack, - sdl_register_super_nak, - sdl_query_info, - sdl_peer_info, - sdl_nat_changed_event, - sdl_send_register_event, - sdl_network_shutdown_event, - sdl_change_network_command, - sdl_command_ack, - sdl_flows, - sdl_stun_request, - sdl_stun_reply, - sdl_data, - sdl_register, - sdl_register_ack, - sdl_stun_probe, - sdl_stun_probe_reply]. - - -get_group_names() -> []. - - -get_msg_or_group_names() -> - [sdl_v4_info, - sdl_v6_info, - sdl_dev_addr, - sdl_empty, - sdl_register_super, - sdl_register_super_ack, - sdl_register_super_nak, - sdl_query_info, - sdl_peer_info, - sdl_nat_changed_event, - sdl_send_register_event, - sdl_network_shutdown_event, - sdl_change_network_command, - sdl_command_ack, - sdl_flows, - sdl_stun_request, - sdl_stun_reply, - sdl_data, - sdl_register, - sdl_register_ack, - sdl_stun_probe, - sdl_stun_probe_reply]. - - -get_enum_names() -> []. - - -fetch_msg_def(MsgName) -> - case find_msg_def(MsgName) of - Fs when is_list(Fs) -> Fs; - error -> erlang:error({no_such_msg, MsgName}) - end. - - --spec fetch_enum_def(_) -> no_return(). -fetch_enum_def(EnumName) -> erlang:error({no_such_enum, EnumName}). - - -find_msg_def(sdl_v4_info) -> - [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = v4, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = nat_type, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_v6_info) -> [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = v6, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_dev_addr) -> - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = net_addr, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = net_bit_len, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, - #field{name = network_domain, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_empty) -> []; -find_msg_def(sdl_register_super) -> - [#field{name = version, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = installed_channel, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}, - #field{name = client_id, fnum = 3, rnum = 4, type = string, occurrence = defaulty, opts = []}, - #field{name = dev_addr, fnum = 4, rnum = 5, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, - #field{name = pub_key, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}, - #field{name = token, fnum = 6, rnum = 7, type = string, occurrence = defaulty, opts = []}, - #field{name = network_code, fnum = 7, rnum = 8, type = string, occurrence = defaulty, opts = []}, - #field{name = hostname, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_register_super_ack) -> - [#field{name = dev_addr, fnum = 1, rnum = 2, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, - #field{name = aes_key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = upgrade_type, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = upgrade_prompt, fnum = 4, rnum = 5, type = string, occurrence = optional, opts = []}, - #field{name = upgrade_address, fnum = 5, rnum = 6, type = string, occurrence = optional, opts = []}]; -find_msg_def(sdl_register_super_nak) -> [#field{name = error_code, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = error_message, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_query_info) -> [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_peer_info) -> - [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, - #field{name = v4_info, fnum = 2, rnum = 3, type = {msg, sdl_v4_info}, occurrence = defaulty, opts = []}, - #field{name = v6_info, fnum = 3, rnum = 4, type = {msg, sdl_v6_info}, occurrence = optional, opts = []}]; -find_msg_def(sdl_nat_changed_event) -> [#field{name = mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, #field{name = ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_send_register_event) -> - [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, - #field{name = nat_ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, - #field{name = nat_port, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = nat_type, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, - #field{name = v6_info, fnum = 5, rnum = 6, type = {msg, sdl_v6_info}, occurrence = optional, opts = []}]; -find_msg_def(sdl_network_shutdown_event) -> [#field{name = message, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_change_network_command) -> [#field{name = dev_addr, fnum = 1, rnum = 2, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, #field{name = aes_key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_command_ack) -> [#field{name = status, fnum = 1, rnum = 2, type = bool, occurrence = defaulty, opts = []}, #field{name = message, fnum = 2, rnum = 3, type = string, occurrence = optional, opts = []}]; -find_msg_def(sdl_flows) -> - [#field{name = forward_num, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = p2p_num, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, - #field{name = inbound_num, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_stun_request) -> - [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = client_id, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}, - #field{name = network_id, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, - #field{name = mac, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}, - #field{name = ip, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, - #field{name = nat_type, fnum = 6, rnum = 7, type = uint32, occurrence = defaulty, opts = []}, - #field{name = v6_info, fnum = 7, rnum = 8, type = {msg, sdl_v6_info}, occurrence = optional, opts = []}]; -find_msg_def(sdl_stun_reply) -> [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_data) -> - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, - #field{name = is_p2p, fnum = 4, rnum = 5, type = bool, occurrence = defaulty, opts = []}, - #field{name = ttl, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, - #field{name = data, fnum = 6, rnum = 7, type = bytes, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_register) -> - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_register_ack) -> - [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, - #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_stun_probe) -> [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = attr, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}]; -find_msg_def(sdl_stun_probe_reply) -> - [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, - #field{name = port, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, - #field{name = ip, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]; -find_msg_def(_) -> error. - - -find_enum_def(_) -> error. - - --spec enum_symbol_by_value(_, _) -> no_return(). -enum_symbol_by_value(E, V) -> erlang:error({no_enum_defs, E, V}). - - --spec enum_value_by_symbol(_, _) -> no_return(). -enum_value_by_symbol(E, V) -> erlang:error({no_enum_defs, E, V}). - - - -get_service_names() -> []. - - -get_service_def(_) -> error. - - -get_rpc_names(_) -> error. - - -find_rpc_def(_, _) -> error. - - - --spec fetch_rpc_def(_, _) -> no_return(). -fetch_rpc_def(ServiceName, RpcName) -> erlang:error({no_such_rpc, ServiceName, RpcName}). - - -%% Convert a a fully qualified (ie with package name) service name -%% as a binary to a service name as an atom. --spec fqbin_to_service_name(_) -> no_return(). -fqbin_to_service_name(X) -> error({gpb_error, {badservice, X}}). - - -%% Convert a service name as an atom to a fully qualified -%% (ie with package name) name as a binary. --spec service_name_to_fqbin(_) -> no_return(). -service_name_to_fqbin(X) -> error({gpb_error, {badservice, X}}). - - -%% Convert a a fully qualified (ie with package name) service name -%% and an rpc name, both as binaries to a service name and an rpc -%% name, as atoms. --spec fqbins_to_service_and_rpc_name(_, _) -> no_return(). -fqbins_to_service_and_rpc_name(S, R) -> error({gpb_error, {badservice_or_rpc, {S, R}}}). - - -%% Convert a service name and an rpc name, both as atoms, -%% to a fully qualified (ie with package name) service name and -%% an rpc name as binaries. --spec service_and_rpc_name_to_fqbins(_, _) -> no_return(). -service_and_rpc_name_to_fqbins(S, R) -> error({gpb_error, {badservice_or_rpc, {S, R}}}). - - -fqbin_to_msg_name(<<"SDLV4Info">>) -> sdl_v4_info; -fqbin_to_msg_name(<<"SDLV6Info">>) -> sdl_v6_info; -fqbin_to_msg_name(<<"SDLDevAddr">>) -> sdl_dev_addr; -fqbin_to_msg_name(<<"SDLEmpty">>) -> sdl_empty; -fqbin_to_msg_name(<<"SDLRegisterSuper">>) -> sdl_register_super; -fqbin_to_msg_name(<<"SDLRegisterSuperAck">>) -> sdl_register_super_ack; -fqbin_to_msg_name(<<"SDLRegisterSuperNak">>) -> sdl_register_super_nak; -fqbin_to_msg_name(<<"SDLQueryInfo">>) -> sdl_query_info; -fqbin_to_msg_name(<<"SDLPeerInfo">>) -> sdl_peer_info; -fqbin_to_msg_name(<<"SDLNatChangedEvent">>) -> sdl_nat_changed_event; -fqbin_to_msg_name(<<"SDLSendRegisterEvent">>) -> sdl_send_register_event; -fqbin_to_msg_name(<<"SDLNetworkShutdownEvent">>) -> sdl_network_shutdown_event; -fqbin_to_msg_name(<<"SDLChangeNetworkCommand">>) -> sdl_change_network_command; -fqbin_to_msg_name(<<"SDLCommandAck">>) -> sdl_command_ack; -fqbin_to_msg_name(<<"SDLFlows">>) -> sdl_flows; -fqbin_to_msg_name(<<"SDLStunRequest">>) -> sdl_stun_request; -fqbin_to_msg_name(<<"SDLStunReply">>) -> sdl_stun_reply; -fqbin_to_msg_name(<<"SDLData">>) -> sdl_data; -fqbin_to_msg_name(<<"SDLRegister">>) -> sdl_register; -fqbin_to_msg_name(<<"SDLRegisterAck">>) -> sdl_register_ack; -fqbin_to_msg_name(<<"SDLStunProbe">>) -> sdl_stun_probe; -fqbin_to_msg_name(<<"SDLStunProbeReply">>) -> sdl_stun_probe_reply; -fqbin_to_msg_name(E) -> error({gpb_error, {badmsg, E}}). - - -msg_name_to_fqbin(sdl_v4_info) -> <<"SDLV4Info">>; -msg_name_to_fqbin(sdl_v6_info) -> <<"SDLV6Info">>; -msg_name_to_fqbin(sdl_dev_addr) -> <<"SDLDevAddr">>; -msg_name_to_fqbin(sdl_empty) -> <<"SDLEmpty">>; -msg_name_to_fqbin(sdl_register_super) -> <<"SDLRegisterSuper">>; -msg_name_to_fqbin(sdl_register_super_ack) -> <<"SDLRegisterSuperAck">>; -msg_name_to_fqbin(sdl_register_super_nak) -> <<"SDLRegisterSuperNak">>; -msg_name_to_fqbin(sdl_query_info) -> <<"SDLQueryInfo">>; -msg_name_to_fqbin(sdl_peer_info) -> <<"SDLPeerInfo">>; -msg_name_to_fqbin(sdl_nat_changed_event) -> <<"SDLNatChangedEvent">>; -msg_name_to_fqbin(sdl_send_register_event) -> <<"SDLSendRegisterEvent">>; -msg_name_to_fqbin(sdl_network_shutdown_event) -> <<"SDLNetworkShutdownEvent">>; -msg_name_to_fqbin(sdl_change_network_command) -> <<"SDLChangeNetworkCommand">>; -msg_name_to_fqbin(sdl_command_ack) -> <<"SDLCommandAck">>; -msg_name_to_fqbin(sdl_flows) -> <<"SDLFlows">>; -msg_name_to_fqbin(sdl_stun_request) -> <<"SDLStunRequest">>; -msg_name_to_fqbin(sdl_stun_reply) -> <<"SDLStunReply">>; -msg_name_to_fqbin(sdl_data) -> <<"SDLData">>; -msg_name_to_fqbin(sdl_register) -> <<"SDLRegister">>; -msg_name_to_fqbin(sdl_register_ack) -> <<"SDLRegisterAck">>; -msg_name_to_fqbin(sdl_stun_probe) -> <<"SDLStunProbe">>; -msg_name_to_fqbin(sdl_stun_probe_reply) -> <<"SDLStunProbeReply">>; -msg_name_to_fqbin(E) -> error({gpb_error, {badmsg, E}}). - - --spec fqbin_to_enum_name(_) -> no_return(). -fqbin_to_enum_name(E) -> error({gpb_error, {badenum, E}}). - - --spec enum_name_to_fqbin(_) -> no_return(). -enum_name_to_fqbin(E) -> error({gpb_error, {badenum, E}}). - - -get_package_name() -> undefined. - - -%% Whether or not the message names -%% are prepended with package name or not. -uses_packages() -> false. - - -source_basename() -> "sdlan_pb.proto". - - -%% Retrieve all proto file names, also imported ones. -%% The order is top-down. The first element is always the main -%% source file. The files are returned with extension, -%% see get_all_proto_names/0 for a version that returns -%% the basenames sans extension -get_all_source_basenames() -> ["sdlan_pb.proto"]. - - -%% Retrieve all proto file names, also imported ones. -%% The order is top-down. The first element is always the main -%% source file. The files are returned sans .proto extension, -%% to make it easier to use them with the various get_xyz_containment -%% functions. -get_all_proto_names() -> ["sdlan_pb"]. - - -get_msg_containment("sdlan_pb") -> - [sdl_change_network_command, - sdl_command_ack, - sdl_data, - sdl_dev_addr, - sdl_empty, - sdl_flows, - sdl_nat_changed_event, - sdl_network_shutdown_event, - sdl_peer_info, - sdl_query_info, - sdl_register, - sdl_register_ack, - sdl_register_super, - sdl_register_super_ack, - sdl_register_super_nak, - sdl_send_register_event, - sdl_stun_probe, - sdl_stun_probe_reply, - sdl_stun_reply, - sdl_stun_request, - sdl_v4_info, - sdl_v6_info]; -get_msg_containment(P) -> error({gpb_error, {badproto, P}}). - - -get_pkg_containment("sdlan_pb") -> undefined; -get_pkg_containment(P) -> error({gpb_error, {badproto, P}}). - - -get_service_containment("sdlan_pb") -> []; -get_service_containment(P) -> error({gpb_error, {badproto, P}}). - - -get_rpc_containment("sdlan_pb") -> []; -get_rpc_containment(P) -> error({gpb_error, {badproto, P}}). - - -get_enum_containment("sdlan_pb") -> []; -get_enum_containment(P) -> error({gpb_error, {badproto, P}}). - - -get_proto_by_msg_name_as_fqbin(<<"SDLData">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLRegisterSuper">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLRegister">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLDevAddr">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLFlows">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLStunRequest">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLSendRegisterEvent">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLNetworkShutdownEvent">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLNatChangedEvent">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLChangeNetworkCommand">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLStunProbe">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLStunReply">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLStunProbeReply">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLEmpty">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLRegisterSuperNak">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLRegisterSuperAck">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLRegisterAck">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLCommandAck">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLV6Info">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLV4Info">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLQueryInfo">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(<<"SDLPeerInfo">>) -> "sdlan_pb"; -get_proto_by_msg_name_as_fqbin(E) -> error({gpb_error, {badmsg, E}}). - - --spec get_proto_by_service_name_as_fqbin(_) -> no_return(). -get_proto_by_service_name_as_fqbin(E) -> error({gpb_error, {badservice, E}}). - - --spec get_proto_by_enum_name_as_fqbin(_) -> no_return(). -get_proto_by_enum_name_as_fqbin(E) -> error({gpb_error, {badenum, E}}). - - --spec get_protos_by_pkg_name_as_fqbin(_) -> no_return(). -get_protos_by_pkg_name_as_fqbin(E) -> error({gpb_error, {badpkg, E}}). - - - -gpb_version_as_string() -> - "4.21.1". - -gpb_version_as_list() -> - [4,21,1]. - -gpb_version_source() -> - "git". diff --git a/apps/sdlan/src/sdlan_test.erl b/apps/sdlan/src/sdlan_test.erl deleted file mode 100644 index 1bd30d5..0000000 --- a/apps/sdlan/src/sdlan_test.erl +++ /dev/null @@ -1,18 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 09. 3月 2024 15:25 -%%%------------------------------------------------------------------- --module(sdlan_test). --author("anlicheng"). - -%% API --export([test/1]). - -test(X) when X band 1 == 0 -> - ok; -test(_) -> - error. diff --git a/apps/sdlan/src/sdlan_util.erl b/apps/sdlan/src/sdlan_util.erl deleted file mode 100644 index 874c3d9..0000000 --- a/apps/sdlan/src/sdlan_util.erl +++ /dev/null @@ -1,74 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 11. 3月 2024 11:10 -%%%------------------------------------------------------------------- --module(sdlan_util). --author("anlicheng"). - -%% API --export([rand_byte/1, md5/1, format_mac/1, assert_call/2]). --export([json_data/1, json_error/2]). --export([is_broadcast_mac/1, is_multicast_mac/1]). - --spec format_mac(Mac :: binary()) -> binary(). -format_mac(Mac) when is_binary(Mac) -> - Hex = fun - (N) when N < 10 -> - $0 + N; - (N) -> - $a + (N - 10) - end, - Y = [[Hex(X0), Hex(X1)] || <> <= Mac], - list_to_binary(lists:flatten(lists:join(":", Y))). - -%% 生成随机字节 -rand_byte(Num) when is_integer(Num), Num > 0 -> - rand_byte0(Num, <<>>). -rand_byte0(0, Acc) -> - Acc; -rand_byte0(Num, Acc) -> - Byte = ceil(rand:uniform() * 255), - rand_byte0(Num - 1, <>). - -%% md5哈希算法 --spec md5(string() | binary()) -> string(). -md5(Str) when is_binary(Str) -> - md5(binary_to_list(Str)); -md5(Str) when is_list(Str) -> - Hash = binary_to_list(erlang:md5(Str)), - lists:flatten([hex(I) || I <- Hash]). - -hex(I) when I > 16#f -> - [hex0((I band 16#f0) bsr 4), hex0(I band 16#0f)]; -hex(I) -> - [$0, hex0(I)]. -hex0(10) -> $a; -hex0(11) -> $b; -hex0(12) -> $c; -hex0(13) -> $d; -hex0(14) -> $e; -hex0(15) -> $f; -hex0(I) -> $0 + I. - -json_data(Data) -> - jiffy:encode(#{<<"result">> => Data}, [force_utf8]). - -json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) -> - jiffy:encode(#{<<"error">> => #{<<"code">> => ErrCode, <<"message">> => ErrMessage}}, [force_utf8]). - -assert_call(true, F) -> - F(); -assert_call(false, _) -> - ok. - --spec is_broadcast_mac(Mac :: binary()) -> boolean(). -is_broadcast_mac(Mac) when is_binary(Mac) -> - Mac =:= <<16#FF,16#FF,16#FF,16#FF,16#FF,16#FF>>. - --spec is_multicast_mac(Mac :: binary()) -> boolean(). -is_multicast_mac(Mac) when is_binary(Mac) -> - binary:part(Mac, 0, 3) =:= <<16#01,16#00,16#5E>>. \ No newline at end of file diff --git a/apps/sdlan/src/test/sdlan_quicer_test.erl b/apps/sdlan/src/test/sdlan_quicer_test.erl deleted file mode 100644 index 89c7928..0000000 --- a/apps/sdlan/src/test/sdlan_quicer_test.erl +++ /dev/null @@ -1,20 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2026, -%%% @doc -%%% -%%% @end -%%% Created : 11. 2月 2026 15:49 -%%%------------------------------------------------------------------- --module(sdlan_quicer_test). --author("anlicheng"). - -%% API --export([test/0]). - -test() -> - {ok, Conn} = quicer:connect("http3.is", 443, [{alpn, ["h3"]}, - {verify, verify_peer}, - {peer_unidi_stream_count, 3}], 5000), - logger:debug("conn is: ~p", [Conn]), - quicer:shutdown_connection(Conn). \ No newline at end of file diff --git a/apps/sdlan/src/test/sdlan_udp_downloader.erl b/apps/sdlan/src/test/sdlan_udp_downloader.erl deleted file mode 100644 index 9177b5b..0000000 --- a/apps/sdlan/src/test/sdlan_udp_downloader.erl +++ /dev/null @@ -1,110 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 17. 4月 2024 10:35 -%%%------------------------------------------------------------------- --module(sdlan_udp_downloader). --author("anlicheng"). - --behaviour(gen_server). - -%% API --export([start_link/0]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, - code_change/3]). - --define(SERVER, ?MODULE). - --record(state, { - socket -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - {ok, Socket} = gen_udp:open(22222, [binary]), - {ok, #state{socket = Socket}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call(_Request, _From, State) -> - {reply, ok, State}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast(_Info, State) -> - {noreply, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({udp, Sock, Ip, Port, <<1>>}, State = #state{socket = Sock}) -> - {ok, Content} = file:read_file("/tmp/files/test.dmg"), - send_file_content(Sock, Ip, Port, 1200, Content), - {noreply, State#state{}}. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== - -send_file_content(Sock, Ip, Port, Size, Content) when byte_size(Content) =< Size -> - gen_udp:send(Sock, Ip, Port, Content); -send_file_content(Sock, Ip, Port, Size, Content) -> - <> = Content, - gen_udp:send(Sock, Ip, Port, Part), - send_file_content(Sock, Ip, Port, Size, Rest). diff --git a/apps/sdlan/src/test/sdlan_udp_wget.erl b/apps/sdlan/src/test/sdlan_udp_wget.erl deleted file mode 100644 index b910336..0000000 --- a/apps/sdlan/src/test/sdlan_udp_wget.erl +++ /dev/null @@ -1,114 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 17. 4月 2024 10:35 -%%%------------------------------------------------------------------- --module(sdlan_udp_wget). --author("anlicheng"). - --behaviour(gen_server). - -%% API --export([start_link/0]). --export([wget/0]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --define(SERVER, ?MODULE). - --record(state, { - socket, - bytes = 0 -}). - -%%%=================================================================== -%%% API -%%%=================================================================== -wget() -> - gen_server:call(?MODULE, wget). - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - {ok, Socket} = gen_udp:open(0, [binary, {active, true}]), - inet_udp:controlling_process(Socket, self()), - - erlang:start_timer(5000, self(), qps_ticker), - - {ok, #state{socket = Socket}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call(wget, _From, State=#state{socket = Socket}) -> - gen_udp:send(Socket, "127.0.0.1", 22222, <<1>>), - {reply, ok, State}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast(_Info, State) -> - {noreply, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({udp, Sock, _Ip, _Port, Data}, State = #state{socket = Sock, bytes = Bytes}) -> - {noreply, State#state{bytes = Bytes + byte_size(Data)}}; -handle_info({timeout, _, qps_ticker}, State = #state{bytes = Bytes}) -> - logger:debug("[sdlan_udp_wget] qps is: ~p(M)", [Bytes / 1024 / 1024]), - erlang:start_timer(5000, self(), qps_ticker), - {noreply, State#state{bytes = 0}}. - - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/apps/sdlan/src/test/stun_client.erl b/apps/sdlan/src/test/stun_client.erl deleted file mode 100644 index 7601ea7..0000000 --- a/apps/sdlan/src/test/stun_client.erl +++ /dev/null @@ -1,208 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 08. 4月 2024 10:37 -%%%------------------------------------------------------------------- --module(stun_client). --author("anlicheng"). --include("sdlan_pb.hrl"). - --behaviour(gen_server). - -%% API --export([start_link/0]). --export([register/1, debug_info/1]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, - code_change/3]). - --define(SERVER, ?MODULE). -%% 请求 --define(STUN_REGISTER, 3). -%% 响应 --define(STUN_REGISTER_ACK, 4). - --define(STUN_DATA, 5). - --record(state, { - socket, - tun_socket, - client_id :: binary(), - network_id, - net_addr, - mask_len, - aes_key, - cookie = 1, - - sessions = #{} -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -register(Pid) when is_pid(Pid) -> - gen_server:call(Pid, register). - -debug_info(Pid) -> - gen_server:call(Pid, debug_info). - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link(?MODULE, [], []). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%% @private -%% @doc Initializes the server --spec(init(Args :: term()) -> - {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | - {stop, Reason :: term()} | ignore). -init([]) -> - {ok, Socket} = gen_tcp:connect("localhost", 18083, [binary, {packet, 2}, {active, true}]), - inet_tcp:controlling_process(Socket, self()), - {ok, TunSocket} = gen_udp:open(12345, [binary, {active, true}]), - - {ok, #state{socket = Socket, tun_socket = TunSocket, client_id = <<"22222222222222222222222222222222">>}}. - -%% @private -%% @doc Handling call messages --spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, - State :: #state{}) -> - {reply, Reply :: term(), NewState :: #state{}} | - {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_call(debug_info, _From, State) -> - {reply, {ok, State}, State}; - -handle_call(register, _From, State = #state{socket = Socket, client_id = ClientId}) -> - Req = #{ - <<"version">> => 1, - <<"client_id">> => ClientId, - <<"dev_addr">> => #{ - <<"net_addr">> => 0, - <<"net_bit_len">> => 0 - }, - <<"token">> => <<"1234567890">> - }, - - Register = #sdl_register_super { - version = 1, - installed_channel = <<"macos">>, - client_id = ClientId, - dev_addr = #sdl_dev_addr { - network_id = 0, - mac = <<11, 12, 13, 14, 15, 16>>, - net_addr = 0, - net_bit_len = 0 - }, - pub_key = <<>>, - token = <<"1234567890">> - }, - - logger:debug("register is: ~p", [Register]), - - Packet = jiffy:encode(Req, [force_utf8]), - ok = gen_tcp:send(Socket, <<1:32, 101, Packet/binary>>), - - {reply, ok, State}. - -%% @private -%% @doc Handling cast messages --spec(handle_cast(Request :: term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_cast(_Request, State = #state{}) -> - {noreply, State}. - -%% @private -%% @doc Handling all non call/cast messages --spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> - {noreply, NewState :: #state{}} | - {noreply, NewState :: #state{}, timeout() | hibernate} | - {stop, Reason :: term(), NewState :: #state{}}). -handle_info({tcp, Socket, <<1:32, 5, Data/binary>>}, State = #state{socket = Socket, tun_socket = TunSocket, client_id = ClientId, cookie = Cookie}) -> - Response = jiffy:decode(Data, [return_maps]), - #{ - <<"dev_addr">> := #{ - <<"network_id">> := NetworkId, - <<"net_addr">> := NetAddr, - <<"net_bit_len">> := NetBitLen - }, - <<"aes_key">> := AesKey, - <<"lifetime">> := Lifetime - } = Response, - - logger:debug("[stun_client] get a register super response: ~p, alloc ip addr: ~p", [Response, sdlan_ipaddr:int_to_ipv4(NetAddr)]), - - %% 开始注册自己的tun信息 - gen_udp:send(TunSocket, "localhost", 1265, <<1, Cookie:32, ClientId/binary, NetworkId:32, NetAddr:32>>), - - {noreply, State#state{network_id = NetworkId, net_addr = NetAddr, mask_len = NetBitLen, aes_key = AesKey, cookie = Cookie + 1}}; - -handle_info({udp, _, _, _, <<2, Cookie:32, Family, Port:16, Ip0, Ip1, Ip2, Ip3>>}, State = #state{}) -> - logger:debug("[stun_client] tun register ack, cookie: ~p, ack: ~p", [Cookie, {Family, Port, {Ip0, Ip1, Ip2, Ip3}}]), - {noreply, State}; - -handle_info({udp, _, Ip, Port, <>}, State = #state{tun_socket = TunSocket, sessions = Sessions}) -> - Packet = <>, - logger:debug("[stun_client] will send stun reply: ~p, peer: ~p", [Packet, {Ip, Port}]), - ok = gen_udp:send(TunSocket, Ip, Port, Packet), - - NSessions = maps:put(SrcIp, {Ip, Port}, Sessions), - {noreply, State#state{sessions = NSessions}}; - -handle_info({udp, _, Ip, Port, <>}, State = #state{sessions = Sessions}) -> - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, register_ack!!!", [NetworkId, SrcIp, DstIp]), - NSessions = maps:put(SrcIp, {Ip, Port}, Sessions), - {noreply, State#state{sessions = NSessions}}; - -handle_info({udp, _, _Ip0, _Port0, <>}, State = #state{tun_socket = TunSocket, sessions = Sessions}) -> - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, data!!!", [NetworkId, SrcIp, DstIp]), - case maps:is_key(SrcIp, Sessions) of - true -> - {Ip, Port} = maps:get(SrcIp, Sessions), - ok = gen_udp:send(TunSocket, Ip, Port, <>), - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, reply data!!!", [NetworkId, SrcIp, DstIp]); - false -> - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, no session", [NetworkId, SrcIp, DstIp]) - end, - {noreply, State}; - -handle_info(Info, State = #state{}) -> - logger:debug("[stun_client] get info: ~p", [Info]), - {noreply, State}. - -%% @private -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. --spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), - State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> - ok. - -%% @private -%% @doc Convert process state when code is changed --spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, - Extra :: term()) -> - {ok, NewState :: #state{}} | {error, Reason :: term()}). -code_change(_OldVsn, State = #state{}, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/config/sys-dev.config b/config/sys-dev.config index 9c78729..ead4a42 100644 --- a/config/sys-dev.config +++ b/config/sys-dev.config @@ -3,16 +3,39 @@ {http_server, [ {port, 18082}, - {acceptors, 500}, + {acceptors, 1}, {max_connections, 10240}, {backlog, 10240} ]}, - {tcp_server, [ - {port, 18083}, + %% 证书配置 + {certificate, [ + {certfile, "/usr/local/code/erl/sdlan/priv/ssl/server.crt"}, + {keyfile, "/usr/local/code/erl/sdlan/priv/ssl/server.key"} + ]}, + + {quic_server, [ + {port, 443}, + {acceptors, 10}, + {alpn, ["punchnet/1.0"]}, + {limits, [ + {max_packet_size, 16384}, + {stream_active_n, 100}, + %% 单位为秒 + {heartbeat_sec, 15} + ]} + ]}, + + {ssl_server, [ + {port, 1443}, {acceptors, 500}, {max_connections, 10240}, - {backlog, 10240} + {backlog, 10240}, + {limits, [ + {max_packet_size, 16384}, + %% 单位为秒 + {heartbeat_sec, 15} + ]} ]}, %% 网络带宽, 单位为: kb @@ -20,23 +43,23 @@ %% stun类型探测相当于有个类型 {stun_servers, [ - {port, 1265}, + {port, 1365}, {acceptor_nums, 5} ]}, {stun_port_assist, [ - {port, 1266} + {port, 1366} ]}, {stun_peer_assist, [ {ip, {47,98,178,3}}, - {port, 1266} + {port, 1366} ]}, - %% 公共的dns域名解析服务 - {public_dns_servers, [ - {{114, 114, 114, 114}, 53}, - {{8,8,8,8}, 53} + {ipv6_assist, [ + {port, 1367}, + {acceptor_nums, 5}, + {global_addr6, "2408:4005:318:4900:164a:b5c6:9023:ca8d"} ]}, {pools, [ @@ -44,20 +67,15 @@ {mysql_sdlan, [{size, 10}, {max_overflow, 20}, {worker_module, mysql}], [ - {host, {39, 98, 184, 67}}, + {host, {118, 178, 229, 213}}, {port, 3306}, - {user, "sdlanuser"}, + {user, "punchnetuser"}, {connect_mode, lazy}, {keep_alive, true}, - {password, "sdlan@J1c8WGu"}, - {database, "sdlan"}, + {password, "punchnet@J1c8WGu"}, + {database, "punchnet_v2"}, {queries, [<<"set names utf8">>]} ] - }, - - {dns_resolver_pool, - [{size, 20}, {max_overflow, 100}, {worker_module, dns_resolver}], - [] } ]}, diff --git a/config/sys-prod.config b/config/sys-prod.config index 79182d0..4ec4657 100644 --- a/config/sys-prod.config +++ b/config/sys-prod.config @@ -3,16 +3,39 @@ {http_server, [ {port, 18082}, - {acceptors, 500}, + {acceptors, 50}, {max_connections, 10240}, {backlog, 10240} ]}, - {tcp_server, [ - {port, 18083}, + %% 证书配置 + {certificate, [ + {certfile, "fullchain.cer"}, + {keyfile, "root.punchsky.com.key"} + ]}, + + {quic_server, [ + {port, 443}, + {acceptors, 10}, + {alpn, ["punchnet/1.0"]}, + {limits, [ + {max_packet_size, 16384}, + {stream_active_n, 100}, + %% 单位为秒 + {heartbeat_sec, 15} + ]} + ]}, + + {ssl_server, [ + {port, 1443}, {acceptors, 500}, {max_connections, 10240}, - {backlog, 10240} + {backlog, 10240}, + {limits, [ + {max_packet_size, 16384}, + %% 单位为秒 + {heartbeat_sec, 15} + ]} ]}, %% 网络带宽, 单位为: kb @@ -20,23 +43,23 @@ %% stun类型探测相当于有个类型 {stun_servers, [ - {port, 1265}, - {acceptor_nums, 1} + {port, 1365}, + {acceptor_nums, 5} ]}, {stun_port_assist, [ - {port, 1266} + {port, 1366} ]}, {stun_peer_assist, [ {ip, {47,98,178,3}}, - {port, 1266} + {port, 1366} ]}, - %% 公共的dns域名解析服务 - {public_dns_servers, [ - {{114, 114, 114, 114}, 53}, - {{8,8,8,8}, 53} + {ipv6_assist, [ + {port, 1367}, + {acceptor_nums, 5}, + {global_addr6, "2408:4005:318:4900:164a:b5c6:9023:ca8d"} ]}, {pools, [ @@ -46,23 +69,16 @@ [ {host, {118, 178, 229, 213}}, {port, 3306}, - {user, "sdlanuser"}, - {connect_mode, lazy}, + {user, "punchnetuser"}, {keep_alive, true}, - {password, "sdlan@J1c8WGu"}, - {database, "sdlan"}, + {password, "punchnet@J1c8WGu"}, + {database, "punchnet_v2"}, {queries, [<<"set names utf8">>]} ] - }, - - {dns_resolver_pool, - [{size, 20}, {max_overflow, 100}, {worker_module, dns_resolver}], - [] } - ]}, - {api_url, "https://punchnet.aioe.tech/api/"} + {api_url, "https://root.punchsky.com/api/"} ]}, diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..a51319c --- /dev/null +++ b/docs/api.md @@ -0,0 +1,386 @@ +# HTTP API 接口文档 + +本文档根据 `src/http` 下各 handler 的 `handle_request/4` 实现整理。 + +## 通用说明 + +- HTTP 服务端口由应用配置 `sdlan.http_server.port` 决定。 +- 响应 `Content-Type` 为 `application/json;charset=utf-8`。 +- 当响应体大小大于等于 1024 字节且请求头 `Accept-Encoding` 包含 `gzip` 时,响应会启用 gzip 压缩。 +- GET 参数来自 URL query string。 +- POST 请求体支持两种格式: + - `Content-Type: application/json`:请求体会按 JSON object 解析,数字保持为 JSON number。 + - `Content-Type: application/x-www-form-urlencoded`:请求体会按表单解析,参数值为 binary/string;涉及整型参数的接口建议使用 JSON 请求体。 +- 统一成功返回格式: + +```json +{ + "result": "" +} +``` + +- 统一失败返回格式: + +```json +{ + "error": { + "code": -1, + "message": "错误描述" + } +} +``` + +- handler 未匹配到 URL、Method 或参数结构时,通常返回 HTTP 200,并返回如下错误格式: + +```json +{ + "error": { + "code": -1, + "message": "url: /path not found" + } +} +``` + +## binlog_handler + +路由配置:`/binlog` + +### POST /binlog + +接收 binlog 通知,目前只记录请求参数并返回固定结果。 + +**Method**:`POST` + +**参数**:无必填参数。请求体可为 JSON object 或 form。 + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| 任意字段 | body | object/string/number/boolean/array | 否 | 当前实现不读取具体字段,仅打印完整请求体参数。 | + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | string | 固定为 `"ok"`。 | + +示例: + +```json +{ + "result": "ok" +} +``` + +## test_handler + +路由配置:`/test/[...]` + +### POST /test/auth_access_token + +测试用 access token 校验接口,目前返回固定结果。 + +**Method**:`POST` + +**参数**:无必填参数。请求体可为 JSON object 或 form。 + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| 任意字段 | body | object/string/number/boolean/array | 否 | 当前实现不读取具体字段。 | + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | string | 固定为 `"ok"`。 | + +示例: + +```json +{ + "result": "ok" +} +``` + +### GET /test/get_all_networks + +测试用获取全部网络 ID。 + +**Method**:`GET` + +**参数**:无。 + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | array<integer> | 网络 ID 列表。当前实现固定返回 `[8]`。 | + +示例: + +```json +{ + "result": [8] +} +``` + +### GET /test/get_network + +测试用获取单个网络详情。 + +**Method**:`GET` + +**参数**: + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| id | query | string(integer) | 是 | 网络 ID。实现中会通过 `binary_to_integer/1` 转为 integer;当前仅内置 ID `8`。 | + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | object | 网络详情对象。 | +| result.id | integer | 网络 ID。 | +| result.name | string | 网络名称。 | +| result.domain | string | 网络域名。 | +| result.ipaddr | string | 网络地址段,CIDR 格式。 | +| result.owner_id | integer | 所属用户 ID。 | +| result.algorithm | string | 加密算法。 | +| result.disabled_clients | array<string> | 禁用的客户端 ID 列表。 | + +示例: + +```json +{ + "result": { + "id": 8, + "name": "test1", + "domain": "punchnet.cn", + "ipaddr": "10.211.179.0/24", + "owner_id": 1234, + "algorithm": "chacha20", + "disabled_clients": [] + } +} +``` + +## api_handler + +路由配置:`/api/[...]` + +注意:当前 `api_handler` 的实现匹配路径为 `/test/auth_token`,但 Cowboy 路由只会把 `/api/[...]` 请求分发给 `api_handler`。因此按当前路由配置,该接口不可达;直接请求 `/test/auth_token` 会被分发到 `test_handler`,也不会命中此实现。 + +### POST /test/auth_token + +获取测试 auth token 信息,返回第一个网络 ID。 + +**Method**:`POST` + +**当前可达性**:不可达,原因见本节说明。 + +**参数**:无必填参数。请求体可为 JSON object 或 form。 + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| 任意字段 | body | object/string/number/boolean/array | 否 | 当前实现不读取具体字段,仅打印完整请求体参数。 | + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | object | 返回数据对象。 | +| result.network_id | integer | `network_bo:get_all_networks/0` 返回列表中的第一个网络 ID。 | + +示例: + +```json +{ + "result": { + "network_id": 8 + } +} +``` + +## network_handler + +路由配置:`/network/[...]` + +### POST /network/create + +启动或确保指定网络已启动。 + +**Method**:`POST` + +**参数**: + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | + +请求示例: + +```json +{ + "id": 8 +} +``` + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | string | 固定为 `"success"`。 | + +示例: + +```json +{ + "result": "success" +} +``` + +**失败返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| error.code | integer | 固定为 `-1`。 | +| error.message | string | 固定为 `"error"`。 | + +### POST /network/delete + +删除指定网络;如果网络未启动,也视为删除成功。 + +**Method**:`POST` + +**参数**: + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | + +请求示例: + +```json +{ + "id": 8 +} +``` + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | string | 固定为 `"success"`。 | + +示例: + +```json +{ + "result": "success" +} +``` + +**失败返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| error.code | integer | 固定为 `-1`。 | +| error.message | string | 固定为 `"error"`。 | + +### POST /network/exit_node_control + +向指定客户端下发出口节点控制命令,并等待客户端 ACK。 + +**Method**:`POST` + +**参数**: + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | +| action | body | integer | 是 | 出口节点动作,传入 `SDLCommand.ExitNodeControl.action`。历史文档约定:`0` 表示关闭,`1` 表示开启。 | +| client_id | body | string | 是 | 目标客户端 ID。 | +| remark | body | string | 是 | 下发备注,用于跟踪命令;可传空字符串。 | +| timeout | body | integer | 是 | 等待 ACK 的超时时间,单位秒。实现中会转换为毫秒。 | + +请求示例: + +```json +{ + "id": 8, + "action": 1, + "client_id": "client-id", + "remark": "trace remark", + "timeout": 10 +} +``` + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | string | 正常 ACK 时固定为 `"success"`。 | + +示例: + +```json +{ + "result": "success" +} +``` + +**其他返回**: + +| 场景 | 返回格式 | 字段类型 | 说明 | +| --- | --- | --- | --- | +| 网络不存在 | `{"result":"network not found"}` | result: string | 当前实现将网络不存在作为 result 返回,而不是 error。 | +| 命令发送失败 | `{"error":{"code":-1,"message":"..."}}` | code: integer, message: string | message 为底层返回的 Reason,需为可 JSON 编码值。 | +| 客户端 ACK 失败 | `{"error":{"code":,"message":""}}` | code: integer, message: string | Code 和 Message 来自 `SDLCommandAck`。 | +| 等待 ACK 超时 | `{"error":{"code":-1,"message":"任务执行超时"}}` | code: integer, message: string | 超过 `timeout` 秒未收到 ACK。 | + +## node_handler + +路由配置:`/node/[...]` + +### POST /node/disable + +禁用指定网络中的客户端节点。 + +**Method**:`POST` + +**参数**: + +| 参数 | 位置 | 类型 | 必填 | 说明 | +| --- | --- | --- | --- | --- | +| network_id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | +| client_id | body | string | 是 | 客户端 ID。 | + +请求示例: + +```json +{ + "network_id": 8, + "client_id": "client-id" +} +``` + +**成功返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| result | string | 固定为 `"success"`。 | + +示例: + +```json +{ + "result": "success" +} +``` + +**失败返回**: + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| error.code | integer | 固定为 `-1`。 | +| error.message | string | 当前实现中网络不存在时为 `"network not found"`。 | diff --git a/docs/mac.md b/docs/mac.md new file mode 100644 index 0000000..39917ae --- /dev/null +++ b/docs/mac.md @@ -0,0 +1,2 @@ +## 查看当前系统的dns + scutil --dns \ No newline at end of file diff --git a/apps/sdlan/include/dns_proxy.hrl b/include/dns_proxy.hrl similarity index 100% rename from apps/sdlan/include/dns_proxy.hrl rename to include/dns_proxy.hrl diff --git a/include/policy.hrl b/include/policy.hrl new file mode 100644 index 0000000..926ca8a --- /dev/null +++ b/include/policy.hrl @@ -0,0 +1,40 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 28. 2月 2026 15:25 +%%%------------------------------------------------------------------- +-author("anlicheng"). + +-record(identity, { + identity_id :: integer(), + network_id :: integer(), + subject_type, + created_at :: integer(), + expired_at :: integer() +}). + +-record(identity_policy, { + identity_id :: integer(), + policy_id :: integer() +}). + +-record(policy, { + policy_id :: integer(), + network_id :: integer(), + name :: binary(), + created_at = 0 :: integer() +}). + +-record(rule, { + rule_id :: integer(), + network_id :: integer(), + src_policy_id :: integer(), + dst_policy_id :: integer(), + proto :: integer(), + port :: integer(), + action = allow :: allow | deny, + created_at = 0 :: integer() +}). \ No newline at end of file diff --git a/apps/sdlan/include/sdlan.hrl b/include/sdlan.hrl similarity index 73% rename from apps/sdlan/include/sdlan.hrl rename to include/sdlan.hrl index 0f2e6c5..c5d6790 100644 --- a/apps/sdlan/include/sdlan.hrl +++ b/include/sdlan.hrl @@ -13,10 +13,12 @@ -define(DEFAULT_PASS, <<"`encrypt!`">>). +%% 一级分类,包类型分类,占一个字节 + -define(PACKET_EMPTY, 16#00). +%% 注册相关 -define(PACKET_REGISTER_SUPER, 16#01). -define(PACKET_REGISTER_SUPER_ACK, 16#02). --define(PACKET_REGISTER_SUPER_ACKNOWLEDGE, 16#03). -define(PACKET_REGISTER_SUPER_NAK, 16#04). -define(PACKET_UNREGISTER, 16#05). @@ -31,23 +33,10 @@ %% 推送的事件信息, 不需要返回值 -define(PACKET_EVENT, 16#10). -%% 定义事件信息 --define(PACKET_EVENT_KNOWN_IP, 16#01). --define(PACKET_EVENT_DROP_IP, 16#02). --define(PACKET_EVENT_NAT_CHANGED, 16#03). --define(PACKET_EVENT_SEND_REGISTER, 16#04). - -%% 网络关闭 --define(PACKET_EVENT_NETWORK_SHUTDOWN, 16#FF). - %% 推送命令信息, 需要等待返回值 -define(PACKET_COMMAND, 16#11). -define(PACKET_COMMAND_ACK, 16#12). -%% 网络发生变化 --define(PACKET_COMMAND_CHANGE_NETWORK, 16#01). --define(PACKET_COMMAND_UPGRADE, 16#02). - %% 网络流量统计 -define(PACKET_FLOW_TRACER, 16#15). @@ -55,7 +44,6 @@ -define(PACKET_REGISTER_ACK, 16#21). %% stun相关的请求 - %% 请求 -define(PACKET_STUN_REQUEST, 16#30). %% 响应 @@ -69,15 +57,21 @@ %% stun消息转发 -define(PACKET_STUN_PROBE_RELAY, 16#3a). -%% stun请求的attr --define(STUN_ATTR_CHANGE_NONE, 0). --define(STUN_ATTR_CHANGE_PORT, 1). --define(STUN_ATTR_CHANGE_PEER, 2). +%% 权限控制 +-define(PACKET_POLICY_REQUEST, 16#b0). +-define(PACKET_POLICY_REPLY, 16#b1). + +%% 欢迎消息 +-define(PACKET_WELCOME, 16#4F). + +%% ARP查询 +-define(PACKET_ARP_REQUEST, 16#50). +-define(PACKET_ARP_RESPONSE, 16#51). %% 数据转发 -define(PACKET_STUN_DATA, 16#FF). --record(id_generator, { - tab :: atom(), - increment_id = 0 :: integer() -}). \ No newline at end of file +%% stun请求的attr +-define(STUN_ATTR_CHANGE_NONE, 0). +-define(STUN_ATTR_CHANGE_PORT, 1). +-define(STUN_ATTR_CHANGE_PEER, 2). \ No newline at end of file diff --git a/include/sdlan_pb.hrl b/include/sdlan_pb.hrl new file mode 100644 index 0000000..bc897f5 --- /dev/null +++ b/include/sdlan_pb.hrl @@ -0,0 +1,270 @@ +%% -*- coding: utf-8 -*- +%% Automatically generated, do not edit +%% Generated by gpb_compile version 4.21.7 + +-ifndef(sdlan_pb). +-define(sdlan_pb, true). + +-define(sdlan_pb_gpb_version, "4.21.7"). + + +-ifndef('SDLV4INFO_PB_H'). +-define('SDLV4INFO_PB_H', true). +-record('SDLV4Info', + {port = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + v4 = <<>> :: iodata() | undefined, % = 2, optional + nat_type = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits + }). +-endif. + +-ifndef('SDLV6INFO_PB_H'). +-define('SDLV6INFO_PB_H', true). +-record('SDLV6Info', + {port = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + v6 = <<>> :: iodata() | undefined % = 2, optional + }). +-endif. + +-ifndef('SDLV6ASSISTPROBE_PB_H'). +-define('SDLV6ASSISTPROBE_PB_H', true). +-record('SDLV6AssistProbe', + {pkt_id = 0 :: non_neg_integer() | undefined % = 1, optional, 32 bits + }). +-endif. + +-ifndef('SDLV6ASSISTPROBEREPLY_PB_H'). +-define('SDLV6ASSISTPROBEREPLY_PB_H', true). +-record('SDLV6AssistProbeReply', + {pkt_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + v6_info = undefined :: sdlan_pb:'SDLV6Info'() | undefined % = 2, optional + }). +-endif. + +-ifndef('SDLWELCOME_PB_H'). +-define('SDLWELCOME_PB_H', true). +-record('SDLWelcome', + {version = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + max_bidi_streams = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + max_packet_size = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits + heartbeat_sec = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits + ipv6_assist = undefined :: sdlan_pb:'SDLV6Info'() | undefined % = 5, optional + }). +-endif. + +-ifndef('SDLREGISTERSUPER_PB_H'). +-define('SDLREGISTERSUPER_PB_H', true). +-record('SDLRegisterSuper', + {client_id = <<>> :: unicode:chardata() | undefined, % = 1, optional + network_id = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + mac = <<>> :: iodata() | undefined, % = 3, optional + ip = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits + mask_len = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits + hostname = <<>> :: unicode:chardata() | undefined, % = 6, optional + pub_key = <<>> :: unicode:chardata() | undefined, % = 7, optional + access_token = <<>> :: unicode:chardata() | undefined % = 8, optional + }). +-endif. + +-ifndef('SDLREGISTERSUPERACK_PB_H'). +-define('SDLREGISTERSUPERACK_PB_H', true). +-record('SDLRegisterSuperAck', + {algorithm = <<>> :: unicode:chardata() | undefined, % = 1, optional + key = <<>> :: iodata() | undefined, % = 2, optional + region_id = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits + session_token = <<>> :: iodata() | undefined % = 4, optional + }). +-endif. + +-ifndef('SDLREGISTERSUPERNAK_PB_H'). +-define('SDLREGISTERSUPERNAK_PB_H', true). +-record('SDLRegisterSuperNak', + {error_code = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + error_message = <<>> :: unicode:chardata() | undefined % = 2, optional + }). +-endif. + +-ifndef('SDLQUERYINFO_PB_H'). +-define('SDLQUERYINFO_PB_H', true). +-record('SDLQueryInfo', + {dst_mac = <<>> :: iodata() | undefined % = 1, optional + }). +-endif. + +-ifndef('SDLPEERINFO_PB_H'). +-define('SDLPEERINFO_PB_H', true). +-record('SDLPeerInfo', + {dst_mac = <<>> :: iodata() | undefined, % = 1, optional + v4_info :: sdlan_pb:'SDLV4Info'() | undefined, % = 2, optional + v6_info :: sdlan_pb:'SDLV6Info'() | undefined % = 3, optional + }). +-endif. + +-ifndef('SDLARPREQUEST_PB_H'). +-define('SDLARPREQUEST_PB_H', true). +-record('SDLArpRequest', + {target_ip = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + origin_ip = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + context = <<>> :: iodata() | undefined % = 3, optional + }). +-endif. + +-ifndef('SDLARPRESPONSE_PB_H'). +-define('SDLARPRESPONSE_PB_H', true). +-record('SDLArpResponse', + {target_ip = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + target_mac = <<>> :: iodata() | undefined, % = 2, optional + origin_ip = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits + context = <<>> :: iodata() | undefined % = 4, optional + }). +-endif. + +-ifndef('SDLPOLICYREQUEST_PB_H'). +-define('SDLPOLICYREQUEST_PB_H', true). +-record('SDLPolicyRequest', + {src_identity_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + dst_identity_id = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + version = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits + }). +-endif. + +-ifndef('SDLPOLICYRESPONSE_PB_H'). +-define('SDLPOLICYRESPONSE_PB_H', true). +-record('SDLPolicyResponse', + {src_identity_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + dst_identity_id = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + version = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits + rules = <<>> :: iodata() | undefined % = 4, optional + }). +-endif. + +-ifndef('SDLEVENT.NATCHANGED_PB_H'). +-define('SDLEVENT.NATCHANGED_PB_H', true). +-record('SDLEvent.NatChanged', + {mac = <<>> :: iodata() | undefined, % = 1, optional + ip = 0 :: non_neg_integer() | undefined % = 2, optional, 32 bits + }). +-endif. + +-ifndef('SDLEVENT.SENDREGISTER_PB_H'). +-define('SDLEVENT.SENDREGISTER_PB_H', true). +-record('SDLEvent.SendRegister', + {dst_mac = <<>> :: iodata() | undefined, % = 1, optional + nat_ip = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + nat_port = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits + nat_type = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits + v6_info :: sdlan_pb:'SDLV6Info'() | undefined % = 5, optional + }). +-endif. + +-ifndef('SDLEVENT.NETWORKSHUTDOWN_PB_H'). +-define('SDLEVENT.NETWORKSHUTDOWN_PB_H', true). +-record('SDLEvent.NetworkShutdown', + {message = <<>> :: unicode:chardata() | undefined % = 1, optional + }). +-endif. + +-ifndef('SDLEVENT_PB_H'). +-define('SDLEVENT_PB_H', true). +-record('SDLEvent', + {event :: {nat_changed, sdlan_pb:'SDLEvent.NatChanged'()} | {send_register, sdlan_pb:'SDLEvent.SendRegister'()} | {shutdown, sdlan_pb:'SDLEvent.NetworkShutdown'()} | undefined % oneof + }). +-endif. + +-ifndef('SDLCOMMAND.EXITNODECONTROL_PB_H'). +-define('SDLCOMMAND.EXITNODECONTROL_PB_H', true). +-record('SDLCommand.ExitNodeControl', + {action = 0 :: integer() | undefined, % = 1, optional, 32 bits + remark = <<>> :: unicode:chardata() | undefined % = 2, optional + }). +-endif. + +-ifndef('SDLCOMMAND_PB_H'). +-define('SDLCOMMAND_PB_H', true). +-record('SDLCommand', + {pkt_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + command :: {exit_node, sdlan_pb:'SDLCommand.ExitNodeControl'()} | undefined % oneof + }). +-endif. + +-ifndef('SDLCOMMANDACK_PB_H'). +-define('SDLCOMMANDACK_PB_H', true). +-record('SDLCommandAck', + {pkt_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + code = 0 :: integer() | undefined, % = 2, optional, 32 bits + message = <<>> :: unicode:chardata() | undefined, % = 3, optional + data = <<>> :: iodata() | undefined % = 4, optional + }). +-endif. + +-ifndef('SDLSTUNREQUEST_PB_H'). +-define('SDLSTUNREQUEST_PB_H', true). +-record('SDLStunRequest', + {client_id = <<>> :: unicode:chardata() | undefined, % = 1, optional + network_id = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + mac = <<>> :: iodata() | undefined, % = 3, optional + ip = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits + nat_type = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits + v6_info :: sdlan_pb:'SDLV6Info'() | undefined, % = 6, optional + session_token = <<>> :: iodata() | undefined % = 7, optional + }). +-endif. + +-ifndef('SDLSTUNREPLY_PB_H'). +-define('SDLSTUNREPLY_PB_H', true). +-record('SDLStunReply', + { + }). +-endif. + +-ifndef('SDLDATA_PB_H'). +-define('SDLDATA_PB_H', true). +-record('SDLData', + {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + src_mac = <<>> :: iodata() | undefined, % = 2, optional + dst_mac = <<>> :: iodata() | undefined, % = 3, optional + is_p2p = false :: boolean() | 0 | 1 | undefined, % = 4, optional + ttl = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits + data = <<>> :: iodata() | undefined, % = 6, optional + session_token = <<>> :: iodata() | undefined, % = 7, optional + identity_id = 0 :: non_neg_integer() | undefined % = 8, optional, 32 bits + }). +-endif. + +-ifndef('SDLSTUNPROBE_PB_H'). +-define('SDLSTUNPROBE_PB_H', true). +-record('SDLStunProbe', + {cookie = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + attr = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + step = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits + }). +-endif. + +-ifndef('SDLSTUNPROBEREPLY_PB_H'). +-define('SDLSTUNPROBEREPLY_PB_H', true). +-record('SDLStunProbeReply', + {cookie = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + step = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits + port = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits + ip = 0 :: non_neg_integer() | undefined % = 4, optional, 32 bits + }). +-endif. + +-ifndef('SDLREGISTER_PB_H'). +-define('SDLREGISTER_PB_H', true). +-record('SDLRegister', + {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + src_mac = <<>> :: iodata() | undefined, % = 2, optional + dst_mac = <<>> :: iodata() | undefined % = 3, optional + }). +-endif. + +-ifndef('SDLREGISTERACK_PB_H'). +-define('SDLREGISTERACK_PB_H', true). +-record('SDLRegisterAck', + {network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits + src_mac = <<>> :: iodata() | undefined, % = 2, optional + dst_mac = <<>> :: iodata() | undefined % = 3, optional + }). +-endif. + +-endif. diff --git a/maxwell.md b/maxwell.md new file mode 100644 index 0000000..c04e344 --- /dev/null +++ b/maxwell.md @@ -0,0 +1,48 @@ +## maxwell配置 + +## docker-compose.yml配置 +```yaml + +services: + maxwell: + image: docker.1ms.run/zendesk/maxwell:latest + container_name: maxwell + network_mode: "host" + + restart: always + entrypoint: ["bin/maxwell"] + + command: + - --host=127.0.0.1 + - --port=3306 + - --user=punchnetuser + - --password=punchnet@J1c8WGu + - --producer=redis + - --redis_host=127.0.0.1 + - --redis_port=16379 + - --redis_type=stream + - --redis_stream=maxwell_stream + - --log_level=info +``` + +## mysql权限配置 + +```sql + +# 创建maxwell依赖的数据库 + +CREATE DATABASE maxwell; +GRANT ALL ON maxwell.* TO 'punchnetuser'@'%'; + +-- 1️⃣ 允许读取数据 +GRANT SELECT ON *.* TO 'punchnetuser'@'%'; + +-- 2️⃣ 允许复制权限(关键) +GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'punchnetuser'@'%'; + +-- 3️⃣ 如果还需要创建 maxwell 库 +GRANT ALL ON maxwell.* TO 'punchnetuser'@'%'; + +FLUSH PRIVILEGES; + +``` \ No newline at end of file diff --git a/message.proto b/message.proto deleted file mode 100644 index 96eb93c..0000000 --- a/message.proto +++ /dev/null @@ -1,155 +0,0 @@ -syntax = "proto3"; - -// 基础公共类型定义 - -message SDLV4Info { - uint32 port = 1; - bytes v4 = 2; - uint32 nat_type = 3; -} - -message SDLV6Info { - uint32 port = 1; - bytes v6 = 2; -} - -// 设备网络地址信息 -message SDLDevAddr { - uint32 network_id = 1; - bytes mac = 2; - uint32 net_addr = 3; - uint32 net_bit_len = 4; - string network_domain = 5; -} - -// tcp通讯消息 -message SDLEmpty { - -} - -message SDLRegisterSuper { - uint32 version = 1; - string installed_channel = 2; - string client_id = 3; - SDLDevAddr dev_addr = 4; - string pub_key = 5; - string token = 6; - string network_code = 7; - string hostname = 8; -} - -message SDLRegisterSuperAck { - SDLDevAddr dev_addr = 1; - bytes aes_key = 2; - uint32 upgrade_type = 3; - optional string upgrade_prompt = 4; - optional string upgrade_address = 5; -} - -message SDLRegisterSuperNak { - uint32 error_code = 1; - string error_message = 2; -} - -// 网络地址查询 - -message SDLQueryInfo { - bytes dst_mac = 1; -} - -message SDLPeerInfo { - bytes dst_mac = 1; - SDLV4Info v4_info = 2; - optional SDLV6Info v6_info = 3; -} - -// 事件定义 - -message SDLNatChangedEvent { - bytes mac = 1; - uint32 ip = 2; -} - -message SDLSendRegisterEvent { - bytes dst_mac = 1; - uint32 nat_ip = 2; - uint32 nat_port = 3; - uint32 nat_type = 4; - optional SDLV6Info v6_info = 5; -} - -message SDLNetworkShutdownEvent { - string message = 1; -} - -// 命令定义 - -message SDLChangeNetworkCommand { - SDLDevAddr dev_addr = 1; - bytes aes_key = 2; -} - -message SDLCommandAck { - // status = true, 表示成功;status = false 表示失败,message是失败原因描述 - bool status = 1; - optional string message = 2; -} - -message SDLFlows { - // 服务器转发流量 - uint32 forward_num = 1; - // p2p直接流量 - uint32 p2p_num = 2; - // 接收的流量 - uint32 inbound_num = 3; -} - -// UDP通讯消息 - -message SDLStunRequest { - uint32 cookie = 1; - string client_id = 2; - uint32 network_id = 3; - bytes mac = 4; - uint32 ip = 5; - uint32 nat_type = 6; - optional SDLV6Info v6_info = 7; -} - -message SDLStunReply { - uint32 cookie = 1; -} - -message SDLData { - uint32 network_id = 1; - bytes src_mac = 2; - bytes dst_mac = 3; - bool is_p2p = 4; - uint32 ttl = 5; - bytes data = 6; -} - -message SDLRegister { - uint32 network_id = 1; - bytes src_mac = 2; - bytes dst_mac = 3; -} - -message SDLRegisterAck { - uint32 network_id = 1; - bytes src_mac = 2; - bytes dst_mac = 3; -} - -// 网络类型探测 - -message SDLStunProbe { - uint32 cookie = 1; - uint32 attr = 2; -} - -message SDLStunProbeReply { - uint32 cookie = 1; - uint32 port = 2; - uint32 ip = 3; -} \ No newline at end of file diff --git a/policy.sql b/policy.sql new file mode 100644 index 0000000..935538c --- /dev/null +++ b/policy.sql @@ -0,0 +1,43 @@ +CREATE TABLE `identity` ( + `identity_id` int NOT NULL AUTO_INCREMENT, + `network_id` int NOT NULL, + `subject_type` enum('token','instance','user','service') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `subject_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` int NOT NULL DEFAULT '0', + `expired_at` int NOT NULL DEFAULT '0', + PRIMARY KEY (`identity_id`), + UNIQUE KEY `uk_subject` (`network_id`,`subject_type`,`subject_id`), + KEY `idx_network_id` (`network_id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `identity_policy` ( + `identity_id` int NOT NULL, + `policy_id` int NOT NULL, + PRIMARY KEY (`identity_id`,`policy_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `policy` ( + `policy_id` int NOT NULL AUTO_INCREMENT, + `network_id` int NOT NULL, + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `created_at` int NOT NULL DEFAULT '0', + PRIMARY KEY (`policy_id`), + KEY `idx_network_id` (`network_id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci + +CREATE TABLE `rule` ( + `rule_id` int NOT NULL AUTO_INCREMENT, + `network_id` int NOT NULL, + `access_rule_id` int NOT NULL, + `src_policy_id` int NOT NULL, + `dst_policy_id` int NOT NULL, + `proto` tinyint NOT NULL, + `port` int NOT NULL, + `action` enum('allow','deny') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` int NOT NULL DEFAULT '0', + PRIMARY KEY (`rule_id`), + KEY `idx_src` (`src_policy_id`), + KEY `idx_network_id` (`network_id`), + KEY `idx_dst` (`dst_policy_id`) +) ENGINE=InnoDB AUTO_INCREMENT=85 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci \ No newline at end of file diff --git a/priv/public_key_sha256.sh b/priv/public_key_sha256.sh new file mode 100644 index 0000000..6314708 --- /dev/null +++ b/priv/public_key_sha256.sh @@ -0,0 +1,5 @@ +# 提取公钥 -> 转换为 RSA 原始格式 (PKCS#1) -> 转为 DER 二进制 -> 计算哈希 +openssl x509 -in cert.pem -pubkey -noout | \ +openssl rsa -pubin -RSAPublicKey_out -outform DER | \ +openssl dgst -sha256 -binary | \ +base64 \ No newline at end of file diff --git a/priv/ssl/server.crt b/priv/ssl/server.crt new file mode 100644 index 0000000..5dd301c --- /dev/null +++ b/priv/ssl/server.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIUMhNyuVo6MieWs2I9LsyTTiDKtYgwDQYJKoZIhvcNAQEL +BQAwgYkxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdC +ZWlqaW5nMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV +BAMMCWFubGljaGVuZzEfMB0GCSqGSIb3DQEJARYQMjQ0MTA4NzE1QHFxLmNvbTAe +Fw0yNTA0MjEwMzUyNTlaFw0yNjA0MjEwMzUyNTlaMIGJMQswCQYDVQQGEwJDTjEQ +MA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlhbmxpY2hlbmcxHzAdBgkq +hkiG9w0BCQEWEDI0NDEwODcxNUBxcS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDdxxyYG0zV2KzeiVH5AGj1X1h7vLAHVS8FGkPL2QBBqW5/PrJ/ +z/sv3QJz6dB3ElOnk14GsY8lWk8uX/fjgNIPawN1G2/bCdMrlPOCEJEIOqZvzQWg +PLRPGjoZx+wjCM/H7h47KVr4GNbo8MakLJeg6QB3rEEIiPrhQIoq9N7AhcjbEvWR +NIxIQrpSqMCE2A5RoKUxAMum9rEoe/6PBw2GgEsQl5E6suRZw3wavg3aUU+6MMyx +iiKEA6fCD5gDqgSo/xjgDUWJIOTTrmW6RBTcWP9iBUjWnCovQQ9zc6CzDXRgfsz9 +7uXQt9fuQEi++lcGnrsePjC99PnirCvmj/C/AgMBAAGjITAfMB0GA1UdDgQWBBT6 +n4jUTWQNcastC5jPHuU7CDzLFjANBgkqhkiG9w0BAQsFAAOCAQEAZJ9fY2Z+4vKr +bBqwHmfBjEnGgS7L2mC7uS2x/x2meBRKlAlw5+nKdaUBccyI2baI3P1mh/iV72Wr +OTcwUwSS6gIOB7JeWSB0UT7KbEOJ1tM/1HYs5F9tOT94P4Adm2gcKY81UlJMfSNQ +WyWFLjWOk/5fUP42BmgbUIafTT9p+LeP6NOyEs6b4hGpF3q5L1QDwMUfASpOWtHn +O7VyBvFyCGkVchnorWJ3ZXPaa7hy+2ULOK/d9zH3xxq4LKRclAS5XAMWHuw6/+tu +CoxA+RPnaqHexPSzYlEElOT286FDyZHadjUDD0q/0Um92NUM3r+UrNEs/OHp7/nU +M3BVM7H6LQ== +-----END CERTIFICATE----- diff --git a/priv/ssl/server.csr b/priv/ssl/server.csr new file mode 100644 index 0000000..f8a18cf --- /dev/null +++ b/priv/ssl/server.csr @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICzzCCAbcCAQAwgYkxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAw +DgYDVQQHDAdCZWlqaW5nMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBM +dGQxEjAQBgNVBAMMCWFubGljaGVuZzEfMB0GCSqGSIb3DQEJARYQMjQ0MTA4NzE1 +QHFxLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN3HHJgbTNXY +rN6JUfkAaPVfWHu8sAdVLwUaQ8vZAEGpbn8+sn/P+y/dAnPp0HcSU6eTXgaxjyVa +Ty5f9+OA0g9rA3Ubb9sJ0yuU84IQkQg6pm/NBaA8tE8aOhnH7CMIz8fuHjspWvgY +1ujwxqQsl6DpAHesQQiI+uFAiir03sCFyNsS9ZE0jEhCulKowITYDlGgpTEAy6b2 +sSh7/o8HDYaASxCXkTqy5FnDfBq+DdpRT7owzLGKIoQDp8IPmAOqBKj/GOANRYkg +5NOuZbpEFNxY/2IFSNacKi9BD3NzoLMNdGB+zP3u5dC31+5ASL76Vwaeux4+ML30 ++eKsK+aP8L8CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQBHdTrwcS0Ip5XO/zJ/ +wFZvxe8wcdMBaHjSRx09Lgy3V1L9d0DPOfuUP4LP8UCxniucA2JLugJO1wr/5nZA +FS9GcyCgbMKX/EskFkpuz72EA11WhyqFp/9nWZsxZB0t1cs3bUFeoFd2SE6QIo4N +UY+guZCcF8hVwppceOxyaUQ9cudAClH9JSMR1XoIwvv3X7FJkPhM12DvcsLr062S +fwG7/1h+VoSpAM/UYtBHBkU0MIVn1Gw6lJvkabUV0oYYBzl9ejsq1Qo2nUMdOEQY +SS/VhVLONMyMCIERt3/GJTXdrJ12VqawJACFwv8g2i6NxbQvbZpF7TpS8amduO8+ +aRE6 +-----END CERTIFICATE REQUEST----- diff --git a/priv/ssl/server.key b/priv/ssl/server.key new file mode 100644 index 0000000..ea81719 --- /dev/null +++ b/priv/ssl/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdxxyYG0zV2Kze +iVH5AGj1X1h7vLAHVS8FGkPL2QBBqW5/PrJ/z/sv3QJz6dB3ElOnk14GsY8lWk8u +X/fjgNIPawN1G2/bCdMrlPOCEJEIOqZvzQWgPLRPGjoZx+wjCM/H7h47KVr4GNbo +8MakLJeg6QB3rEEIiPrhQIoq9N7AhcjbEvWRNIxIQrpSqMCE2A5RoKUxAMum9rEo +e/6PBw2GgEsQl5E6suRZw3wavg3aUU+6MMyxiiKEA6fCD5gDqgSo/xjgDUWJIOTT +rmW6RBTcWP9iBUjWnCovQQ9zc6CzDXRgfsz97uXQt9fuQEi++lcGnrsePjC99Pni +rCvmj/C/AgMBAAECggEAM4j6RwpI/4RbH1cvmjoTKbmfORmumfWceIYS7QKfAaMa +jy0Fk5fD2ep0kHTrwU+b6tvexJVsGxTyQ2d/lfkwVu7aHdNjWbXdwUnakAXDffML +C/3LaeHRUHRavfTsFXQNvHrDwaGphu9WuUiCEFJgZb7fIfAAKLiT+9XghXzjaj79 +nGANBB++kfBGacfj2NMedCxsbZ++pD7DbTG4utnHmzgwB3WEEm2kIbt0XpuDSZqe +/tCA1gCOADjV17C31booT6xdoj+s/Se0YxY91JaZFkI5wTSDIhB9scZzh8piy8YQ +QaEaRUUYNbzdI1MyvgewT6wQLONNlytOOc9hYnPgAQKBgQDyzaublY2q+yzqCQ68 +JSKNTCSFRwumJ1kmdfz/0QwzS363l7LFnfIb55h27q3vuiagPfRbi0GK/tVXhOe+ +8mntNMoJJQJzowpy4ANqKfGndojXejE1s1ExpuGyqWV4MyFGiwAnnzyWRENw4laS +roY0OcynNuq++isgrVMPlDLAvwKBgQDp1OTh2wcSfhsaVbMjNVCOGD82OFK057JB +3C62Li2lCybFwcooypCyZthUdskY2Gf/mDdnpLSLvXr/7bO3IyLopA3WpnYqMBt+ +7sP/VQJMoyobLFMnJh+N+CxwkhRNAib64054WKwiJcccJ5fplUvNjOLBgGx3a/3N +OIxx+L7QAQKBgQC+EK3zPuEFJVYFZk24jkE75oz4H6NIz6iD6PzBrH0mckShpwh0 +la1+lo7NGw3hiRDPg3ATcTE/gziyKAHZgZ3V5+r3uZbvuoNlZWKG6oqWkr2QH8EB +znsSqRYoa15Y931m4Uyft5EP+CPq6+LlM+UuYMiJZP3hvaehDszkdxg7tQKBgGjv +vMPLCpJ2+2zHFvxu+ba7FOsdPain7ix2RpRFhwBxT7Yh8Lp7pZIaa20EXd0DiTCA +PCUMGmY345IlN6ixYQIsVXWGALOQIVbGijj1CnIgK05EhxCjoDeTL0ZZmDizBZFE +HzwM9zrf30o4TolqEbmuRzj1jDfPw/esMAMZ0XABAoGBANpjvUN0Qvy9WmLyPe6U +DBzIAUyyIL3mnCuHLCQ+dE6nBf5l20sVjTdIl/eLlvmD7dwT/D9Zsg32/c2NBCdY +DltKKZl2u9nuSJ1g8DWTZUQHkYSTeKPOoAl/5mbCgyTxzmmmtZF6MySKuif0rzwS +X2Rwou9zTpwgsEEmQ/RH4G94 +-----END PRIVATE KEY----- diff --git a/proto/sdlan.proto b/proto/sdlan.proto new file mode 100644 index 0000000..cd1d3fb --- /dev/null +++ b/proto/sdlan.proto @@ -0,0 +1,229 @@ +syntax = "proto3"; + +//package message; + +// 基础公共类型定义 + +message SDLV4Info { + uint32 port = 1; + bytes v4 = 2; + uint32 nat_type = 3; +} + +message SDLV6Info { + uint32 port = 1; + bytes v6 = 2; +} + +// ipv6 assist相关 +message SDLV6AssistProbe { + uint32 pkt_id = 1; +} + +message SDLV6AssistProbeReply { + uint32 pkt_id = 1; + SDLV6Info v6_info = 2; +} + +// 和super之间采用了quic协议通讯 +// 传输层采用: <> + +message SDLWelcome { + uint32 version = 1; + // 服务器允许的最大双向流 + uint32 max_bidi_streams = 2; + // 服务器允许的最大包 + uint32 max_packet_size = 3; + // 心跳包的间隔 + uint32 heartbeat_sec = 4; + // ipv6辅助器地址 + SDLV6Info ipv6_assist = 5; +} + +// 这里修改成了扁平的结构, 否则有些字段不好找放的位置 +message SDLRegisterSuper { + string client_id = 1; + // 网络地址信息已经有https请求分配了 + // 注册的时候需要带上(network_id, mac, ip, mask_len, hostname) + uint32 network_id = 2; + bytes mac = 3; + uint32 ip = 4; + uint32 mask_len = 5; + string hostname = 6; + + string pub_key = 7; + // 客户端使用http协议请求后端,通过token或者账号密码登录时, 统一返回一个access_token; + // RegisterSuper的时候,验证凭证是否合法 (access_token) + string access_token = 8; +} + +// 客户端的升级逻辑,在https的接口里面去完成 +// 部分逻辑会脱离quic去通讯,增加session_token校验 +message SDLRegisterSuperAck { + // 目前支持aes, chacha20 + string algorithm = 1; + bytes key = 2; + // 逻辑分段,chacha20加密算法需要使用该字段 + uint32 region_id = 3; + bytes session_token = 4; +} + +message SDLRegisterSuperNak { + uint32 error_code = 1; + string error_message = 2; +} + +// 网络地址查询 +message SDLQueryInfo { + bytes dst_mac = 1; +} + +message SDLPeerInfo { + bytes dst_mac = 1; + optional SDLV4Info v4_info = 2; + optional SDLV6Info v6_info = 3; +} + +// ARP查询相关 +// 真实的arp请求是通过广播的形式获取到的,但是针对于macos这种tun的实现;是能够分析出arp请求包的; +// 对于当前网络来说,服务端是知道mac对应的ip地址的,因此没有必要广播;直接通过服务器端返回 +message SDLArpRequest { + uint32 target_ip = 1; + uint32 origin_ip = 2; + bytes context = 3; +} + +message SDLArpResponse { + uint32 target_ip = 1; + bytes target_mac = 2; + uint32 origin_ip = 3; + bytes context = 4; +} + +// 权限请求查询相关 +message SDLPolicyRequest { + uint32 src_identity_id = 1; + uint32 dst_identity_id = 2; + uint32 version = 3; +} + +// 基于quic通讯,rules部分已经没有了长度限制 +message SDLPolicyResponse { + uint32 src_identity_id = 1; + uint32 dst_identity_id = 2; + // 版本号,客户端需要比较版本号确定是否覆盖; 请求端自己去管理版本号,服务端只是原样回写 + uint32 version = 3; + // 1 + 2稀疏序列化规则, 按照: <> 这个格式序列号所有的规则信息; 下发的数据默认都是allow,deny规则的服务器端已经屏蔽 + bytes rules = 4; +} + +// 事件定义 + +message SDLEvent { + // nat映射变化 + message NatChanged { + bytes mac = 1; + uint32 ip = 2; + } + + // 发送register消息 + message SendRegister { + bytes dst_mac = 1; + uint32 nat_ip = 2; + uint32 nat_port = 3; + uint32 nat_type = 4; + optional SDLV6Info v6_info = 5; + } + + // 网络关闭 + message NetworkShutdown { + string message = 1; + } + + oneof event { + NatChanged nat_changed = 1; + SendRegister send_register = 2; + NetworkShutdown shutdown = 3; + } +} + +// Command指令 +message SDLCommand { + uint32 pkt_id = 1; + // 出口节点控制 + message ExitNodeControl { + int32 action = 1; // 必选:操作类型 + string remark = 2; // 可选:备注(方便日志/调试) + } + + oneof command { + ExitNodeControl exit_node = 2; + } +} + +message SDLCommandAck { + uint32 pkt_id = 1; + int32 code = 2; + string message = 3; + bytes data = 4; +} + +// UDP通讯消息 + +// client和stun之间的心跳包,客户端需要和super的udp之间的存活逻辑 +message SDLStunRequest { + string client_id = 1; + uint32 network_id = 2; + bytes mac = 3; + uint32 ip = 4; + uint32 nat_type = 5; + optional SDLV6Info v6_info = 6; + bytes session_token = 7; +} + +message SDLStunReply { +} + +message SDLData { + uint32 network_id = 1; + bytes src_mac = 2; + bytes dst_mac = 3; + bool is_p2p = 4; + uint32 ttl = 5; + bytes data = 6; + bytes session_token = 7; + // 端通过https登录的时候,服务端会分配该端对应的权限标识 + // 后续的请求过程中需要带上这个值,对端通过这个值要判断对数据包是否放行 + uint32 identity_id = 8; +} + +// 网络类型探测 + +message SDLStunProbe { + uint32 cookie = 1; + uint32 attr = 2; + // 增加step是为了方便端上判断,收到的请求和响应之间的映射关系;服务器端原样返回 + uint32 step = 3; +} + +message SDLStunProbeReply { + uint32 cookie = 1; + // 增加step是为了方便端上判断,收到的请求和响应之间的映射关系;服务器端原样返回 + uint32 step = 2; + uint32 port = 3; + uint32 ip = 4; +} + +// Node-Node之间的握手逻辑, 是基于udp传输的 + +message SDLRegister { + uint32 network_id = 1; + bytes src_mac = 2; + bytes dst_mac = 3; +} + +message SDLRegisterAck { + uint32 network_id = 1; + bytes src_mac = 2; + bytes dst_mac = 3; +} \ No newline at end of file diff --git a/rebar.config b/rebar.config index ae8d624..b19e7d3 100644 --- a/rebar.config +++ b/rebar.config @@ -1,13 +1,33 @@ {erl_opts, [ debug_info ]}. + +{plugins, [ + {rebar3_gpb_plugin, ".*", {git, "https://github.com/lrascao/rebar3_gpb_plugin.git", {tag, "2.23.8"}}} +]}. + +% ====================== +% 核心:强制指定 proto 路径 + 输出到你的 apps/sdlan +% ====================== +{gpb_opts, [ + {i, "proto"}, % proto 文件路径 + {src_dirs, ["proto"]}, % 源码目录(必须) + recursive, % 递归查找 proto 文件 + {module_name_suffix, "_pb"}, % 生成模块后缀 + {o_erl, "src"}, % .erl 输出目录 + {o_hrl, "include"}, % .hrl 输出目录 + include_as_lib, % gpb.hrl 通过 -include_lib("gpb/include/gpb.hrl") + {strings_as_binaries, true}, % proto string → Erlang binary + type_specs, % 生成 type specs + report, % 编译报告 + verbose % 打印详细信息 +]}. + {deps, [ {poolboy, ".*", {git, "https://github.com/devinus/poolboy.git", {tag, "1.5.1"}}}, {hackney, ".*", {git, "https://github.com/benoitc/hackney.git", {tag, "1.16.0"}}}, - {jiffy, ".*", {git, "https://github.com/davisp/jiffy.git", {tag, "1.1.1"}}}, {cowboy, ".*", {git, "https://github.com/ninenines/cowboy.git", {tag, "2.12.0"}}}, {mysql, ".*", {git, "https://github.com/mysql-otp/mysql-otp", {tag, "1.8.0"}}}, - {gpb, ".*", {git, "https://github.com/tomas-abrahamsson/gpb.git", {tag, "4.21.1"}}}, {throttle, ".*", {git, "https://github.com/lambdaclass/throttle.git", {tag, "0.3.0"}}}, {dns_erlang, ".*", {git, "https://github.com/dnsimple/dns_erlang.git", {tag, "v4.4.0"}}}, {quicer, ".*", {git, "https://github.com/emqx/quic.git", {tag, "0.4.0"}}}, @@ -15,34 +35,18 @@ {sync, ".*", {git, "https://github.com/rustyio/sync.git", {branch, "master"}}} ]}. -{relx, [{release, {sdlan, "0.1.0"}, - [sdlan, - sasl]}, - - {mode, dev}, - - %% automatically picked up if the files - %% exist but can be set manually, which - %% is required if the names aren't exactly - %% sys.config and vm.args - {sys_config, "./config/sys.config"}, - {vm_args, "./config/vm.args"} - - %% the .src form of the configuration files do - %% not require setting RELX_REPLACE_OS_VARS - %% {sys_config_src, "./config/sys.config.src"}, - %% {vm_args_src, "./config/vm.args.src"} +{provider_hooks, [ + {pre, [ + {compile, {protobuf, compile}}, + {clean, {protobuf, clean}} + ]} ]}. -{profiles, [{prod, [{relx, - [%% prod is the default mode when prod - %% profile is used, so does not have - %% to be explicitly included like this - {mode, prod} +{relx, [{release, {sdlan, "0.1.0"}, + [sdlan, sasl]}, + {mode, dev}, + {sys_config, "./config/sys.config"}, + {vm_args, "./config/vm.args"}]}. - %% use minimal mode to exclude ERTS - %% {mode, minimal} - ] - }]}]}. - -{rebar_packages_cdn, "https://hexpm.upyun.com"}. \ No newline at end of file +{profiles, [{prod, [{relx, [{mode, prod}]}]}]}. +{rebar_packages_cdn, "https://hexpm.upyun.com"}. diff --git a/rebar.lock b/rebar.lock index e43e3d7..c53aa6a 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,5 @@ {"1.2.0", -[{<<"base32">>,{pkg,<<"base32">>,<<"1.0.0">>},2}, +[{<<"base32">>,{pkg,<<"base32">>,<<"1.0.0">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.2">>},1}, {<<"cowboy">>, {git,"https://github.com/ninenines/cowboy.git", @@ -12,44 +12,24 @@ {<<"dns_erlang">>, {git,"https://github.com/dnsimple/dns_erlang.git", {ref,"e1149a2dd6f49c6560aa245bc6f3d40a5cbe70e1"}}, - 1}, - {<<"dns_proxy">>, - {git,"https://gitea.s5s8.com/anlicheng/dns_proxy.git", - {ref,"5ed832359e42ec99d148bf2ada1729b540017ab8"}}, 0}, {<<"fs">>,{pkg,<<"fs">>,<<"6.1.1">>},1}, - {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1}, - {<<"gpb">>, - {git,"https://github.com/tomas-abrahamsson/gpb.git", - {ref,"a53bc4909b3dc5a78b996263d92db38fed9d4782"}}, - 0}, {<<"hackney">>, {git,"https://github.com/benoitc/hackney.git", {ref,"f3e9292db22c807e73f57a8422402d6b423ddf5f"}}, 0}, {<<"idna">>,{pkg,<<"idna">>,<<"6.0.1">>},1}, - {<<"jiffy">>, - {git,"https://github.com/davisp/jiffy.git", - {ref,"9ea1b35b6e60ba21dfd4adbd18e7916a831fd7d4"}}, - 0}, - {<<"lager">>, - {git,"https://github.com/erlang-lager/lager.git", - {ref,"459a3b2cdd9eadd29e5a7ce5c43932f5ccd6eb88"}}, - 0}, {<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1}, {<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},1}, {<<"mysql">>, {git,"https://github.com/mysql-otp/mysql-otp", {ref,"caf5ff96c677a8fe0ce6f4082bc036c8fd27dd62"}}, 0}, - {<<"parse_trans">>, - {git,"https://github.com/uwiger/parse_trans", - {ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}}, - 0}, + {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.0">>},1}, {<<"pkt">>, {git,"https://github.com/msantos/pkt.git", {ref,"67a4a14f596fded5ad5f2d8f94318faa8ad2c288"}}, - 1}, + 0}, {<<"poolboy">>, {git,"https://github.com/devinus/poolboy.git", {ref,"3bb48a893ff5598f7c73731ac17545206d259fac"}}, @@ -78,10 +58,10 @@ {<<"base32">>, <<"1AB331F812FCC254C8F7D4348E1E5A6F2B9B32B7A260BF2BC3358E3BF14C841A">>}, {<<"certifi">>, <<"B7CFEAE9D2ED395695DD8201C57A2D019C0C43ECAF8B8BCB9320B40D6662F340">>}, {<<"fs">>, <<"9D147B944D60CFA48A349F12D06C8EE71128F610C90870BDF9A6773206452ED0">>}, - {<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>}, {<<"idna">>, <<"1D038FB2E7668CE41FBF681D2C45902E52B3CB9E9C77B55334353B222C2EE50C">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, + {<<"parse_trans">>, <<"09765507A3C7590A784615CFD421D101AEC25098D50B89D7AA1D66646BC571C1">>}, {<<"snabbkaffe">>, <<"9BE2F54F61FC6862391B666B2B5B76C3FA53598E2989A17CEF1B48CF347A8A63">>}, {<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>}, {<<"unicode_util_compat">>, <<"8516502659002CEC19E244EBD90D312183064BE95025A319A6C7E89F4BCCD65B">>}]}, @@ -89,10 +69,10 @@ {<<"base32">>, <<"0449285348ED0C4CD83C7198E76C5FD5A0451C4EF18695B9FD43792A503E551A">>}, {<<"certifi">>, <<"3B3B5F36493004AC3455966991EAF6E768CE9884693D9968055AEEEB1E575040">>}, {<<"fs">>, <<"EF94E95FFE79916860649FED80AC62B04C322B0BB70F5128144C026B4D171F8B">>}, - {<<"goldrush">>, <<"99CB4128CFFCB3227581E5D4D803D5413FA643F4EB96523F77D9E6937D994CEB">>}, {<<"idna">>, <<"A02C8A1C4FD601215BB0B0324C8A6986749F807CE35F25449EC9E69758708122">>}, {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, {<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>}, + {<<"parse_trans">>, <<"17EF63ABDE837AD30680EA7F857DD9E7CED9476CDD7B0394432AF4BFC241B960">>}, {<<"snabbkaffe">>, <<"70A98DF36AE756908D55B5770891D443D63C903833E3E87D544036E13D4FAC26">>}, {<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>}, {<<"unicode_util_compat">>, <<"D48D002E15F5CC105A696CF2F1BBB3FC72B4B770A184D8420C8DB20DA2674B38">>}]} diff --git a/src/dns_proxy/dns_resolver.erl b/src/dns_proxy/dns_resolver.erl new file mode 100644 index 0000000..08693d5 --- /dev/null +++ b/src/dns_proxy/dns_resolver.erl @@ -0,0 +1,147 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2025, +%%% @doc +%%% +%%% @end +%%% Created : 03. 12月 2025 23:00 +%%%------------------------------------------------------------------- +-module(dns_resolver). +-author("anlicheng"). + +-include_lib("dns_erlang/include/dns.hrl"). +-include_lib("pkt/include/pkt.hrl"). +-include("dns_proxy.hrl"). + +-export([resolve/1]). + +%% 协议部分 +-define(TCP_PROTOCOL, 6). +-define(UDP_PROTOCOL, 17). + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec resolve(IpPacket :: binary()) -> {ok, RespIpPacket :: binary()} | {error, Reason :: term()}. +resolve(IpPacket) when is_binary(IpPacket) -> + try + {#ipv4{saddr = ReqSAddr, daddr = ReqDAddr, p = Protocol}, ReqIpPayload} = pkt:ipv4(IpPacket), + case Protocol of + ?UDP_PROTOCOL -> + {#udp{sport = ReqSPort, dport = ReqDPort}, UdpPayload} = pkt:udp(ReqIpPayload), + DnsQueryMessage = dns:decode_message(UdpPayload), + case resolve0(DnsQueryMessage) of + {ok, DnsResp} -> + RespIpPacket = build_ip_packet(ReqDAddr, ReqSAddr, ReqDPort, ReqSPort, DnsResp), + {ok, RespIpPacket}; + {error, Reason} -> + {error, Reason} + end; + _ -> + {error, invalid_packet} + end + catch error:_ -> + {error, invalid_packet} + end. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +-spec resolve0(Packet :: #dns_message{}) -> {ok, Resp :: binary()} | {error, Reason :: any()}. +resolve0(QueryMsg = #dns_message{qc = 1, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]}) -> + %% 查找是否是内置的域名 + case sdlan_hostname_regedit:lookup(QName) of + {ok, Ip} when QType =:= ?DNS_TYPE_A, QClass =:= ?DNS_CLASS_IN -> + Answer = #dns_rr { + name = QName, + type = QType, + class = QClass, + ttl = 300, + data = #dns_rrdata_a { + ip = Ip + } + }, + RespMsg = QueryMsg#dns_message{ + qr = true, + ra = true, + anc = 1, + auc = 0, + adc = 0, + answers = [Answer], + authority = [], + additional = [] + }, + logger:debug("[dns_resolver] punchnet inbuilt qnanme: ~p, ip: ~p", [QName, Ip]), + {ok, dns:encode_message(RespMsg)}; + {ok, _Ip} -> + {ok, dns:encode_message(build_empty_response(QueryMsg))}; + error -> + case sdlan_domain_regedit:maybe_domain(QName) of + true -> + EmptyDnsResp = dns:encode_message(build_nxdomain_response(QueryMsg)), + {ok, EmptyDnsResp}; + false -> + {error, not_supported} + end + end; +resolve0(Error) -> + {error, Error}. + +-spec build_empty_response(QueryMsg :: #dns_message{}) -> EmptyResp :: #dns_message{}. +build_empty_response(QueryMsg) -> + QueryMsg#dns_message{ + qr = true, + aa = true, + ra = true, + rc = ?DNS_RCODE_NOERROR, + anc = 0, + auc = 0, + adc = 0, + answers = [], + authority = [], + additional = [] + }. + +-spec build_nxdomain_response(QueryMsg :: #dns_message{}) -> EmptyResp :: #dns_message{}. +build_nxdomain_response(QueryMsg) -> + QueryMsg#dns_message{ + qr = true, + aa = true, + ra = true, + rc = ?DNS_RCODE_NXDOMAIN, + anc = 0, + auc = 0, + adc = 0, + answers = [], + authority = [], + additional = [] + }. + +-spec build_ip_packet(SAddr :: inet:ip4_address(), DAddr :: inet:ip4_address(), SPort :: integer(), DPort :: integer(), Payload :: binary()) -> IpPacket :: binary(). +build_ip_packet(SAddr, DAddr, SPort, DPort, UdpPayload) when is_integer(SPort), is_integer(DPort), is_binary(UdpPayload) -> + ULen = 8 + byte_size(UdpPayload), + RespUdpHeader = pkt:udp(#udp{ + sport = SPort, + dport = DPort, + ulen = ULen, + sum = dns_utils:udp_checksum(SAddr, DAddr, SPort, DPort, UdpPayload) + }), + IpPayload = <>, + + IpPacket0 = #ipv4{ + len = 20 + ULen, + ttl = 64, + off = 0, + mf = 0, + sum = 0, + p = ?UDP_PROTOCOL, + saddr = SAddr, + daddr = DAddr, + opt = <<>> + }, + IpCheckSum = dns_utils:ip_checksum(IpPacket0), + IpHeader = pkt:ipv4(IpPacket0#ipv4{sum = IpCheckSum}), + + <>. diff --git a/apps/sdlan/src/test/sdlan_tcp_client.erl b/src/dns_proxy/dns_server.erl similarity index 68% rename from apps/sdlan/src/test/sdlan_tcp_client.erl rename to src/dns_proxy/dns_server.erl index cae3213..ba4eda8 100644 --- a/apps/sdlan/src/test/sdlan_tcp_client.erl +++ b/src/dns_proxy/dns_server.erl @@ -4,15 +4,18 @@ %%% @doc %%% %%% @end -%%% Created : 29. 3月 2024 14:32 +%%% Created : 09. 4月 2024 17:37 %%%------------------------------------------------------------------- --module(sdlan_tcp_client). +-module(dns_server). -author("anlicheng"). +-include("sdlan.hrl"). +-include("sdlan_pb.hrl"). -behaviour(gen_server). %% API --export([start_link/0]). +-export([start_link/2]). +-export([get_name/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -27,11 +30,15 @@ %%% API %%%=================================================================== +-spec get_name(Id :: integer()) -> atom(). +get_name(Id) when is_integer(Id) -> + list_to_atom("dns_server:" ++ integer_to_list(Id)). + %% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> +-spec(start_link(Name :: atom(), Port :: integer()) -> {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). +start_link(Name, Port) when is_atom(Name), is_integer(Port) -> + gen_server:start_link({local, Name}, ?MODULE, [Port], []). %%%=================================================================== %%% gen_server callbacks @@ -42,9 +49,21 @@ start_link() -> -spec(init(Args :: term()) -> {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | {stop, Reason :: term()} | ignore). -init([]) -> - {ok, Socket} = gen_tcp:connect("localhost", 18083, [binary, {packet, 2}, {active, true}]), - ok = gen_tcp:send(Socket, <<"hello world">>), +init([Port]) -> + %% 需要提高进程的调度优先级 + erlang:process_flag(priority, high), + Opts = [ + binary, + {reuseaddr, true}, + {reuseport, true}, + {active, true}, + {recbuf, 5 * 1024 * 1024}, + {sndbuf, 5 * 1024 * 1024} + ], + {ok, Socket} = gen_udp:open(Port, Opts), + inet_udp:controlling_process(Socket, self()), + + logger:debug("[sdlan_stun] start at port: ~p", [Port]), {ok, #state{socket = Socket}}. %% @private @@ -66,7 +85,8 @@ handle_call(_Request, _From, State = #state{}) -> {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). -handle_cast(_Request, State = #state{}) -> +%% 当前node下的转发,基于进程间的通讯 +handle_cast(_Request, State) -> {noreply, State}. %% @private @@ -75,7 +95,16 @@ handle_cast(_Request, State = #state{}) -> {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). -handle_info(_Info, State = #state{}) -> +handle_info({udp, Sock, Ip, Port, IpPacket}, State = #state{socket = Sock}) -> + case dns_resolver:resolve(IpPacket) of + {ok, RespIpPacket} -> + gen_udp:send(Sock, Ip, Port, RespIpPacket); + {error, Reason} -> + logger:debug("[dns_server] resolve dns query error: ~p", [Reason]) + end, + {noreply, State}; +handle_info(Info, State) -> + logger:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]), {noreply, State}. %% @private @@ -98,4 +127,4 @@ code_change(_OldVsn, State = #state{}, _Extra) -> %%%=================================================================== %%% Internal functions -%%%=================================================================== +%%%=================================================================== \ No newline at end of file diff --git a/apps/sdlan/src/dns_proxy/dns_proxy_sup.erl b/src/dns_proxy/dns_server_sup.erl similarity index 69% rename from apps/sdlan/src/dns_proxy/dns_proxy_sup.erl rename to src/dns_proxy/dns_server_sup.erl index 9882fb7..0d54814 100644 --- a/apps/sdlan/src/dns_proxy/dns_proxy_sup.erl +++ b/src/dns_proxy/dns_server_sup.erl @@ -3,7 +3,7 @@ %% @end %%%------------------------------------------------------------------- --module(dns_proxy_sup). +-module(dns_server_sup). -behaviour(supervisor). @@ -12,6 +12,7 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). @@ -23,28 +24,23 @@ start_link() -> %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional -%% modules => modules()} % optional +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, - Port = 15353, - Specs = [ + AcceptorNum = 10, + + Specs = lists:map(fun(Id) -> + Name = dns_server:get_name(Id), #{ - id => dns_handler_sup, - start => {dns_handler_sup, start_link, []}, - restart => permanent, - shutdown => 2000, - type => supervisor, - modules => ['dns_handler_sup'] - }, - #{ - id => dns_server, - start => {dns_server, start_link, [Port]}, + id => Name, + start => {dns_server, start_link, [Name, Port]}, restart => permanent, shutdown => 2000, type => worker, modules => ['dns_server'] } - ], - - {ok, {SupFlags, Specs}}. \ No newline at end of file + end, lists:seq(1, AcceptorNum)), + {ok, {SupFlags, Specs}}. diff --git a/apps/sdlan/src/dns_proxy/dns_utils.erl b/src/dns_proxy/dns_utils.erl similarity index 98% rename from apps/sdlan/src/dns_proxy/dns_utils.erl rename to src/dns_proxy/dns_utils.erl index 3dc81e6..5a64c00 100644 --- a/apps/sdlan/src/dns_proxy/dns_utils.erl +++ b/src/dns_proxy/dns_utils.erl @@ -112,6 +112,7 @@ ip_checksum(#ipv4{hl = HL, tos = ToS, len = Len, CheckSum end. +-spec test() -> term(). test() -> %Bin = <<69,0,0,77,48,179,0,0,64,17,28,168,100,123,0,2,100,100,100,100,252,230,0,53,0,57,6,92,152,24,1,0,0,1,0,0,0,0,0,0,2,100,98,7,95,100,110,115,45,115,100,4,95,117,100,112,8,112,117,110,99,104,110,101,116,2,116,115,3,110,101,116,0,0,12,0,1>>, Bin = <<69,0,0,93,0,0,0,0,64,6,77,86,100,100,100,100,100,123,0,2,0,53,196,102,0,73,39,7,215,192,129,128,0,1,0,1,0,0,0,0,2,108,98,7,95,100,110,115,45,115,100,4,95,117,100,112,8,112,117,110,99,104,110,101,116,2,116,115,3,110,101,116,0,0,12,0,1,192,12,0,12,0,1,0,0,1,44,0,4,192,168,1,101>>, @@ -128,4 +129,4 @@ test() -> logger:debug("ip_sum: ~p, =: ~p, udp: ~p, checkSum: ~p, =: ~p", [IpSum, ip_checksum(IPPacket), UDP, CheckSum, X]), - dns:decode_message(UDPPayload). \ No newline at end of file + dns:decode_message(UDPPayload). diff --git a/apps/sdlan/src/http_handler/api_handler.erl b/src/http/api_handler.erl similarity index 86% rename from apps/sdlan/src/http_handler/api_handler.erl rename to src/http/api_handler.erl index 2d2b6d2..b3a2c89 100644 --- a/apps/sdlan/src/http_handler/api_handler.erl +++ b/src/http/api_handler.erl @@ -17,6 +17,8 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 重新加载对应的主机信息 +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. handle_request("POST", "/test/auth_token", _, PostParams) -> logger:debug("[test_handler] get post params: ~p", [PostParams]), [Id | _] = network_bo:get_all_networks(), @@ -31,4 +33,4 @@ handle_request(_, Path, _, _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% helper methods -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ No newline at end of file +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/http/binlog_handler.erl b/src/http/binlog_handler.erl new file mode 100644 index 0000000..788a4d2 --- /dev/null +++ b/src/http/binlog_handler.erl @@ -0,0 +1,32 @@ +%%%------------------------------------------------------------------- +%%% @author licheng5 +%%% @copyright (C) 2020, +%%% @doc +%%% +%%% @end +%%% Created : 26. 4月 2020 3:36 下午 +%%%------------------------------------------------------------------- +-module(binlog_handler). +-author("licheng5"). + +%% API +-export([handle_request/4]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% helper methods +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% 重新加载对应的主机信息 +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. +handle_request("POST", "/binlog", _, PostParams) -> + logger:debug("[binlog_handler] get post params: ~p", [PostParams]), + {ok, 200, sdlan_util:json_data(<<"ok">>)}; + +handle_request(_, Path, _, _) -> + Path1 = list_to_binary(Path), + {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% helper methods +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/apps/sdlan/src/http_handler/http_protocol.erl b/src/http/http_protocol.erl similarity index 86% rename from apps/sdlan/src/http_handler/http_protocol.erl rename to src/http/http_protocol.erl index 231eb60..9e14724 100644 --- a/apps/sdlan/src/http_handler/http_protocol.erl +++ b/src/http/http_protocol.erl @@ -12,6 +12,7 @@ %% API -export([init/2]). +-spec init(Req :: cowboy_req:req(), Opts :: [module()]) -> {ok, cowboy_req:req(), [module()]}. init(Req0, Opts = [Mod|_]) -> Method = binary_to_list(cowboy_req:method(Req0)), Path = binary_to_list(cowboy_req:path(Req0)), @@ -19,10 +20,12 @@ init(Req0, Opts = [Mod|_]) -> GetParams = maps:from_list(GetParams0), {ok, PostParams, Req1} = parse_body(Req0), + Headers = cowboy_req:headers(Req0), + logger:debug("[http_protocol] request path: ~p, get_params: ~p, post_params: ~p, headers: ~p", + [Path, GetParams, PostParams, Headers]), + try Mod:handle_request(Method, Path, GetParams, PostParams) of {ok, StatusCode, Resp} -> - %logger:debug("[http_protocol] request path: ~p, get_params: ~p, post_params: ~p, response: ~ts", - % [Path, GetParams, PostParams, Resp]), AcceptEncoding = cowboy_req:header(<<"accept-encoding">>, Req1, <<>>), Req2 = case iolist_size(Resp) >= 1024 andalso supported_gzip(AcceptEncoding) of true -> @@ -45,9 +48,10 @@ init(Req0, Opts = [Mod|_]) -> {ok, Req2, Opts}; _:Error:Stack -> logger:warning("[http_handler] get error: ~p, stack: ~p", [Error, Stack]), + ErrorBin = sdlan_util:term_to_binary(Error), Req2 = cowboy_req:reply(500, #{ <<"Content-Type">> => <<"text/html;charset=utf-8">> - }, <<"Internal Server Error">>, Req1), + }, <<"Internal Server Error: ", ErrorBin/binary>>, Req1), {ok, Req2, Opts} end. @@ -62,7 +66,7 @@ parse_body(Req0) -> {ok, Body, Req1} = read_body(Req0), case Body /= <<>> of true -> - {ok, catch jiffy:decode(Body, [return_maps]), Req1}; + {ok, catch json:decode(Body), Req1}; false -> {ok, #{}, Req1} end; @@ -83,4 +87,4 @@ read_body(Req, AccData) -> {ok, <>, Req1}; {more, Data, Req1} -> read_body(Req1, <>) - end. \ No newline at end of file + end. diff --git a/src/http/network_handler.erl b/src/http/network_handler.erl new file mode 100644 index 0000000..ec49602 --- /dev/null +++ b/src/http/network_handler.erl @@ -0,0 +1,72 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2024, +%%% @doc +%%% +%%% @end +%%% Created : 09. 4月 2024 14:28 +%%%------------------------------------------------------------------- +-module(network_handler). +-author("anlicheng"). +-include_lib("sdlan_pb.hrl"). + +%% API +-export([handle_request/4]). + +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. +handle_request("POST", "/network/create", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> + case sdlan_network_sup:ensure_network_started(NetworkId) of + {ok, Pid} when is_pid(Pid) -> + {ok, 200, sdlan_util:json_data(<<"success">>)}; + {error, Reason} -> + logger:debug("[network_handler] create network: ~p, get error: ~p", [NetworkId, Reason]), + ReasonBin = sdlan_util:term_to_binary(Reason), + {ok, 200, sdlan_util:json_error(-1, <<"error: ", ReasonBin/binary>>)} + end; + +handle_request("POST", "/network/delete", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> + case sdlan_network:get_pid(NetworkId) of + undefined -> + {ok, 200, sdlan_util:json_data(<<"success">>)}; + NetworkPid when is_pid(NetworkPid) -> + case sdlan_network_sup:delete_network(NetworkId) of + ok -> + {ok, 200, sdlan_util:json_data(<<"success">>)}; + {error, Reason} -> + logger:debug("[network_handler] delete network: ~p, get error: ~p", [NetworkId, Reason]), + {ok, 200, sdlan_util:json_error(-1, <<"error">>)} + end + end; + +handle_request("POST", "/network/exit_node_control", _, #{<<"id">> := NetworkId, <<"action">> := Action, <<"client_id">> := ClientId, <<"remark">> := Remark, <<"timeout">> := Timeout}) when NetworkId > 0 -> + case sdlan_network:get_pid(NetworkId) of + undefined -> + {ok, 200, sdlan_util:json_data(<<"network not found">>)}; + NetworkPid when is_pid(NetworkPid) -> + ReceiverPid = self(), + SubCommand = {exit_node, #'SDLCommand.ExitNodeControl'{ + action = Action, + remark = Remark + }}, + case sdlan_network:command(NetworkPid, ReceiverPid, ClientId, SubCommand) of + {error, Reason} -> + {ok, 200, sdlan_util:json_error(-1, Reason)}; + {ok, Ref} -> + case sdlan_network:wait_command_ack(Ref, Timeout * 1000) of + {ok, #'SDLCommandAck'{code = Code, message = Message}} -> + case Code == 0 of + true -> + {ok, 200, sdlan_util:json_data(<<"success">>)}; + false -> + {ok, 200, sdlan_util:json_error(Code, Message)} + end; + {error, timeout} -> + {ok, 200, sdlan_util:json_error(-1, <<"任务执行超时"/utf8>>)} + end + end + end; + +handle_request(_, Path, _, _) -> + Path1 = list_to_binary(Path), + {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. diff --git a/src/http/node_handler.erl b/src/http/node_handler.erl new file mode 100644 index 0000000..58801d2 --- /dev/null +++ b/src/http/node_handler.erl @@ -0,0 +1,28 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2024, +%%% @doc +%%% +%%% @end +%%% Created : 09. 4月 2024 14:28 +%%%------------------------------------------------------------------- +-module(node_handler). +-author("anlicheng"). + +%% API +-export([handle_request/4]). + +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. +handle_request("POST", "/node/disable", _, #{<<"network_id">> := NetworkId, <<"client_id">> := ClientId}) when NetworkId > 0 -> + case sdlan_network:get_pid(NetworkId) of + undefined -> + {ok, 200, sdlan_util:json_error(-1, <<"network not found">>)}; + Pid -> + sdlan_network:disable_client(Pid, ClientId), + {ok, 200, sdlan_util:json_data(<<"success">>)} + end; + +handle_request(_, Path, _, _) -> + Path1 = list_to_binary(Path), + {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. diff --git a/src/http/sdlan_http_server.erl b/src/http/sdlan_http_server.erl new file mode 100644 index 0000000..2e755fc --- /dev/null +++ b/src/http/sdlan_http_server.erl @@ -0,0 +1,41 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 03. 5月 2026 15:06 +%%%------------------------------------------------------------------- +-module(sdlan_http_server). +-author("anlicheng"). + +%% API +-export([start/0]). + +%% 启动http服务 +-spec start() -> ok. +start() -> + {ok, Props} = application:get_env(sdlan, http_server), + Acceptors = proplists:get_value(acceptors, Props, 50), + MaxConnections = proplists:get_value(max_connections, Props, 10240), + Backlog = proplists:get_value(backlog, Props, 1024), + Port = proplists:get_value(port, Props), + + Dispatcher = cowboy_router:compile([ + {'_', [ + {"/api/[...]", http_protocol, [api_handler]}, + {"/binlog", http_protocol, [binlog_handler]}, + {"/network/[...]", http_protocol, [network_handler]}, + {"/node/[...]", http_protocol, [node_handler]}, + {"/test/[...]", http_protocol, [test_handler]} + ]} + ]), + + TransOpts = [ + {port, Port}, + {num_acceptors, Acceptors}, + {backlog, Backlog}, + {max_connections, MaxConnections} + ], + {ok, Pid} = cowboy:start_clear(http_listener, TransOpts, #{env => #{dispatch => Dispatcher}}), + logger:debug("[iot_app] the http server start at: ~p, pid is: ~p", [Port, Pid]). diff --git a/apps/sdlan/src/http_handler/test_handler.erl b/src/http/test_handler.erl similarity index 51% rename from apps/sdlan/src/http_handler/test_handler.erl rename to src/http/test_handler.erl index 5f81d5e..612d0d9 100644 --- a/apps/sdlan/src/http_handler/test_handler.erl +++ b/src/http/test_handler.erl @@ -17,27 +17,13 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 重新加载对应的主机信息 -handle_request("POST", "/test/auth_token", _, PostParams) -> - logger:debug("[test_handler] get post params: ~p", [PostParams]), - Data = #{ - <<"network_id">> => 8, - <<"upgrade_type">> => 0, - <<"upgrade_prompt">> => <<"simple upgrade">>, - <<"upgrade_address">> => <<"upgrade_address">> - }, - {ok, 200, sdlan_util:json_data(Data)}; - -handle_request("POST", "/test/upgrade", _, PostParams) -> - logger:debug("[test_handler] get post params: ~p", [PostParams]), - Data = #{ - <<"upgrade_type">> => 1, - <<"upgrade_prompt">> => <<"prompt需要升级"/utf8>>, - <<"upgrade_address">> => <<"macappstore://apps.apple.com/app/id836500024">> - }, - {ok, 200, sdlan_util:json_data(Data)}; +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. +handle_request("POST", "/test/auth_access_token", _, _PostParams) -> + {ok, 200, sdlan_util:json_data(<<"ok">>)}; handle_request("GET", "/test/get_all_networks", _, _) -> - {ok, 200, sdlan_util:json_data([8, 9, 10])}; + {ok, 200, sdlan_util:json_data([8])}; handle_request("GET", "/test/get_network", #{<<"id">> := Id0}, _) -> Id = binary_to_integer(Id0), @@ -45,22 +31,10 @@ handle_request("GET", "/test/get_network", #{<<"id">> := Id0}, _) -> 8 => #{ <<"id">> => 8, <<"name">> => <<"test1">>, + <<"domain">> => <<"punchnet.cn">>, <<"ipaddr">> => <<"10.211.179.0/24">>, <<"owner_id">> => 1234, - <<"disabled_clients">> => [] - }, - 9 => #{ - <<"id">> => 9, - <<"name">> => <<"test2">>, - <<"ipaddr">> => <<"10.211.180.0/24">>, - <<"owner_id">> => 1234, - <<"disabled_clients">> => [] - }, - 10 => #{ - <<"id">> => 10, - <<"name">> => <<"test3">>, - <<"ipaddr">> => <<"10.211.181.0/24">>, - <<"owner_id">> => 1234, + <<"algorithm">> => <<"chacha20">>, <<"disabled_clients">> => [] } }, @@ -74,4 +48,4 @@ handle_request(_, Path, _, _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% helper methods -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ No newline at end of file +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/ipv6_assist/ipv6_assist_server.erl b/src/ipv6_assist/ipv6_assist_server.erl new file mode 100644 index 0000000..75c2a5f --- /dev/null +++ b/src/ipv6_assist/ipv6_assist_server.erl @@ -0,0 +1,120 @@ +%%%------------------------------------------------------------------- +%%% @doc IPv6 UDP listener for connectivity checks. +%%% @end +%%%------------------------------------------------------------------- +-module(ipv6_assist_server). + +-include("sdlan.hrl"). +-include("sdlan_pb.hrl"). + +-behaviour(gen_server). + +%% API +-export([start_link/2]). +-export([get_name/1]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). + +-record(state, { + socket +}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec get_name(Id :: integer()) -> atom(). +get_name(Id) when is_integer(Id) -> + list_to_atom("ipv6_assistor_server:" ++ integer_to_list(Id)). + +-spec start_link(Name :: atom(), Port :: integer()) -> + {ok, Pid :: pid()} | ignore | {error, Reason :: term()}. +start_link(Name, Port) when is_atom(Name), is_integer(Port) -> + gen_server:start_link({local, Name}, ?MODULE, [Port], []). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +-spec init(Args :: term()) -> + {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | + {stop, Reason :: term()} | ignore. +init([Port]) -> + erlang:process_flag(priority, high), + Opts = [ + binary, + inet6, + {reuseaddr, true}, + {reuseport, true}, + {active, true}, + {recbuf, 5 * 1024 * 1024}, + {sndbuf, 5 * 1024 * 1024} + ], + {ok, Socket} = gen_udp:open(Port, Opts), + inet_udp:controlling_process(Socket, self()), + + logger:debug("[ipv6_assistor_server] start at port: ~p", [Port]), + {ok, #state{socket = Socket}}. + +-spec handle_call(Request :: term(), From :: {pid(), Tag :: term()}, + State :: #state{}) -> + {reply, Reply :: term(), NewState :: #state{}} | + {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | + {noreply, NewState :: #state{}} | + {noreply, NewState :: #state{}, timeout() | hibernate} | + {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | + {stop, Reason :: term(), NewState :: #state{}}. +handle_call(_Request, _From, State = #state{}) -> + {reply, ok, State}. + +-spec handle_cast(Request :: term(), State :: #state{}) -> + {noreply, NewState :: #state{}} | + {noreply, NewState :: #state{}, timeout() | hibernate} | + {stop, Reason :: term(), NewState :: #state{}}. +handle_cast(_Request, State) -> + {noreply, State}. + +-spec handle_info(Info :: timeout() | term(), State :: #state{}) -> + {noreply, NewState :: #state{}} | + {noreply, NewState :: #state{}, timeout() | hibernate} | + {stop, Reason :: term(), NewState :: #state{}}. +handle_info({udp, Sock, Ip, Port, Body}, State = #state{socket = Sock}) -> + maybe + ThrottleKey = {Ip, Port}, + ok ?= limit_check(ThrottleKey), + #'SDLV6AssistProbe'{pkt_id = PktId} ?= catch sdlan_pb:decode_msg(Body, 'SDLV6AssistProbe'), + V6Bytes = sdlan_util:ipv6_to_bytes(Ip), + ReplyBin = sdlan_pb:encode_msg(#'SDLV6AssistProbeReply'{ + pkt_id = PktId, + v6_info = #'SDLV6Info'{ + v6 = V6Bytes, + port = Port + } + }), + ok ?= gen_udp:send(Sock, Ip, Port, ReplyBin) + end, + {noreply, State}; +handle_info(_Info, State) -> + {noreply, State}. + +-spec terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), + State :: #state{}) -> term(). +terminate(_Reason, _State = #state{}) -> + ok. + +-spec code_change(OldVsn :: term() | {down, term()}, State :: #state{}, + Extra :: term()) -> + {ok, NewState :: #state{}} | {error, Reason :: term()}. +code_change(_OldVsn, State = #state{}, _Extra) -> + {ok, State}. + +%% 访问频率限制 +-spec limit_check(ThrottleKey :: any()) -> ok | limited. +limit_check(ThrottleKey) -> + case throttle:check(sdlan_ipv6_assist, ThrottleKey) of + {ok, _RestCount, _LeftToReset} -> + ok; + {limit_exceeded, 0, _LeftToReset} -> + limited + end. \ No newline at end of file diff --git a/src/ipv6_assist/ipv6_assist_server_sup.erl b/src/ipv6_assist/ipv6_assist_server_sup.erl new file mode 100644 index 0000000..3f73ed8 --- /dev/null +++ b/src/ipv6_assist/ipv6_assist_server_sup.erl @@ -0,0 +1,39 @@ +%%%------------------------------------------------------------------- +%% @doc ipv6_assist top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(ipv6_assist_server_sup). + +-behaviour(supervisor). + +-export([start_link/0]). +-export([init/1]). + +-define(SERVER, ?MODULE). + +-spec start_link() -> supervisor:startlink_ret(). +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. +init([]) -> + SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, + {ok, Props} = application:get_env(sdlan, ipv6_assist), + Port = proplists:get_value(port, Props, 1367), + AcceptorNum = proplists:get_value(acceptor_nums, Props, 5), + + Specs = lists:map(fun(Id) -> + Name = ipv6_assist_server:get_name(Id), + #{ + id => Name, + start => {ipv6_assist_server, start_link, [Name, Port]}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['ipv6_assist_server'] + } + end, lists:seq(1, AcceptorNum)), + {ok, {SupFlags, Specs}}. diff --git a/apps/sdlan/src/model/network_bo.erl b/src/model/network_bo.erl similarity index 100% rename from apps/sdlan/src/model/network_bo.erl rename to src/model/network_bo.erl diff --git a/apps/sdlan/src/mysql/mysql_pool.erl b/src/mysql/mysql_pool.erl similarity index 100% rename from apps/sdlan/src/mysql/mysql_pool.erl rename to src/mysql/mysql_pool.erl diff --git a/apps/sdlan/src/mysql/mysql_provider.erl b/src/mysql/mysql_provider.erl similarity index 100% rename from apps/sdlan/src/mysql/mysql_provider.erl rename to src/mysql/mysql_provider.erl diff --git a/src/policy/identity_policy_ets.erl b/src/policy/identity_policy_ets.erl new file mode 100644 index 0000000..de69c9a --- /dev/null +++ b/src/policy/identity_policy_ets.erl @@ -0,0 +1,33 @@ +-module(identity_policy_ets). +-include("policy.hrl"). + +-export([init/0]). +-export([get_policies/1, insert/1, delete/1, update/2]). + +-spec init() -> ets:tab(). +init() -> + ets:new(identity_policy, [named_table, bag, public, {keypos, 2}, {read_concurrency, true}]). + +-spec get_policies(IdentityId :: integer()) -> [PolicyId :: integer()]. +get_policies(IdentityId) when is_integer(IdentityId) -> + Records = ets:lookup(identity_policy, IdentityId), + lists:map(fun(#identity_policy{policy_id = PolicyId}) -> PolicyId end, Records). + +-spec insert(map() | #identity_policy{}) -> true. +insert(#{<<"identity_id">> := IdentityId, <<"policy_id">> := PolicyId}) -> + insert(#identity_policy{identity_id = IdentityId, policy_id = PolicyId}); +insert(IdentityPolicy=#identity_policy{}) -> + true = ets:insert(identity_policy, IdentityPolicy). + +-spec delete(map() | #identity_policy{}) -> true. +delete(#{<<"identity_id">> := IdentityId, <<"policy_id">> := PolicyId}) -> + ets:delete_object(identity_policy, #identity_policy{identity_id = IdentityId, policy_id = PolicyId}); +delete(IdentityPolicy = #identity_policy{}) -> + true = ets:delete_object(identity_policy, IdentityPolicy). + +-spec update(NewData :: map(), OldData :: map()) -> true. +update(NewData=#{<<"identity_id">> := IdentityId, <<"policy_id">> := PolicyId}, OldData) -> + %% 清理老的数据 + #{<<"identity_id">> := OldIdentityId, <<"policy_id">> := OldPolicyId} = maps:merge(NewData, OldData), + ets:delete_object(identity_policy, #identity_policy{identity_id = OldIdentityId, policy_id = OldPolicyId}), + ets:insert(identity_policy, #identity_policy{identity_id = IdentityId, policy_id = PolicyId}). diff --git a/src/policy/maxwell_redis_channel.erl b/src/policy/maxwell_redis_channel.erl new file mode 100644 index 0000000..4b8adb6 --- /dev/null +++ b/src/policy/maxwell_redis_channel.erl @@ -0,0 +1,143 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 28. 2月 2026 22:07 +%%%------------------------------------------------------------------- +-module(maxwell_redis_channel). +-author("licheng5"). +-include("policy.hrl"). + +%% API +-export([start/1, loop/1]). + +-record(command, { + data = <<>>, + stage = parse_arg_num, + arg_num = 0, + args = [] +}). + +-record(state, { + socket, + command +}). + +%%-------------------------------------------------------------------- +%% esockd callback +%%-------------------------------------------------------------------- + +-spec start(Socket :: inet:socket()) -> pid(). +start(Socket) -> + spawn(?MODULE, loop, [#state{socket = Socket, command = #command{}}]). + +-spec loop(State :: #state{}) -> no_return(). +loop(State=#state{socket = Socket, command = Command = #command{data = Data}}) -> + inet:setopts(Socket, [{active, once}]), + receive + {tcp, _, Packet} -> + NData = <>, + case parse(Command#command{data = NData}) of + {ok, #command{args = Args}} -> + {reply, Reply} = handle_command(Args), + gen_tcp:send(Socket, Reply), + loop(State#state{command = #command{}}); + {more_data, NCommand} -> + %% 请求的数据包过大,一次接受不完整 + loop(State#state{command = NCommand}) + end; + {tcp_error, _} -> + exit(normal); + {tcp_closed, _} -> + logger:debug("[maxwell_redis_channel] channel closed"), + exit(normal) + end. + +%% PING命令 +handle_command([<<"PING">>]) -> + {reply, encode({single_line, <<"PONG">>})}; + +handle_command([<<"PUBLISH">>, _Channel, Msg]) -> + case catch json:decode(Msg) of + M when is_map(M) -> + handle_data(M); + _ -> + ok + end, + {reply, encode(1)}; + +handle_command(_) -> + {reply, encode({error, <<"Unsuported Command">>})}. + +handle_data(#{<<"database">> := <<"punchnet_v2">>, <<"table">> := <<"identity_policy">>, <<"type">> := <<"insert">>, <<"data">> := Data}) -> + identity_policy_ets:insert(Data); +handle_data(#{<<"database">> := <<"punchnet_v2">>, <<"table">> := <<"identity_policy">>, <<"type">> := <<"delete">>, <<"data">> := Data}) -> + identity_policy_ets:delete(Data); +handle_data(#{<<"database">> := <<"punchnet_v2">>, <<"table">> := <<"identity_policy">>, <<"type">> := <<"update">>, <<"data">> := Data, <<"old">> := Old}) -> + identity_policy_ets:update(Data, Old); +%% 处理rule +handle_data(#{<<"database">> := <<"punchnet_v2">>, <<"table">> := <<"rule">>, <<"type">> := <<"insert">>, <<"data">> := Data}) -> + rule_ets:insert(Data); +handle_data(#{<<"database">> := <<"punchnet_v2">>, <<"table">> := <<"rule">>, <<"type">> := <<"delete">>, <<"data">> := Data}) -> + rule_ets:delete(Data); +handle_data(#{<<"database">> := <<"punchnet_v2">>, <<"table">> := <<"rule">>, <<"type">> := <<"update">>, <<"data">> := Data, <<"old">> := Old}) -> + rule_ets:update(Data, Old); +handle_data(_Json) -> + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% helper methods +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% 解析请求的包, 支持请求不在一个包里面的情况, 基于状态机 +parse(Command = #command{stage = parse_arg_num, data = <<$*, Rest/binary>>}) -> + case binary:split(Rest, <<$\r, $\n>>) of + [ArgNum0, ArgBin] -> + ArgNum = binary_to_integer(ArgNum0), + parse(Command#command{arg_num = ArgNum, data = ArgBin, stage = parse_arg}); + _ -> + {more_data, Command} + end; +%% 解析请求的参数 +parse(Command = #command{stage = parse_arg, args = Args, arg_num = 0, data = <<>>}) -> + {ok, Command#command{args = lists:reverse(Args)}}; +parse(Command = #command{stage = parse_arg, args = Args, arg_num = ArgNum, data = ArgBin}) -> + case binary:split(ArgBin, <<$\r, $\n>>) of + [<<"$", ArgLen0/binary>>, RestArgBin] -> + ArgLen = binary_to_integer(ArgLen0), + case RestArgBin of + <> -> + parse(Command#command{arg_num = ArgNum - 1, args = [Arg | Args], data = RestArgBin1}); + _ -> + {more_data, Command} + end; + _ -> + {more_data, Command} + end. + +%% redis数据返回格式化 +-spec encode(tuple() | binary() | integer() | list()) -> iolist(). +encode({single_line, Arg}) when is_binary(Arg) -> + [<<$+>>, Arg, <<$\r, $\n>>]; +encode({error, Arg}) when is_binary(Arg) -> + [<<$->>, Arg, <<$\r, $\n>>]; +encode(Arg) when is_integer(Arg) -> + [<<$:>>, integer_to_list(Arg), <<$\r, $\n>>]; +encode(Arg) when is_binary(Arg) -> + [<<$$>>, integer_to_list(iolist_size(Arg)), <<$\r, $\n>>, Arg, <<$\r, $\n>>]; +encode(Args) when is_list(Args) -> + ArgCount = [<<$*>>, integer_to_list(length(Args)), <<$\r, $\n>>], + ArgsBin = lists:map(fun encode/1, lists:map(fun to_binary/1, Args)), + [ArgCount, ArgsBin]. + +%% 将数据转换成binary +to_binary(X) when is_list(X) -> + unicode:characters_to_binary(X); +to_binary(X) when is_atom(X) -> + list_to_binary(atom_to_list(X)); +to_binary(X) when is_binary(X) -> + X; +to_binary(X) when is_integer(X) -> + list_to_binary(integer_to_list(X)). diff --git a/src/policy/maxwell_redis_server.erl b/src/policy/maxwell_redis_server.erl new file mode 100644 index 0000000..bc6ff4f --- /dev/null +++ b/src/policy/maxwell_redis_server.erl @@ -0,0 +1,47 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 28. 2月 2026 22:07 +%%%------------------------------------------------------------------- +-module(maxwell_redis_server). +-author("licheng5"). + +%% API +-export([start_link/1, init/1]). + +%%-------------------------------------------------------------------- +%% esockd callback +%%-------------------------------------------------------------------- + +-spec start_link(Port :: inet:port_number()) -> {ok, pid()}. +start_link(Port) when is_integer(Port) -> + {ok, spawn_link(?MODULE, init, [Port])}. + +-spec init(Port :: inet:port_number()) -> no_return(). +init(Port) -> + {ok, LSocket} = gen_tcp:listen(Port, [ + binary, + {packet, 0}, + {reuseaddr, true}, + {backlog, 1024}, + {active, false} + ]), + accept_loop(LSocket). + +accept_loop(LSocket) -> + case gen_tcp:accept(LSocket) of + {ok, Socket} -> + logger:debug("accept socket: ~p", [Socket]), + %% 每个连接一个进程 + Pid = maxwell_redis_channel:start(Socket), + ok = gen_tcp:controlling_process(Socket, Pid), + accept_loop(LSocket); + {error, closed} -> + exit(tcp_closed); + {error, Reason} -> + logger:debug("[maxwell_redis_server] Accept error: ~p~n", [Reason]), + accept_loop(LSocket) + end. diff --git a/src/policy/rule_ets.erl b/src/policy/rule_ets.erl new file mode 100644 index 0000000..f3c8c85 --- /dev/null +++ b/src/policy/rule_ets.erl @@ -0,0 +1,78 @@ +-module(rule_ets). +-include("policy.hrl"). + +-export([init/0]). +-export([insert/1, get_rules/2, delete/1, update/2]). + +-spec init() -> ets:tab(). +init() -> + ets:new(rule_table, [named_table, ordered_set, public, {keypos, 2}, {read_concurrency, true}]), + ets:new(rule_index, [named_table, bag, public, {read_concurrency, true}]). + +-spec get_rules(SrcPolicyIds :: any(), DstPolicyIds :: any()) -> {ok, [{Proto :: integer(), Port :: integer()}]}. +get_rules(SrcPolicyIds, DstPolicyIds) when is_list(SrcPolicyIds), is_list(DstPolicyIds) -> + MatchKeys = [{S, D, '_'} || S <- SrcPolicyIds, D <- DstPolicyIds], + Records = lists:flatmap(fun({S, D, _}) -> ets:match_object(rule_index, {S, D, '_'}) end, MatchKeys), + Rules = lists:flatmap(fun({_, _, RuleId}) -> ets:lookup(rule_table, RuleId) end, Records), + + S = lists:foldl(fun(Rule, S) -> + case Rule of + #rule{action = allow, proto = Proto, port = Port} -> + sets:add_element({Proto, Port}, S); + _ -> + S + end + end, sets:new(), Rules), + + {ok, sets:to_list(S)}. + +-spec insert(Data :: map()) -> true. +insert(#{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId, + <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId, <<"proto">> := Proto, + <<"port">> := Port, <<"action">> := Action, <<"created_at">> := CreatedAt}) -> + Rule = #rule{ + rule_id = RuleId, + network_id = NetworkId, + src_policy_id = SrcPolicyId, + dst_policy_id = DstPolicyId, + proto = Proto, + port = Port, + action = format_action(Action), + created_at = CreatedAt + }, + ets:insert(rule_table, Rule), + ets:insert(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). + +-spec update(NewData :: map(), OldData :: map()) -> true. +update(NewData = #{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId, + <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId, <<"proto">> := Proto, + <<"port">> := Port, <<"action">> := Action, <<"created_at">> := CreatedAt}, OldData) -> + + %% rule_id是主键,直接覆盖 + Rule = #rule{ + rule_id = RuleId, + network_id = NetworkId, + src_policy_id = SrcPolicyId, + dst_policy_id = DstPolicyId, + proto = Proto, + port = Port, + action = format_action(Action), + created_at = CreatedAt + }, + ets:insert(rule_table, Rule), + %% index老的数据可能要清理掉, 用就的数据覆盖新的数据,得到的是Old的Record + #{<<"src_policy_id">> := OldSrcPolicyId, <<"dst_policy_id">> := OldDstPolicyId} = maps:merge(NewData, OldData), + ets:delete_object(rule_index, {OldSrcPolicyId, OldDstPolicyId, RuleId}), + %% 建立信息的索引 + ets:insert(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). + +-spec delete(Data :: map()) -> true. +delete(#{<<"rule_id">> := RuleId, <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId}) -> + ets:delete(rule_table, RuleId), + ets:delete_object(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). + +-spec format_action(binary()) -> atom(). +format_action(<<"allow">>) -> + allow; +format_action(_) -> + deny. diff --git a/src/quic/sdlan_quic_channel.erl b/src/quic/sdlan_quic_channel.erl new file mode 100644 index 0000000..8cc3cb1 --- /dev/null +++ b/src/quic/sdlan_quic_channel.erl @@ -0,0 +1,48 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% Compatibility facade for the QUIC channel API. +%%% @end +%%%------------------------------------------------------------------- +-module(sdlan_quic_channel). +-author("anlicheng"). + +%% API +-export([start_link/2]). +-export([accept_stream/1, send_event/2, command/4, stop/2, debug_info/1]). +-export([test_rules/2]). + +%%%=================================================================== +%%% API +%%%=================================================================== + +%% 测试规则函数 +-spec test_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> binary(). +test_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) -> + sdlan_session:test_rules(SrcIdentityId, DstIdentityId). + +-spec send_event(Pid :: pid(), Event :: binary()) -> ok. +send_event(Pid, ProtobufEvent) when is_pid(Pid), is_binary(ProtobufEvent) -> + sdlan_quic_transport:send_event(Pid, ProtobufEvent). + +-spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> ok. +command(Pid, Ref, ReceiverPid, SubCommand) when is_pid(Pid), is_pid(ReceiverPid) -> + sdlan_quic_transport:command(Pid, Ref, ReceiverPid, SubCommand). + +-spec accept_stream(Pid :: pid()) -> ok. +accept_stream(Pid) when is_pid(Pid) -> + sdlan_quic_transport:accept_stream(Pid). + +-spec stop(Pid :: pid(), Reason :: term()) -> ok. +stop(Pid, Reason) when is_pid(Pid) -> + sdlan_quic_transport:stop(Pid, Reason). + +-spec debug_info(Pid :: pid()) -> map(). +debug_info(Pid) when is_pid(Pid) -> + sdlan_quic_transport:debug_info(Pid). + +%% @doc Creates a transport process. Kept for existing supervisor specs. +-spec start_link(Conn :: quicer:connection_handle(), Limits :: proplists:proplist()) -> gen_statem:start_ret(). +start_link(Conn, Limits) when is_list(Limits) -> + sdlan_quic_transport:start_link(Conn, Limits). diff --git a/apps/sdlan/src/dns_proxy/dns_handler_sup.erl b/src/quic/sdlan_quic_channel_sup.erl similarity index 67% rename from apps/sdlan/src/dns_proxy/dns_handler_sup.erl rename to src/quic/sdlan_quic_channel_sup.erl index 009395d..345ed63 100644 --- a/apps/sdlan/src/dns_proxy/dns_handler_sup.erl +++ b/src/quic/sdlan_quic_channel_sup.erl @@ -1,22 +1,22 @@ %%%------------------------------------------------------------------- %%% @author anlicheng -%%% @copyright (C) 2025, +%%% @copyright (C) 2026, %%% @doc %%% %%% @end -%%% Created : 03. 12月 2025 17:29 +%%% Created : 13. 2月 2026 18:00 %%%------------------------------------------------------------------- --module(dns_handler_sup). +-module(sdlan_quic_channel_sup). -author("anlicheng"). -behaviour(supervisor). %% API -export([start_link/0]). +-export([start_channel/2]). %% Supervisor callbacks -export([init/1]). --export([start_handler/0]). -define(SERVER, ?MODULE). @@ -38,29 +38,26 @@ start_link() -> %% this function is called by the new process to find out about %% restart strategy, maximum restart frequency and child %% specifications. +-spec(init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore). init([]) -> SupFlags = #{strategy => simple_one_for_one, intensity => 0, period => 1}, - Spec = #{ - id => dns_handler, - start => {'dns_handler', start_link, []}, + + AChild = #{ + id => sdlan_quic_transport, + start => {'sdlan_quic_transport', start_link, []}, restart => temporary, shutdown => 2000, type => worker, - modules => ['dns_handler'] + modules => ['sdlan_quic_transport'] }, - - {ok, {SupFlags, [Spec]}}. + {ok, {SupFlags, [AChild]}}. %%%=================================================================== %%% Internal functions %%%=================================================================== -start_handler() -> - case supervisor:start_child(?MODULE, []) of - {ok, Pid} -> - {ok, Pid}; - {error, {already_started, Pid}} -> - {ok, Pid}; - StartError -> - StartError - end. \ No newline at end of file +-spec start_channel(NConn :: quicer:connection_handle(), Limits :: proplists:proplist()) -> supervisor:startchild_ret(). +start_channel(NConn, Limits) when is_list(Limits) -> + supervisor:start_child(?MODULE, [NConn, Limits]). diff --git a/src/quic/sdlan_quic_server.erl b/src/quic/sdlan_quic_server.erl new file mode 100644 index 0000000..a59a70b --- /dev/null +++ b/src/quic/sdlan_quic_server.erl @@ -0,0 +1,93 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 11. 2月 2026 21:26 +%%%------------------------------------------------------------------- +-module(sdlan_quic_server). +-author("anlicheng"). + +%% API +-export([start_link/0, init/0]). + +-spec start_link() -> {ok, pid()}. +start_link() -> + {ok, spawn_link(?MODULE, init, [])}. + +-spec init() -> ok. +init() -> + process_flag(trap_exit, true), + {ok, Props} = application:get_env(sdlan, quic_server), + Port = proplists:get_value(port, Props), + Alpn = proplists:get_value(alpn, Props), + Limits = proplists:get_value(limits, Props), + AcceptorCount = proplists:get_value(acceptors, Props, 10), + + %% 证书配置 + {CertFile, KeyFile} = sdlan_util:certificate_config(), + + LOptions = #{ + % 必选:QUIC/TLS证书配置 + certfile => CertFile, + keyfile => KeyFile, + alpn => Alpn, + peer_bidi_stream_count => 1, + conn_acceptors => AcceptorCount + }, + ListenAddr = "0.0.0.0:" ++ integer_to_list(Port), + case quicer:listen(ListenAddr, LOptions) of + {ok, L} -> + logger:notice("[sdlan_quic_server] listen on ~s, acceptors: ~p", [ListenAddr, AcceptorCount]), + Pids = [spawn_link(fun() -> loop_accept(L, Limits, I) end) || I <- lists:seq(1, AcceptorCount)], + wait_acceptors(L, Pids); + Error -> + exit(Error) + end. + +wait_acceptors(L, Pids) -> + receive + {'EXIT', Pid, Reason} -> + logger:warning("[sdlan_quic_server] acceptor ~p exit with reason: ~p", [Pid, Reason]), + quicer:close_listener(L), + exit({acceptor_exit, Pid, Reason, Pids}); + stop -> + quicer:close_listener(L), + ok; + Info -> + logger:notice("[sdlan_quic_server] get unexpected info: ~p", [Info]), + wait_acceptors(L, Pids) + end. + +loop_accept(L, Limits, AcceptorId) -> + case quicer:accept(L, #{}, infinity) of + {ok, Conn} -> + logger:debug("[sdlan_quic_server] acceptor: ~p, accept a new connection: ~p", [AcceptorId, Conn]), + case quicer:handshake(Conn) of + {ok, NConn} -> + case sdlan_quic_channel_sup:start_channel(NConn, Limits) of + {ok, ChannelPid} -> + logger:debug("[sdlan_quic_server] conn: ~p, handshake success, channel pid: ~p", [NConn, ChannelPid]), + case quicer:controlling_process(NConn, ChannelPid) of + ok -> + sdlan_quic_transport:accept_stream(ChannelPid); + {error, Reason} -> + logger:warning("[sdlan_quic_server] conn: ~p, controlling_process failed: ~p", [NConn, Reason]), + sdlan_quic_transport:stop(ChannelPid, {controlling_process_failed, Reason}), + quicer:close_connection(NConn) + end; + Error -> + quicer:close_connection(NConn), + logger:notice("[sdlan_quic_server] start channel get error: ~p", [Error]) + end, + loop_accept(L, Limits, AcceptorId); + {error, Reason} -> + logger:debug("[sdlan_quic_server] acceptor: ~p, handshake failed: ~p", [AcceptorId, Reason]), + quicer:close_connection(Conn), + loop_accept(L, Limits, AcceptorId) + end; + {error, Reason} -> + logger:debug("[sdlan_quic_server] acceptor: ~p, accept failed: ~p", [AcceptorId, Reason]), + loop_accept(L, Limits, AcceptorId) + end. diff --git a/src/quic/sdlan_quic_transport.erl b/src/quic/sdlan_quic_transport.erl new file mode 100644 index 0000000..6ed166f --- /dev/null +++ b/src/quic/sdlan_quic_transport.erl @@ -0,0 +1,301 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% QUIC transport for sdlan sessions. +%%% @end +%%%------------------------------------------------------------------- +-module(sdlan_quic_transport). +-author("anlicheng"). +-include("sdlan.hrl"). +-include("sdlan_pb.hrl"). + +-behaviour(gen_statem). + +%% 心跳包监测机制 +-define(STREAM_ACTIVE_N, 100). + +%% API +-export([start_link/2]). +-export([accept_stream/1, send_event/2, command/4, stop/2, debug_info/1]). + +%% gen_statem callbacks +-export([init/1, handle_event/4, terminate/3, code_change/4, callback_mode/0]). + +-record(state, { + conn :: quicer:connection_handle(), + %% 最大包大小 + max_packet_size = 16384, + %% 心跳间隔 + heartbeat_sec = 15, + stream_active_n = ?STREAM_ACTIVE_N, + + stream :: undefined | quicer:stream_handle(), + %% 累积器,用于处理协议framing的解析 + buf = <<>>, + + session :: sdlan_session:session(), + + close_reason = undefined +}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec send_event(Pid :: pid(), Event :: binary()) -> ok. +send_event(Pid, ProtobufEvent) when is_pid(Pid), is_binary(ProtobufEvent) -> + gen_statem:cast(Pid, {send_event, ProtobufEvent}). + +-spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> ok. +command(Pid, Ref, ReceiverPid, SubCommand) when is_pid(Pid), is_pid(ReceiverPid) -> + gen_statem:cast(Pid, {command, Ref, ReceiverPid, SubCommand}). + +-spec accept_stream(Pid :: pid()) -> ok. +accept_stream(Pid) when is_pid(Pid) -> + gen_statem:cast(Pid, accept_stream). + +-spec stop(Pid :: pid(), Reason :: term()) -> ok. +stop(Pid, Reason) when is_pid(Pid) -> + gen_statem:stop(Pid, Reason, 2000). + +-spec debug_info(Pid :: pid()) -> map(). +debug_info(Pid) when is_pid(Pid) -> + gen_statem:call(Pid, debug_info). + +%% @doc Creates a gen_statem process which calls Module:init/1 to +%% initialize. To ensure a synchronized start-up procedure, this +%% function does not return until Module:init/1 has returned. +-spec start_link(Conn :: quicer:connection_handle(), Limits :: proplists:proplist()) -> gen_statem:start_ret(). +start_link(Conn, Limits) when is_list(Limits) -> + gen_statem:start_link(?MODULE, [Conn, Limits], []). + +%%%=================================================================== +%%% gen_statem callbacks +%%%=================================================================== + +%% @private +%% @doc Whenever a gen_statem is started using gen_statem:start/[3,4] or +%% gen_statem:start_link/[3,4], this function is called by the new +%% process to initialize. +-spec init(Args :: term()) -> gen_statem:init_result(atom(), #state{}). +init([Conn, Limits]) -> + MaxPacketSize = proplists:get_value(max_packet_size, Limits, 16384), + HeartbeatSec = proplists:get_value(heartbeat_sec, Limits, 15), + StreamActiveN = proplists:get_value(stream_active_n, Limits, ?STREAM_ACTIVE_N), + Session = sdlan_session:new(HeartbeatSec, ?MODULE), + {ok, initializing, #state{ + conn = Conn, + max_packet_size = MaxPacketSize, + heartbeat_sec = HeartbeatSec, + stream_active_n = StreamActiveN, + session = Session + }}. + +%% @private +%% @doc This function is called by a gen_statem when it needs to find out +%% the callback mode of the callback module. +-spec callback_mode() -> gen_statem:callback_mode_result(). +callback_mode() -> + handle_event_function. + +%% @private +%% @doc If callback_mode is handle_event_function, then whenever a +%% gen_statem receives an event from call/2, cast/2, or as a normal +%% process message, this function is called. + +-spec handle_event(EventType :: gen_statem:event_type(), EventContent :: term(), + StateName :: atom(), State :: #state{}) -> gen_statem:event_handler_result(atom(), #state{}). +handle_event(cast, accept_stream, initializing, State = #state{conn = Conn, stream_active_n = StreamActiveN}) -> + logger:debug("[sdlan_quic_transport] call do_init of conn: ~p", [Conn]), + case quicer:async_accept_stream(Conn, #{active => StreamActiveN}) of + {ok, _} -> + {next_state, waiting_stream, State}; + {error, Reason} -> + {stop, {accept_stream_failed, Reason}, State} + end; + +%% 处理收到的quic消息 +handle_event(info, {quic, dgram_state_changed, Conn, Opts = #{dgram_send_enabled := true}}, _, State = #state{conn = Conn}) -> + logger:debug("[sdlan_quic_transport] dgram_state_changed, opts: ~p", [Opts]), + {keep_state, State}; + +handle_event(info, {quic, new_stream, Stream, Opts}, waiting_stream, State = #state{max_packet_size = MaxPacketSize, heartbeat_sec = HeartbeatSec}) -> + logger:debug("[sdlan_quic_transport] call new_stream: ~p, opts: ~p", [Stream, Opts]), + %% 发送欢迎消息 + quic_send(Stream, sdlan_session:welcome_packet(MaxPacketSize, HeartbeatSec)), + logger:debug("[sdlan_quic_transport] get stream: ~p, send welcome", [Stream]), + + {next_state, initialized, State#state{stream = Stream}}; + +handle_event(info, {quic, new_stream, Stream, Opts}, _StateName, State) -> + logger:warning("[sdlan_quic_transport] reject unexpected stream: ~p, opts: ~p", [Stream, Opts]), + quicer:close_stream(Stream, 1000), + {keep_state, State}; + +handle_event(info, {quic, stream_closed, Stream, Props}, _StateName, State = #state{stream = Stream}) -> + expected_stop({stream_closed, Props}, State); + +handle_event(info, {quic, peer_send_shutdown, Stream, _Props}, _StateName, State = #state{stream = Stream}) -> + expected_stop(peer_send_shutdown, State); + +handle_event(info, {quic, peer_send_aborted, Stream, ErrorCode}, _StateName, State = #state{stream = Stream}) -> + expected_stop({peer_send_aborted, ErrorCode}, State); + +handle_event(info, {quic, peer_receive_aborted, Stream, ErrorCode}, _StateName, State = #state{stream = Stream}) -> + expected_stop({peer_receive_aborted, ErrorCode}, State); + +handle_event(info, {quic, send_shutdown_complete, Stream, _Props}, _StateName, State = #state{stream = Stream}) -> + expected_stop(connection_shutdown, State); + +handle_event(info, {quic, passive, Stream, _Props}, _StateName, State = #state{stream = Stream, stream_active_n = StreamActiveN}) -> + ok = quicer:setopt(Stream, active, StreamActiveN), + {keep_state, State}; + +handle_event(info, {quic, closed, Conn, Props}, _StateName, State = #state{conn = Conn}) -> + expected_stop({connection_closed, Props}, State); + +handle_event(info, {quic, transport_shutdown, Conn, Props}, _StateName, State = #state{conn = Conn}) -> + expected_stop({transport_shutdown, Props}, State); + +handle_event(info, {quic, shutdown, Conn, ErrorCode}, _StateName, State = #state{conn = Conn}) -> + expected_stop({connection_shutdown_by_peer, ErrorCode}, State); + +%% 处理quicer相关的信息, 需要转换成内部能够识别的frame消息 +handle_event(info, {quic, Data, Stream, _Props}, _StateName, + State = #state{stream = Stream, buf = Buf, max_packet_size = MaxPacketSize}) when is_binary(Data) -> + case decode_frames(<>, MaxPacketSize) of + {error, Reason} -> + {stop, Reason, State}; + {ok, NBuf, Frames} -> + Actions = [{next_event, internal, {frame, Frame}} || Frame <- Frames], + {keep_state, State#state{buf = NBuf}, Actions} + end; + +%% 处理内部的包消息 +handle_event(internal, {frame, Frame}, _StateName, State = #state{stream = Stream, session = Session}) -> + case sdlan_session:handle_frame(Frame, Session) of + {ok, NStateName, NSession, Packets} -> + quic_send(Stream, Packets), + {next_state, NStateName, State#state{session = NSession}}; + {stop, Reason, _NStateName, NSession, Packets} -> + quic_send(Stream, Packets), + {stop, Reason, State#state{session = NSession}} + end; + +handle_event(info, {timeout, TimerRef, ping_ticker}, _StateName, State = #state{session = Session}) -> + case sdlan_session:handle_timeout(TimerRef, Session) of + {ok, NStateName, NSession} -> + {next_state, NStateName, State#state{session = NSession}}; + {stop, Reason, _NStateName, NSession} -> + expected_stop(Reason, State#state{session = NSession}) + end; + +%% 发送指令信息 +handle_event(cast, {send_event, Event}, _StateName, State = #state{stream = Stream, session = Session}) -> + case sdlan_session:send_event(Event, Session) of + {ok, NStateName, NSession, Packets} -> + quic_send(Stream, Packets), + {next_state, NStateName, State#state{session = NSession}}; + {error, not_registered} -> + keep_state_and_data + end; + +%% 发送命令信息 +handle_event(cast, {command, Ref, ReceiverPid, SubCommand}, _StateName, State = #state{stream = Stream, session = Session}) -> + case sdlan_session:command(Ref, ReceiverPid, SubCommand, Session) of + {ok, NStateName, NSession, Packets} -> + quic_send(Stream, Packets), + {next_state, NStateName, State#state{session = NSession}}; + {error, not_registered} -> + keep_state_and_data + end; + +handle_event({call, From}, debug_info, StateName, State) -> + {keep_state, State, [{reply, From, debug_info(StateName, State)}]}; + +handle_event(info, {'EXIT', _, _}, _StateName, State) -> + expected_stop(connection_closed, State); + +handle_event(EventType, Info, StateName, State) -> + logger:notice("[sdlan_quic_transport] state: ~p, state_name: ~p, event_type: ~p, info: ~p", [State, StateName, EventType, Info]), + keep_state_and_data. + +%% @private +%% @doc This function is called by a gen_statem when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any +%% necessary cleaning up. When it returns, the gen_statem terminates with +%% Reason. The return value is ignored. +-spec terminate(Reason :: term(), StateName :: atom(), State :: #state{}) -> ok. +terminate(Reason, _StateName, _State = #state{conn = Conn, stream = Stream, session = Session, close_reason = CloseReason}) -> + Stream /= undefined andalso quicer:close_stream(Stream, 1000), + quicer:close_connection(Conn), + logger:notice("[sdlan_quic_transport] terminate closed with reason: ~p, close_reason: ~p", [Reason, CloseReason]), + sdlan_session:close(Session), + ok. + +%% @private +%% @doc Convert process state when code is changed +-spec code_change(OldVsn :: term(), StateName :: atom(), State :: #state{}, Extra :: term()) -> + {ok, atom(), #state{}}. +code_change(_OldVsn, StateName, State = #state{}, _Extra) -> + {ok, StateName, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +%% 有2种情况 +%% 1. 收到了多个完整的请求 +%% 2. 不完整,则不处理 +-spec decode_frames(Buf :: binary(), MaxPacketSize :: integer()) -> {ok, RestBin::binary(), Frames :: list()} | {error, Reason :: any()}. +decode_frames(Buf, MaxPacketSize) when is_binary(Buf) -> + decode_frames0(Buf, MaxPacketSize, []). +decode_frames0(<>, MaxPacketSize, _Frames) when Len > MaxPacketSize -> + {error, frame_too_large}; +decode_frames0(<>, MaxPacketSize, Frames) -> + decode_frames0(Rest, MaxPacketSize, [Frame|Frames]); +decode_frames0(Rest, _MaxPacketSize, Frames) -> + {ok, Rest, lists:reverse(Frames)}. + +-spec quic_send(Stream :: quicer:stream_handle(), Data :: iodata()) -> ok. +quic_send(_Stream, []) -> + ok; +quic_send(Stream, Data) -> + Len = iolist_size(Data), + true = Len =< 65535, + case quicer:send(Stream, [<>, Data]) of + {ok, _} -> + incr_counter(quic_frames_sent, 1), + incr_counter(quic_bytes_sent, Len + 2), + ok; + {error, Reason} -> + exit({quic_send_failed, Reason}) + end. + +expected_stop(Reason, State) -> + logger:notice("[sdlan_quic_transport] expected close: ~p", [Reason]), + {stop, normal, State#state{close_reason = Reason}}. + +debug_info(StateName, #state{session = Session, stream_active_n = StreamActiveN, heartbeat_sec = HeartbeatSec}) -> + ProcInfo = maps:from_list(process_info(self(), [message_queue_len, memory, reductions])), + SessionInfo = sdlan_session:debug_info(Session), + maps:merge(SessionInfo, ProcInfo#{ + state => StateName, + session => SessionInfo, + frames_sent => get_counter(quic_frames_sent), + bytes_sent => get_counter(quic_bytes_sent), + stream_active_n => StreamActiveN, + heartbeat_sec => HeartbeatSec + }). + +incr_counter(Key, Inc) -> + erlang:put(Key, get_counter(Key) + Inc). + +get_counter(Key) -> + case erlang:get(Key) of + undefined -> + 0; + Value when is_integer(Value) -> + Value + end. diff --git a/apps/sdlan/src/sdlan.app.src b/src/sdlan.app.src similarity index 92% rename from apps/sdlan/src/sdlan.app.src rename to src/sdlan.app.src index 0f99a57..80128c4 100644 --- a/apps/sdlan/src/sdlan.app.src +++ b/src/sdlan.app.src @@ -10,14 +10,11 @@ ranch, poolboy, mysql, - jiffy, hackney, - gpb, throttle, dns_erlang, pkt, quicer, - mnesia, erts, public_key, ssl, diff --git a/src/sdlan_api.erl b/src/sdlan_api.erl new file mode 100644 index 0000000..78c55d8 --- /dev/null +++ b/src/sdlan_api.erl @@ -0,0 +1,219 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2024, +%%% @doc +%%% +%%% @end +%%% Created : 27. 3月 2024 16:17 +%%%------------------------------------------------------------------- +-module(sdlan_api). +-author("anlicheng"). + +-define(API_TOKEN, <<"H6p*2RfEu4ITcL">>). + +%% API +-export([get_all_networks/0, get_network/1]). +-export([flow_report/5, network_forward_report/2, auth_access_token/1, set_node_status/1]). + +-spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}. +get_all_networks() -> + case safe_request(fun() -> do_get("get_all_networks", []) end) of + {ok, Resp} -> + case decode_json(Resp) of + {ok, #{<<"result">> := Networks}} -> + {ok, Networks}; + {ok, #{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}}} -> + {error, Message}; + {ok, _} -> + {error, <<"invalid json">>}; + {error, Reason} -> + {error, Reason} + end; + {error, _Reason} = Error -> + Error + end. + +-spec get_network(Id :: integer()) -> {ok, Network :: map()} | {error, Reason :: any()}. +get_network(Id) when is_integer(Id) -> + case safe_request(fun() -> do_get("get_network", [{<<"id">>, integer_to_binary(Id)}]) end) of + {ok, Resp} -> + case decode_json(Resp) of + {ok, #{<<"result">> := Network}} -> + {ok, Network}; + {ok, #{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}}} -> + {error, Message}; + {ok, _} -> + {error, <<"invalid json">>}; + {error, Reason} -> + {error, Reason} + end; + {error, _Reason} = Error -> + Error + end. + +-spec auth_access_token(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}. +auth_access_token(Params) when is_map(Params) -> + case safe_request(fun() -> do_post("auth/access_token", Params) end) of + {ok, Resp} -> + case decode_json(Resp) of + {ok, Result} -> + {ok, Result}; + {error, Reason} -> + {error, Reason} + end; + {error, _Reason} = Error -> + Error + end. + +-spec set_node_status(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}. +set_node_status(Params) when is_map(Params) -> + case safe_request(fun() -> do_post("set_node_status", Params) end) of + {ok, Resp} -> + decode_json(Resp); + {error, _Reason} = Error -> + Error + end. + +-spec flow_report(ClientId :: binary(), NetworkId :: integer(), ForwardNum :: integer(), P2PNum :: integer(), InboundNum :: integer()) -> + {ok, Resp :: map()} | {error, Reason :: any()}. +flow_report(ClientId, NetworkId, ForwardNum, P2PNum, InboundNum) + when is_binary(ClientId), is_integer(NetworkId), is_integer(ForwardNum), is_integer(P2PNum), is_integer(InboundNum) -> + Params = #{ + <<"client_id">> => ClientId, + <<"network_id">> => NetworkId, + <<"forward_num">> => ForwardNum, + <<"p2p_num">> => P2PNum, + <<"inbound_num">> => InboundNum + }, + case safe_request(fun() -> do_post("client_flow_report", Params) end) of + {ok, Resp} -> + decode_json(Resp); + {error, _Reason} = Error -> + Error + end. + +-spec network_forward_report(NetworkId :: integer(), ForwardNum :: integer()) -> + {ok, Resp :: map()} | {error, Reason :: any()}. +network_forward_report(NetworkId, ForwardNum) when is_integer(NetworkId), is_integer(ForwardNum) -> + Params = #{ + <<"network_id">> => NetworkId, + <<"forward_num">> => ForwardNum + }, + case safe_request(fun() -> do_post("network_forward_report", Params) end) of + {ok, Resp} -> + decode_json(Resp); + {error, _Reason} = Error -> + Error + end. + +-spec safe_request(Fun :: fun(() -> {ok, binary()} | {error, any()})) -> {ok, binary()} | {error, any()}. +safe_request(Fun) when is_function(Fun, 0) -> + case catch Fun() of + {ok, _Resp} = Ok -> + Ok; + {error, _Reason} = Error -> + Error; + {'EXIT', Reason} -> + {error, Reason}; + Error -> + {error, Error} + end. + +-spec decode_json(Resp :: binary()) -> {ok, map()} | {error, any()}. +decode_json(Resp) when is_binary(Resp) -> + try json:decode(Resp) of + Result when is_map(Result) -> + {ok, Result}; + Other -> + {error, {invalid_json, Other}} + catch error:Reason -> + {error, Reason} + end. + +-spec do_get(Uri :: string(), Params :: [{K :: binary(), V :: binary()}]) -> {ok, Response :: binary()} | {error, Reason :: any()}. +do_get(Uri, Params) when is_list(Uri), is_list(Params) -> + {ok, Url0} = application:get_env(sdlan, api_url), + + Headers = [ + {<<"Content-Type">>, <<"application/json">>}, + {<<"X-sign">>, sign_params(Params)} + ], + + QS0 = uri_string:compose_query(Params), + QS = iolist_to_binary(QS0), + + Url = Url0 ++ Uri ++ "?" ++ binary_to_list(QS), + case catch hackney:request(get, Url, Headers, <<>>, [{pool, false}]) of + {ok, 200, _, ClientRef} -> + {ok, RespBody} = hackney:body(ClientRef), + hackney:close(ClientRef), + {ok, RespBody}; + {ok, HttpCode, _, ClientRef} -> + {ok, RespBody} = hackney:body(ClientRef), + hackney:close(ClientRef), + {error, {HttpCode, RespBody}}; + {error, Reason} -> + {error, Reason} + end. + +-spec do_post(Uri :: string(), Params :: map()) -> {ok, Resp :: binary()} | {error, Reason :: any()}. +do_post(Uri, Params) when is_list(Uri), is_map(Params) -> + {ok, Url0} = application:get_env(sdlan, api_url), + + Headers = [ + {<<"content-type">>, <<"application/json">>}, + {<<"X-sign">>, sign_params(Params)} + ], + + Body = iolist_to_binary(json:encode(Params)), + Url = Url0 ++ Uri, + + case catch hackney:request(post, Url, Headers, Body, [{pool, false}]) of + {ok, 200, _, ClientRef} -> + {ok, RespBody} = hackney:body(ClientRef), + hackney:close(ClientRef), + {ok, RespBody}; + {ok, HttpCode, _, ClientRef} -> + {ok, RespBody} = hackney:body(ClientRef), + hackney:close(ClientRef), + {error, {HttpCode, RespBody}}; + {ok, HttpCode, _} -> + {error, {HttpCode, <<"empty response">>}}; + {ok, ClientRef} -> + hackney:close(ClientRef), + {error, <<"empty response">>}; + {error, Reason} -> + {error, Reason} + end. + +-spec sign_params(Params :: any()) -> binary(). +sign_params(Params) when is_list(Params) -> + %% 签名逻辑 + Keys = lists:map(fun({K, _}) -> K end, Params), + Parts = lists:map(fun(K) -> + V = as_binary(proplists:get_value(K, Params, <<"">>)), + <>, Parts)), + logger:debug("sign: ~p, params: ~p", [SignBin, Params]), + + list_to_binary(sdlan_util:hmac(?API_TOKEN, SignBin)); +sign_params(Params) when is_map(Params) -> + SortedKeys = lists:sort(maps:keys(Params)), + Parts = lists:map(fun(K) -> + V = as_binary(maps:get(K, Params, <<"">>)), + <>, Parts)), + logger:debug("sign: ~p, params: ~p", [SignBin, Params]), + list_to_binary(sdlan_util:hmac(?API_TOKEN, SignBin)). + +-spec as_binary(Bin :: any()) -> binary(). +as_binary(Bin) when is_binary(Bin) -> + Bin; +as_binary(I) when is_integer(I) -> + integer_to_binary(I); +as_binary(F) when is_float(F) -> + float_to_binary(F, [short]); +as_binary(Str) when is_list(Str) -> + list_to_binary(Str). diff --git a/src/sdlan_app.erl b/src/sdlan_app.erl new file mode 100644 index 0000000..058dc0a --- /dev/null +++ b/src/sdlan_app.erl @@ -0,0 +1,47 @@ +%%%------------------------------------------------------------------- +%% @doc sdlan public API +%% @end +%%%------------------------------------------------------------------- + +-module(sdlan_app). + +-behaviour(application). + +-export([start/2, stop/1]). + +-spec start(StartType :: application:start_type(), StartArgs :: term()) -> + {ok, pid()} | {ok, pid(), term()} | {error, term()}. +start(_StartType, _StartArgs) -> + io:setopts([{encoding, unicode}]), + %% 加速内存的回收 + erlang:system_flag(fullsweep_after, 16), + + %% 设置环境变量 + case sdlan_util:ipv6_assist_info() of + {ok, V6Info} -> + application:set_env(sdlan, ipv6_assist_info, V6Info); + undefined -> + ok + end, + + %% 现在ipv6探测工具的使用频率 + throttle:setup(sdlan_ipv6_assist, 60, per_minute), + + %% 启动注册表 + sdlan_hostname_regedit:init(), + sdlan_domain_regedit:init(), + + %% 权限的数据管理 + identity_policy_ets:init(), + rule_ets:init(), + + sdlan_http_server:start(), + sdlan_ssl_server:start(), + + sdlan_sup:start_link(). + +-spec stop(State :: term()) -> ok. +stop(_State) -> + ok. + +%% internal functions diff --git a/apps/sdlan/src/sdlan_cipher.erl b/src/sdlan_cipher.erl similarity index 61% rename from apps/sdlan/src/sdlan_cipher.erl rename to src/sdlan_cipher.erl index 8282a31..4b8c56a 100644 --- a/apps/sdlan/src/sdlan_cipher.erl +++ b/src/sdlan_cipher.erl @@ -12,14 +12,13 @@ %% API -export([rsa_encrypt/2, rsa_pem_decode/1]). -export([aes_encrypt/3, aes_decrypt/3]). --export([test/0]). +-export([test/0, test_chacha20/0]). +-spec test() -> ok. test() -> Key = <<"abcdabcdabcdabcd">>, X = aes_encrypt(Key, Key, <<"hello world">>), logger:debug("x is: ~p, raw: ~p", [X, aes_decrypt(Key, Key, X)]), - - ok. -spec rsa_pem_decode(PubKey :: binary()) -> public_key:rsa_public_key(). @@ -40,4 +39,45 @@ aes_encrypt(Key, IVec, PlainText) when is_binary(Key), is_binary(IVec), is_binar %% 基于aes的解密算法 -spec aes_decrypt(binary(), binary(), binary()) -> binary(). aes_decrypt(Key, IVec, CipherText) when is_binary(Key), is_binary(IVec), is_binary(CipherText) -> - crypto:crypto_one_time(aes_128_ofb, Key, IVec, CipherText, [{encrypt, false}, {padding, pkcs_padding}]). \ No newline at end of file + crypto:crypto_one_time(aes_128_ofb, Key, IVec, CipherText, [{encrypt, false}, {padding, pkcs_padding}]). + + +-spec test_chacha20() -> ok. +test_chacha20() -> + Key = crypto:strong_rand_bytes(32), + Nonce = crypto:strong_rand_bytes(12), + PlainText = <<"hello world">>, + + Enc = chacha20_encrypt(Key, Nonce, PlainText), + + Ex = chacha20_decrypt(Key, Enc), + + logger:debug("yes ex is: ~p", [Ex]), + ok. + + +chacha20_encrypt(Key, Nonce, Plain) -> + AAD = <<>>, + {Cipher, Tag} = crypto:crypto_one_time_aead( + chacha20_poly1305, + Key, + Nonce, + Plain, + AAD, + true + ), + <>. + +chacha20_decrypt(Key, <>) -> + AAD = <<>>, + CipherLen = byte_size(Rest) - 16, + <> = Rest, + crypto:crypto_one_time_aead( + chacha20_poly1305, + Key, + Nonce, + Cipher, + AAD, + Tag, + false + ). diff --git a/apps/sdlan/src/sdlan_domain_regedit.erl b/src/sdlan_domain_regedit.erl similarity index 89% rename from apps/sdlan/src/sdlan_domain_regedit.erl rename to src/sdlan_domain_regedit.erl index 7fe64df..d0692d5 100644 --- a/apps/sdlan/src/sdlan_domain_regedit.erl +++ b/src/sdlan_domain_regedit.erl @@ -14,6 +14,7 @@ -define(TABLE, sdlan_domain_regedit). +-spec init() -> ets:tab(). init() -> ets:new(?TABLE, [named_table, ordered_set, public, {read_concurrency, true}, {write_concurrency, true}]). @@ -31,6 +32,6 @@ maybe_domain(QName) when is_binary(QName) -> false end. --spec insert(Domain :: binary()) -> no_return(). +-spec insert(Domain :: binary()) -> true. insert(Domain) when is_binary(Domain) -> - true = ets:insert(?TABLE, {Domain}). \ No newline at end of file + true = ets:insert(?TABLE, {Domain}). diff --git a/apps/sdlan/src/sdlan_hostname_regedit.erl b/src/sdlan_hostname_regedit.erl similarity index 57% rename from apps/sdlan/src/sdlan_hostname_regedit.erl rename to src/sdlan_hostname_regedit.erl index c934516..d2ebfcd 100644 --- a/apps/sdlan/src/sdlan_hostname_regedit.erl +++ b/src/sdlan_hostname_regedit.erl @@ -10,23 +10,29 @@ -author("anlicheng"). %% API --export([init/0, lookup/1, insert/2]). +-export([init/0, lookup/1, insert/3]). -define(TABLE, sdlan_hostname_regedit). +-spec init() -> ets:tab(). init() -> ets:new(?TABLE, [named_table, set, public, {read_concurrency, true}, {write_concurrency, true}]). -spec lookup(FullHostname :: binary()) -> error | {ok, Ip :: inet:ip4_address()}. lookup(FullHostname) when is_binary(FullHostname) -> - case ets:lookup(?TABLE, FullHostname) of + LowerFullHostname = string:lowercase(FullHostname), + case ets:lookup(?TABLE, LowerFullHostname) of [{_, Ip}] -> {ok, Ip}; [] -> error end. --spec insert(FullHostname :: binary(), Ip :: integer()) -> no_return(). -insert(FullHostname, Ip) when is_binary(FullHostname), is_integer(Ip) -> +-spec insert(any(), Domain :: binary(), Ip :: integer()) -> true | ok. +insert(HostName, Domain, Ip) when is_binary(HostName), is_binary(Domain), is_integer(Ip), HostName /= <<>> -> + FullHostname = <>, + LowerFullHostname = string:lowercase(FullHostname), <> = <>, - true = ets:insert(?TABLE, {FullHostname, {Ip0, Ip1, Ip2, Ip3}}). \ No newline at end of file + true = ets:insert(?TABLE, {LowerFullHostname, {Ip0, Ip1, Ip2, Ip3}}); +insert(_, _, _) -> + ok. diff --git a/src/sdlan_network.erl b/src/sdlan_network.erl new file mode 100644 index 0000000..ffc58f8 --- /dev/null +++ b/src/sdlan_network.erl @@ -0,0 +1,725 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2024, +%%% @doc +%%% +%%% @end +%%% Created : 27. 3月 2024 15:13 +%%%------------------------------------------------------------------- +-module(sdlan_network). +-author("anlicheng"). +-include("sdlan.hrl"). +-include("sdlan_pb.hrl"). +-include_lib("stdlib/include/ms_transform.hrl"). + +-behaviour(gen_server). + +%% broadcast, "FF-FF-FF-FF-FF-FF" +-define(BROADCAST_MAC, <<16#FF,16#FF,16#FF,16#FF,16#FF,16#FF>>). + +%% API +-export([start_link/2]). +-export([get_name/1, get_pid/1, lookup_pid/1, peer_info/3, unregister/3, debug_info/1, get_network_id/1, attach/6, arp_request/2]). +-export([forward_by_ets/5, update_hole/7, disable_client/2, get_channel/2]). +-export([command/4, wait_command_ack/2]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). + +-record(hole, { + peer :: {Ip :: inet:ip4_address(), Port :: integer()}, + nat_type :: integer() +}). + +%% ip的使用信息, 记录Node的运行时状态信息 +-record(endpoint, { + channel_pid :: undefined | pid(), + channel_ref :: undefined | reference(), + + client_id :: binary(), + mac :: binary(), + ip :: integer(), + hostname :: binary(), + hole :: undefined | #hole{}, + %% 记录ip和ip_v6的映射关系, #{ip_addr :: integer() => {}} + v6_info :: undefined | #'SDLV6Info'{}, + session_token :: binary(), + last_seen :: integer() %% monotonic_time(second), +}). + +-record(state, { + network_id :: integer(), + name :: binary(), + domain :: binary(), + ipaddr :: binary(), + mask_len :: integer(), + owner_id :: integer(), + + %% 加密算法, 默认为chacha20 + algorithm :: binary(), + %% 同一个网络下公用的密钥, 采用AES-256加密算法;随机生成 + key :: binary(), + + %% 设置网络带宽 + throttle_key :: atom(), + endpoint_table :: ets:tid() +}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec get_pid(Id :: integer()) -> undefined | pid(). +get_pid(Id) when is_integer(Id) -> + whereis(get_name(Id)). + +-spec lookup_pid(Id :: integer()) -> {ok, Pid :: pid()} | error. +lookup_pid(Id) when is_integer(Id) -> + case whereis(get_name(Id)) of + undefined -> + error; + Pid -> + {ok, Pid} + end. + +-spec get_name(Id :: integer()) -> atom(). +get_name(Id) when is_integer(Id) -> + list_to_atom("sdlan_network:" ++ integer_to_list(Id)). + +-spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}. +get_network_id(Pid) when is_pid(Pid) -> + gen_server:call(Pid, get_network_id). + +-spec attach(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), Ip :: integer(), Hostname :: binary()) -> + {ok, Algorithm :: binary(), Key :: binary(), RegionId :: integer(), SessionToken :: binary()}. +attach(Pid, ChannelPid, ClientId, Mac, Ip, Hostname) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(Ip), is_binary(Hostname) -> + gen_server:call(Pid, {attach, ChannelPid, ClientId, Mac, Ip, Hostname}). + +-spec unregister(Pid :: pid(), ClientId :: binary(), Mac :: binary()) -> ok. +unregister(Pid, ClientId, Mac) when is_pid(Pid), is_binary(ClientId), is_binary(Mac) -> + gen_server:cast(Pid, {unregister, ClientId, Mac}). + +-spec peer_info(Pid :: pid(), SrcMac :: binary(), DstMac :: binary()) -> + error | {ok, {NatPeer :: {Ip :: inet:ip4_address(), Port :: integer()}, NatType :: integer()}, V6Info :: undefined | #'SDLV6Info'{}}. +peer_info(Pid, SrcMac, DstMac) when is_pid(Pid), is_binary(SrcMac), is_binary(DstMac) -> + gen_server:call(Pid, {peer_info, SrcMac, DstMac}). + +-spec arp_request(Pid :: pid(), TargetIp :: integer()) -> error | {ok, Mac :: binary()}. +arp_request(Pid, TargetIp) when is_pid(Pid), is_integer(TargetIp) -> + gen_server:call(Pid, {arp_request, TargetIp}). + +-spec command(Pid :: pid(), ReceiverPid :: pid(), ClientId :: binary(), {Tag :: atom(), SubCommand :: any()}) -> + {error, Reason :: binary()} | {ok, Ref :: reference()}. +command(Pid, ReceiverPid, ClientId, SubCommand) when is_pid(Pid), is_pid(ReceiverPid), is_binary(ClientId) -> + gen_server:call(Pid, {command, ReceiverPid, ClientId, SubCommand}). + +-spec wait_command_ack(Ref :: reference(), Timeout :: integer()) -> {error, timeout} | {ok, CommandAck :: #'SDLCommandAck'{}}. +wait_command_ack(Ref, Timeout) when is_reference(Ref), is_integer(Timeout) -> + receive + {quic_command_ack, Ref, CommandAck} -> + {ok, CommandAck} + after Timeout -> + {error, timeout} + end. + +-spec forward_by_ets(NetworkId :: integer(), Sock :: any(), SrcMac :: binary(), DstMac :: binary(), Packet :: binary()) -> + {ok, ForwardBytes :: integer()} | {error, Reason :: any()}. +forward_by_ets(NetworkId, Sock, SrcMac, DstMac, Packet) when is_integer(NetworkId), is_binary(SrcMac), is_binary(DstMac), is_binary(Packet) -> + case endpoint_existing_table_name(NetworkId) of + {ok, Table} -> + case lookup_endpoint(Table, SrcMac) of + #endpoint{} -> + case sdlan_util:is_broadcast_mac(DstMac) orelse sdlan_util:is_multicast_mac(DstMac) of + true -> + forward_broadcast_by_ets(NetworkId, Sock, SrcMac, DstMac, Packet); + false -> + forward_unicast_by_ets(NetworkId, Sock, SrcMac, DstMac, Packet) + end; + undefined -> + logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, forward discard, src not found", + [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + {error, src_not_found} + end; + error -> + {error, table_not_found} + end. + +%% 更新ip地址对应的nat关系 +-spec update_hole(Pid :: pid(), SessionToken :: binary(), ClientId :: binary(), Mac :: binary(), Peer :: tuple(), NatType :: integer(), V6Info :: undefined | #'SDLV6Info'{}) -> ok. +update_hole(Pid, SessionToken, ClientId, Mac, Peer, NatType, V6Info) when is_pid(Pid), is_binary(ClientId), is_binary(Mac), is_integer(NatType) -> + gen_server:cast(Pid, {update_hole, SessionToken, ClientId, Mac, Peer, NatType, V6Info}). + +-spec disable_client(Pid :: pid(), ClientId :: binary()) -> ok | error. +disable_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) -> + gen_server:call(Pid, {disable_client, ClientId}). + +-spec get_channel(Pid :: pid(), ClientId :: binary()) -> error | {ok, ChannelPid :: pid()}. +get_channel(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) -> + gen_server:call(Pid, {get_channel, ClientId}). + +-spec debug_info(Pid :: pid()) -> map(). +debug_info(Pid) when is_pid(Pid) -> + gen_server:call(Pid, debug_info). + +%% @doc Spawns the server and registers the local name (unique) +-spec(start_link(Name :: atom(), NetworkData :: tuple()) -> + {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). +start_link(Name, NetworkData = {network, Id, _NetworkName, _Domain, _IpAddr, _MaskLen, _OwnerId, _Algorithm}) + when is_atom(Name), is_integer(Id) -> + gen_server:start_link({local, Name}, ?MODULE, [NetworkData], []). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +%% @private +%% @doc Initializes the server +-spec(init(Args :: term()) -> + {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | + {stop, Reason :: term()} | ignore). +init([{network, Id, Name, Domain, IpAddr, MaskLen, OwnerId, Algorithm0}]) -> + erlang:process_flag(trap_exit, true), + %% 限流key + ThrottleKey = list_to_atom("network_throttle:" ++ integer_to_list(Id)), + %% 绑定到资源协调器 + sdlan_network_coordinator:attach(self(), ThrottleKey), + + sdlan_domain_regedit:insert(Domain), + + %% 处理加密算法 + Algorithm = normalization_algorithm(Algorithm0), + Key = gen_key(Algorithm), + EndpointTable = new_endpoint_table(Id), + + {ok, #state{network_id = Id, name = Name, domain = Domain, ipaddr = IpAddr, algorithm = Algorithm, + owner_id = OwnerId, mask_len = MaskLen, key = Key, throttle_key = ThrottleKey, endpoint_table = EndpointTable}}. + +%% @private +%% @doc Handling call messages +-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()}, + State :: #state{}) -> + {reply, Reply :: term(), NewState :: #state{}} | + {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} | + {noreply, NewState :: #state{}} | + {noreply, NewState :: #state{}, timeout() | hibernate} | + {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | + {stop, Reason :: term(), NewState :: #state{}}). +%% 给客户端分配ip地址 +handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From, + State = #state{network_id = NetworkId, domain = Domain, algorithm = Algorithm, key = Key, endpoint_table = EndpointTable}) -> + %% 分配ip地址的时候,以mac地址为唯一基准 + logger:debug("[sdlan_network] alloc_ip, network_id: ~p, client_id: ~p, mac: ~p, ip_addr: ~p", + [NetworkId, ClientId, sdlan_util:format_mac(Mac), sdlan_util:int_to_ipv4(Ip)]), + %% 添加域名->ip的映射关系 + sdlan_hostname_regedit:insert(Hostname, Domain, Ip), + + %% mac对应的Endpoint存在,并且对应的ip变了,需要通知端上清理arp + maybe_nat_changed(ChannelPid, Mac, Ip, EndpointTable), + + ChannelRef = monitor(process, ChannelPid), + SessionToken = gen_session_token(), + Endpoint = #endpoint{ + channel_pid = ChannelPid, + channel_ref = ChannelRef, + client_id = ClientId, + mac = Mac, + ip = Ip, + hostname = Hostname, + session_token = SessionToken, + last_seen = erlang:monotonic_time(second) + }, + insert_endpoint(EndpointTable, Mac, Endpoint), + + %% 生成对应的分区id + RegionId = gen_region_id(Ip), + + {reply, {ok, Algorithm, Key, RegionId, SessionToken}, State}; + +%% client设置为禁止状态,不允许重连 +handle_call({disable_client, ClientId}, _From, State = #state{endpoint_table = EndpointTable}) -> + MatchSpec = ets:fun2ms(fun(Object = {_Mac, #endpoint{client_id = ClientId0}}) when ClientId0 =:= ClientId -> + Object + end), + case select_endpoint(EndpointTable, MatchSpec) of + {ok, Mac, Endpoint} -> + cleanup_endpoint(Endpoint, undefined, disabled), + delete_endpoint(EndpointTable, Mac), + {reply, ok, State}; + error -> + {reply, ok, State} + end; + +handle_call({get_channel, ClientId}, _From, State = #state{endpoint_table = EndpointTable}) -> + MatchSpec = ets:fun2ms(fun(Object = {_Mac, #endpoint{client_id = ClientId0}}) when ClientId0 =:= ClientId -> + Object + end), + case select_endpoint(EndpointTable, MatchSpec) of + {ok, _, #endpoint{channel_pid = ChannelPid}} -> + {reply, {ok, ChannelPid}, State}; + error -> + {reply, error, State} + end; + +handle_call(get_network_id, _From, State = #state{network_id = NetworkId}) -> + {reply, {ok, NetworkId}, State}; + +%% 网络存在的nat_peer信息 +handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{endpoint_table = EndpointTable}) -> + case lookup_endpoint(EndpointTable, DstMac) of + #endpoint{channel_pid = DstChannelPid, hole = #hole{peer = DstNatPeer, nat_type = DstNatType}, v6_info = DstV6Info} -> + %% 让目标服务器发送sendRegister事件(2024-06-25 新增,提高打洞的成功率) + maybe + #endpoint{hole = #hole{peer = {SrcNatIp, SrcNatPort}, nat_type = SrcNatType}, v6_info = SrcV6Info} ?= lookup_endpoint(EndpointTable, SrcMac), + + RegisterEvent = sdlan_pb:encode_msg(#'SDLEvent' { + event = {send_register, #'SDLEvent.SendRegister'{ + dst_mac = SrcMac, + nat_ip = sdlan_util:ipv4_to_int(SrcNatIp), + nat_type = SrcNatType, + nat_port = SrcNatPort, + v6_info = SrcV6Info + }} + }), + logger:debug("Event: send_register, for peer_info"), + + sdlan_quic_channel:send_event(DstChannelPid, RegisterEvent) + end, + {reply, {ok, {DstNatPeer, DstNatType}, DstV6Info}, State}; + _ -> + {reply, error, State} + end; + +%% arp查询 +handle_call({arp_request, TargetIp}, _From, State = #state{endpoint_table = EndpointTable}) -> + MatchSpec = ets:fun2ms(fun(Object = {_Mac, #endpoint{ip = Ip}}) when Ip =:= TargetIp -> + Object + end), + case select_endpoint(EndpointTable, MatchSpec) of + error -> + {reply, error, State}; + {ok, Mac, _} -> + {reply, {ok, Mac}, State} + end; + +%% 发送命令 +handle_call({command, ReceiverPid, ClientId, SubCommand}, _From, State = #state{endpoint_table = EndpointTable}) -> + MatchSpec = ets:fun2ms(fun(Object = {_Mac, #endpoint{client_id = ClientId0}}) when ClientId0 =:= ClientId -> + Object + end), + case select_endpoint(EndpointTable, MatchSpec) of + {ok, _Mac, #endpoint{channel_pid = ChannelPid}} -> + Ref = make_ref(), + sdlan_quic_channel:command(ChannelPid, Ref, ReceiverPid, SubCommand), + {reply, {ok, Ref}, State}; + error -> + {reply, {error, <<"目标Node不在线"/utf8>>}, State} + end; + +handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = IpAddr, mask_len = MaskLen, owner_id = OwnerId, endpoint_table = EndpointTable}) -> + Reply = #{ + <<"network_id">> => NetworkId, + <<"ipaddr">> => IpAddr, + <<"mask_len">> => MaskLen, + <<"owner_id">> => OwnerId, + <<"metrics">> => network_metrics(State), + <<"used_ips">> => lists:map(fun format_endpoint/1, list_endpoints(EndpointTable)) + }, + {reply, Reply, State}. + +%% @private +%% @doc Handling cast messages +-spec(handle_cast(Request :: term(), State :: #state{}) -> + {noreply, NewState :: #state{}} | + {noreply, NewState :: #state{}, timeout() | hibernate} | + {stop, Reason :: term(), NewState :: #state{}}). +%% 删除ip的占用并关闭channel +handle_cast({unregister, ClientId, Mac}, State = #state{network_id = NetworkId, endpoint_table = EndpointTable}) -> + logger:debug("[sdlan_network] networkd_id: ~p, unregister client_id: ~p, Mac: ~p", + [NetworkId, ClientId, sdlan_util:format_mac(Mac)]), + case lookup_endpoint(EndpointTable, Mac) of + Endpoint = #endpoint{client_id = ClientId} -> + cleanup_endpoint(Endpoint, Endpoint#endpoint.channel_pid, unregister), + delete_endpoint(EndpointTable, Mac), + {noreply, State}; + undefined -> + {noreply, State} + end; + +%% 需要判断,client是属于当前网络的 +handle_cast({update_hole, SessionToken, ClientId, Mac, Peer, NatType, V6Info}, State = #state{endpoint_table = EndpointTable}) -> + case lookup_endpoint(EndpointTable, Mac) of + %% ClientId =:= ClientId0, SessionToken =:= SessionToken0 + Endpoint0 = #endpoint{ip = Ip, client_id = ClientId, hole = OldHole, session_token = SessionToken} -> + NHole = #hole{peer = Peer, nat_type = NatType}, + maybe + true ?= not same_hole(OldHole, NHole), + + NatChangedEvent = sdlan_pb:encode_msg(#'SDLEvent' { + event = {nat_changed, #'SDLEvent.NatChanged'{ + mac = Mac, + ip = Ip + }} + }), + + logger:debug("[sdlan_network] Event: nat_changed, update_hole, client_id: ~p(~p), hole changed", [ClientId, Ip]), + broadcast(fun(#endpoint{channel_pid = ChannelPid}) -> + sdlan_quic_channel:send_event(ChannelPid, NatChangedEvent) + end, [Mac], EndpointTable) + end, + NEndpoint = Endpoint0#endpoint{hole = NHole, v6_info = V6Info, last_seen = erlang:monotonic_time(second)}, + insert_endpoint(EndpointTable, Mac, NEndpoint), + logger:debug("[sdlan_network] mac: ~p, ip: ~p, endpoint is: ~p", [Mac, Ip, NEndpoint]), + + {noreply, State}; + _ -> + {noreply, State} + end. + +%% @private +%% @doc Handling all non call/cast messages +-spec(handle_info(Info :: timeout() | term(), State :: #state{}) -> + {noreply, NewState :: #state{}} | + {noreply, NewState :: #state{}, timeout() | hibernate} | + {stop, Reason :: term(), NewState :: #state{}}). +%% Channel进程退出, hole里面的数据也需要清理 +handle_info({'DOWN', _MRef, process, ChannelPid, Reason}, State = #state{network_id = NetworkId, endpoint_table = EndpointTable}) -> + logger:notice("[sdlan_network] network_id: ~p, channel_pid: ~p, close with reason: ~p", [NetworkId, ChannelPid, Reason]), + remove_channel_endpoints(ChannelPid, EndpointTable), + {noreply, State}; + +handle_info(Info, State) -> + logger:debug("[sdlan_network] get unknown info: ~p", [Info]), + {noreply, State}. + +%% @private +%% @doc This function is called by a gen_server when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any +%% necessary cleaning up. When it returns, the gen_server terminates +%% with Reason. The return value is ignored. +-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), + State :: #state{}) -> ok). +terminate(Reason, #state{network_id = NetworkId, endpoint_table = EndpointTable}) -> + broadcast(fun(#endpoint{channel_pid = ChannelPid}) -> + case is_pid(ChannelPid) andalso is_process_alive(ChannelPid) of + true -> + NetworkShutdownEvent = sdlan_pb:encode_msg(#'SDLEvent'{ + event = {shutdown, #'SDLEvent.NetworkShutdown'{ + message = <<"Network shutdown">> + }} + }), + + logger:debug("[sdlan_network] Event: shutdown"), + + sdlan_quic_channel:send_event(ChannelPid, NetworkShutdownEvent), + sdlan_quic_channel:stop(ChannelPid, normal); + false -> + ok + end + end, [], EndpointTable), + logger:debug("[sdlan_network] network: ~p, will terminate with reason: ~p", [NetworkId, Reason]), + ok. + +%% @private +%% @doc Convert process state when code is changed +-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{}, + Extra :: term()) -> + {ok, NewState :: #state{}} | {error, Reason :: term()}). +code_change(_OldVsn, State = #state{}, _Extra) -> + {ok, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +-spec limiting_check(ThrottleKey :: any()) -> pass | denied. +limiting_check(ThrottleKey) -> + case throttle:check(sdlan_network, ThrottleKey) of + {ok, _RestCount, _LeftToReset} -> + pass; + {limit_exceeded, 0, _LeftToReset} -> + %% 尝试获取其他网络是否有让渡的资源 + case sdlan_network_coordinator:checkout() of + ok -> + pass; + error -> + denied + end + end. + +-spec endpoint_table_name(NetworkId :: integer()) -> atom(). +endpoint_table_name(NetworkId) when is_integer(NetworkId) -> + list_to_atom(lists:concat(["sdlan_network_endpoint:", NetworkId])). + +-spec endpoint_existing_table_name(NetworkId :: integer()) -> {ok, atom()} | error. +endpoint_existing_table_name(NetworkId) when is_integer(NetworkId) -> + try + Atom = list_to_existing_atom(lists:concat(["sdlan_network_endpoint:", NetworkId])), + {ok, Atom} + catch error:_ -> + error + end. + +-spec throttle_key(NetworkId :: integer()) -> atom(). +throttle_key(NetworkId) when is_integer(NetworkId) -> + list_to_atom("network_throttle:" ++ integer_to_list(NetworkId)). + +-spec new_endpoint_table(NetworkId :: integer()) -> ets:tid(). +new_endpoint_table(NetworkId) when is_integer(NetworkId) -> + ets:new(endpoint_table_name(NetworkId), [ + named_table, + protected, + set, + {read_concurrency, true}, + {write_concurrency, true} + ]). + +-spec insert_endpoint(Table :: ets:tid(), Mac :: binary(), Endpoint :: #endpoint{}) -> true. +insert_endpoint(Table, Mac, Endpoint = #endpoint{}) when is_binary(Mac) -> + ets:insert(Table, {Mac, Endpoint}). + +-spec delete_endpoint(Table :: ets:tid(), Mac :: binary()) -> true. +delete_endpoint(Table, Mac) when is_binary(Mac) -> + ets:delete(Table, Mac). + +-spec lookup_endpoint(atom() | ets:tid(), Mac :: binary()) -> #endpoint{} | undefined. +lookup_endpoint(Table, Mac) when is_binary(Mac) -> + try ets:lookup(Table, Mac) of + [{Mac, Endpoint = #endpoint{}}] -> + Endpoint; + [] -> + undefined + catch error:_ -> + undefined + end. + +-spec list_endpoints(atom() | ets:tid()) -> [{binary(), #endpoint{}}]. +list_endpoints(Table) -> + try ets:tab2list(Table) of + Endpoints when is_list(Endpoints) -> + Endpoints + catch error:_ -> + [] + end. + +-spec remove_channel_endpoints(ChannelPid :: pid(), Table :: ets:tid()) -> ok. +remove_channel_endpoints(ChannelPid, Table) when is_pid(ChannelPid) -> + lists:foreach(fun + ({Mac, #endpoint{channel_pid = ChannelPid0}}) when ChannelPid =:= ChannelPid0 -> + delete_endpoint(Table, Mac); + (_) -> + ok + end, list_endpoints(Table)). + +-spec forward_unicast_by_ets(NetworkId :: integer(), Sock :: any(), SrcMac :: binary(), DstMac :: binary(), Packet :: binary()) -> + {ok, integer()} | {error, any()}. +forward_unicast_by_ets(NetworkId, Sock, SrcMac, DstMac, Packet) -> + PacketBytes = byte_size(Packet), + case endpoint_existing_table_name(NetworkId) of + {ok, Table} -> + case lookup_endpoint(Table, DstMac) of + #endpoint{hole = #hole{peer = Peer = {NatIp, NatPort}}} -> + case limiting_check(throttle_key(NetworkId)) of + pass -> + logger:debug("[sdlan_network] forward data by ets networkd_id: ~p, src_mac: ~p, dst_mac: ~p, hole: ~p", + [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), Peer]), + gen_udp:send(Sock, NatIp, NatPort, Packet), + {ok, PacketBytes}; + denied -> + logger:notice("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, rate limited, discard", + [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + {error, rate_limited} + end; + #endpoint{} -> + logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p, hole not found", + [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + {error, hole_not_found}; + undefined -> + logger:debug("[sdlan_network] networkd_id: ~p, src_mac: ~p, dst_mac: ~p not found", + [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + {error, dst_not_found} + end; + error -> + {error, table_not_found} + end. + +-spec forward_broadcast_by_ets(NetworkId :: integer(), Sock :: any(), SrcMac :: binary(), DstMac :: binary(), Packet :: binary()) -> + {ok, integer()}. +forward_broadcast_by_ets(NetworkId, Sock, SrcMac, DstMac, Packet) -> + Table = endpoint_table_name(NetworkId), + lists:foreach(fun + ({Mac, #endpoint{hole = #hole{peer = {NatIp, NatPort}}}}) when Mac =/= SrcMac -> + gen_udp:send(Sock, NatIp, NatPort, Packet); + (_) -> + ok + end, list_endpoints(Table)), + logger:debug("[sdlan_network] broadcast data by ets networkd_id: ~p, src_mac: ~p, dst_mac: ~p", + [NetworkId, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + {ok, byte_size(Packet)}. + +maybe_nat_changed(ChannelPid, Mac, Ip, EndpointTable) -> + OldEndpoint = lookup_endpoint(EndpointTable, Mac), + %% mac对应的Endpoint存在,并且对应的ip变了,需要通知端上清理arp + maybe + #endpoint{ip = OldIp} ?= OldEndpoint, + true ?= OldIp =/= Ip, + + Event = sdlan_pb:encode_msg(#'SDLEvent'{ + event = {nat_changed, #'SDLEvent.NatChanged' { + mac = Mac, + ip = Ip + }} + }), + logger:debug("Event: nat_changed, for attach"), + + broadcast(fun(#endpoint{channel_pid = ChannelPid0}) -> + sdlan_quic_channel:send_event(ChannelPid0, Event) + end, [Mac], EndpointTable) + end, + %% 重复attach需要清理之前的绑定信息;即使IP未变化,也不能保留旧channel。 + cleanup_endpoint(OldEndpoint, ChannelPid, rebind). + +cleanup_endpoint(undefined, _KeepChannelPid, _Reason) -> + ok; +cleanup_endpoint(#endpoint{channel_ref = ChannelRef, channel_pid = ChannelPid}, KeepChannelPid, Reason) -> + is_reference(ChannelRef) andalso erlang:demonitor(ChannelRef, [flush]), + case should_stop_channel(ChannelPid, KeepChannelPid) of + true -> + catch sdlan_quic_channel:stop(ChannelPid, Reason), + ok; + false -> + ok + end. + +should_stop_channel(ChannelPid, KeepChannelPid) when is_pid(ChannelPid), ChannelPid =/= KeepChannelPid -> + is_process_alive(ChannelPid); +should_stop_channel(_, _) -> + false. + +-spec broadcast(Fun :: fun((#endpoint{}) -> term()), ExcludeMacs :: [binary()], Table :: ets:tid()) -> ok. +broadcast(Fun, ExcludeMacs, Table) when is_function(Fun, 1), is_list(ExcludeMacs) -> + lists:foreach(fun({Mac, Endpoint}) -> + case lists:member(Mac, ExcludeMacs) of + true -> + ok; + false -> + Fun(Endpoint) + end + end, list_endpoints(Table)). + +-spec format_endpoint({Mac :: binary(), Host :: #endpoint{}}) -> map(). +format_endpoint({Mac, #endpoint{client_id = ClientId, ip = Ip, hole = #hole{peer = {NatIp, NatPort}, nat_type = NatType}, v6_info = V6Info}}) -> + HoleMap = #{ + nat_ip => NatIp, + nat_port => NatPort, + nat_type => NatType + }, + + V6InfoMap = case V6Info of + undefined -> + #{}; + #'SDLV6Info'{v6 = V6, port = V6Port} -> + #{v6 => V6, port => V6Port} + end, + #{ + client_id => ClientId, + mac => sdlan_util:format_mac(Mac), + ip => sdlan_util:int_to_ipv4(Ip), + hole_map => HoleMap, + v6_info => V6InfoMap + }; +format_endpoint({Mac, #endpoint{client_id = ClientId, ip = Ip, hole = undefined, v6_info = V6Info}}) -> + V6InfoMap = case V6Info of + undefined -> + #{}; + #'SDLV6Info'{v6 = V6, port = V6Port} -> + #{v6 => V6, port => V6Port} + end, + #{ + client_id => ClientId, + mac => sdlan_util:format_mac(Mac), + ip => sdlan_util:int_to_ipv4(Ip), + hole_map => undefined, + v6_info => V6InfoMap + }. + +network_metrics(#state{network_id = NetworkId, endpoint_table = EndpointTable}) -> + ProcInfo = maps:from_list(process_info(self(), [message_queue_len, memory, reductions])), + ProcInfo#{ + network_id => NetworkId, + endpoint_count => endpoint_count(EndpointTable), + channel_metrics => channel_metrics(EndpointTable) + }. + +endpoint_count(Table) -> + case catch ets:info(Table, size) of + Size when is_integer(Size) -> + Size; + _ -> + 0 + end. + +channel_metrics(Table) -> + lists:foldl(fun({_Mac, #endpoint{channel_pid = ChannelPid}}, Acc) -> + case is_pid(ChannelPid) andalso is_process_alive(ChannelPid) of + true -> + ProcInfo = maps:from_list(process_info(ChannelPid, [message_queue_len, memory])), + [ProcInfo#{pid => ChannelPid} | Acc]; + false -> + Acc + end + end, [], list_endpoints(Table)). + +-spec select_endpoint(Table :: ets:tid(), MatchSpec :: ets:match_spec()) -> error | {ok, Mac :: binary(), Endpoint :: #endpoint{}}. +select_endpoint(Table, MatchSpec) -> + case catch ets:select(Table, MatchSpec, 1) of + {[], _Continuation} -> + error; + {[{Mac, Endpoint = #endpoint{}}], _Continuation} -> + {ok, Mac, Endpoint}; + '$end_of_table' -> + error; + {'EXIT', _} -> + error + end. + +-spec same_hole(Hole :: #hole{}, Hole :: #hole{}) -> boolean(). +same_hole(#hole{peer = OldPeer, nat_type = OldNatType}, #hole{peer = Peer, nat_type = NatType}) when OldPeer =:= Peer, OldNatType =:= NatType -> + true; +same_hole(_, _) -> + false. + +-spec gen_session_token() -> binary(). +gen_session_token() -> + Bytes = crypto:strong_rand_bytes(32), + base64:encode(Bytes). + +-spec normalization_algorithm(any()) -> binary(). +normalization_algorithm(<<"aes">>) -> + <<"aes">>; +normalization_algorithm(<<"chacha20">>) -> + <<"chacha20">>; +normalization_algorithm(_) -> + <<"chacha20">>. + +-spec gen_key(Algorithm :: binary()) -> Key :: binary(). +gen_key(<<"aes">>) -> + sdlan_util:rand_byte(32); +gen_key(<<"chacha20">>) -> + sdlan_util:rand_byte(32). + +-spec gen_region_id(IpInt :: integer()) -> integer(). +gen_region_id(IpInt) -> + %% 把整数 IP 转成字符串 + IpStr = integer_to_list(IpInt), + %% 拼接盐 + FullStr = "salt_fG7xQp2BzH9L" ++ IpStr, + time33(FullStr, 5381). + +%% 核心Time33算法 +-spec time33(string(), integer()) -> integer(). +time33([], Hash) -> + Hash band 16#FFFFFFFF; % 32位 +time33([C|Rest], Hash) -> + %% hash = hash * 33 + char + NewHash = ((Hash bsl 5) + Hash) + C, + time33(Rest, NewHash). diff --git a/apps/sdlan/src/sdlan_network_coordinator.erl b/src/sdlan_network_coordinator.erl similarity index 96% rename from apps/sdlan/src/sdlan_network_coordinator.erl rename to src/sdlan_network_coordinator.erl index 2d7053d..1017e14 100644 --- a/apps/sdlan/src/sdlan_network_coordinator.erl +++ b/src/sdlan_network_coordinator.erl @@ -29,7 +29,7 @@ %%% API %%%=================================================================== --spec attach(NetworkPid :: pid(), ThrottleKey :: atom()) -> no_return(). +-spec attach(NetworkPid :: pid(), ThrottleKey :: atom()) -> ok. attach(NetworkPid, ThrottleKey) when is_pid(NetworkPid), is_atom(ThrottleKey) -> gen_server:cast(?SERVER, {attach, NetworkPid, ThrottleKey}). @@ -91,7 +91,7 @@ handle_cast({attach, NetworkPid, ThrottleKey}, State = #state{network_map = Netw {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). -handle_info({timeout, _, release_ticker}, State = #state{network_map = ChannelMap}) -> +handle_info({timeout, _, release_ticker}, State = #state{network_map = NetworkMap}) -> %% 让渡资源定时器 erlang:start_timer(100, self(), release_ticker), AccReleaseCount = lists:foldl(fun(ThrottleKey, Acc) -> @@ -103,7 +103,7 @@ handle_info({timeout, _, release_ticker}, State = #state{network_map = ChannelMa {limit_exceeded, 0, _} -> Acc end - end, 0, maps:keys(ChannelMap)), + end, 0, maps:values(NetworkMap)), % logger:debug("[sdlan_network_coordinator] can release count is: ~p", [AccReleaseCount]), {noreply, State#state{release_count = AccReleaseCount}}; handle_info({'DOWN', _, process, NetworkPid, Reason}, State = #state{network_map = NetworkMap}) -> diff --git a/src/sdlan_network_sup.erl b/src/sdlan_network_sup.erl new file mode 100644 index 0000000..62bbc25 --- /dev/null +++ b/src/sdlan_network_sup.erl @@ -0,0 +1,191 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2024, +%%% @doc +%%% +%%% @end +%%% Created : 27. 3月 2024 15:12 +%%%------------------------------------------------------------------- +-module(sdlan_network_sup). +-author("anlicheng"). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). +-export([ensure_network_started/1, delete_network/1, get_all_networks/0, start_network/1, reallocate_bind_width/0]). + +%% Supervisor callbacks +-export([init/1]). + +-define(SERVER, ?MODULE). + +%%%=================================================================== +%%% API functions +%%%=================================================================== + +%% @doc Starts the supervisor +-spec(start_link() -> {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + +%%%=================================================================== +%%% Supervisor callbacks +%%%=================================================================== + +%% @private +%% @doc Whenever a supervisor is started using supervisor:start_link/[2,3], +%% this function is called by the new process to find out about +%% restart strategy, maximum restart frequency and child +%% specifications. +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore + | {stop, Reason :: term()}. +init([]) -> + SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, + case sdlan_api:get_all_networks() of + {ok, NetworkIds} -> + Specs = lists:filtermap(fun load_child_spec/1, NetworkIds), + set_network_bind(length(Specs)), + + {ok, {SupFlags, Specs}}; + {error, Reason} -> + logger:warning("[sdlan_network_sup] load all networks error: ~p", [Reason]), + {stop, {load_networks_failed, Reason}} + end. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +-spec ensure_network_started(Id :: integer()) -> {ok, Pid :: pid()} | {error, Reason :: any()}. +ensure_network_started(Id) when is_integer(Id) -> + case sdlan_network:get_pid(Id) of + undefined -> + case child_spec(Id) of + {ok, Spec} -> + start_child(Spec); + {error, Reason} -> + {error, Reason} + end; + Pid when is_pid(Pid) -> + {ok, Pid} + end. + +-spec start_network(Id :: integer()) -> {ok, Pid :: pid()} | {error, Reason :: any()}. +start_network(Id) when is_integer(Id) -> + case child_spec(Id) of + {ok, Spec} -> + start_child(Spec); + {error, Reason} -> + {error, Reason} + end. + +-spec start_child(Spec :: map()) -> {ok, Pid :: pid()} | {error, Reason :: any()}. +start_child(Spec) -> + case supervisor:start_child(?MODULE, Spec) of + {ok, Pid} when is_pid(Pid) -> + {ok, Pid}; + {ok, undefined} -> + {error, ignored}; + {error, {'already_started', Pid}} when is_pid(Pid) -> + {ok, Pid}; + {error, Error} -> + {error, Error} + end. + +-spec get_all_networks() -> [pid()]. +get_all_networks() -> + lists:map(fun({_Id, ChildPid, _Type, _Modules}) -> ChildPid end, supervisor:which_children(?MODULE)). + +%% 重新分配网络带宽 +-spec reallocate_bind_width() -> term(). +reallocate_bind_width() -> + ChildPids = lists:map(fun({_Id, ChildPid, _Type, _Modules}) -> ChildPid end, supervisor:which_children(?MODULE)), + set_network_bind(length(ChildPids)). + +-spec delete_network(NetworkId :: integer()) -> ok | {error, Reason :: any()}. +delete_network(NetworkId) when is_integer(NetworkId) -> + ChildId = sdlan_network:get_name(NetworkId), + case supervisor:terminate_child(?MODULE, ChildId) of + ok -> + supervisor:delete_child(?MODULE, ChildId); + Error -> + Error + end. + +-spec child_spec(Id :: integer()) -> {ok, map()} | {error, Reason :: any()}. +child_spec(Id) when is_integer(Id) -> + case load_network_data(Id) of + {ok, NetworkData} -> + Name = sdlan_network:get_name(Id), + {ok, #{ + id => Name, + start => {sdlan_network, start_link, [Name, NetworkData]}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['sdlan_network'] + }}; + {error, Reason} -> + {error, Reason} + end. + +-spec load_child_spec(Id :: integer()) -> {true, map()} | false. +load_child_spec(Id) -> + case child_spec(Id) of + {ok, Spec} -> + {true, Spec}; + {error, Reason} -> + logger:warning("[sdlan_network_sup] skip network: ~p, reason: ~p", [Id, Reason]), + false + end. + +-spec load_network_data(Id :: integer()) -> {ok, tuple()} | {error, Reason :: any()}. +load_network_data(Id) when is_integer(Id) -> + case sdlan_api:get_network(Id) of + {ok, #{<<"ipaddr">> := Null}} when Null == <<"null">>; Null == <<"NULL">> -> + {error, <<"ipaddrr is null">>}; + {ok, #{<<"id">> := NetworkId}} when NetworkId =/= Id -> + {error, {network_id_mismatch, Id, NetworkId}}; + {ok, NetworkInfo = #{<<"id">> := Id, <<"name">> := Name, <<"domain">> := Domain, + <<"algorithm">> := Algorithm, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} -> + logger:debug("[sdlan_network_sup] load network info: ~p", [NetworkInfo]), + case parse_ipaddr(IpAddr0) of + {ok, IpAddr, MaskLen} -> + {ok, {network, Id, Name, Domain, IpAddr, MaskLen, OwnerId, Algorithm}}; + {error, Reason} -> + {error, Reason} + end; + {ok, NetworkInfo} -> + {error, {invalid_network_info, NetworkInfo}}; + {error, Reason} -> + logger:warning("[sdlan_network_sup] load network: ~p, get error: ~p", [Id, Reason]), + {error, Reason} + end. + +%% 解析IpAddr: <<"192.168.172/24">> +-spec parse_ipaddr(IpAddr0 :: binary()) -> {ok, IpAddr :: binary(), MaskLen :: integer()} | {error, Reason :: any()}. +parse_ipaddr(IpAddr0) when is_binary(IpAddr0) -> + try + case binary:split(IpAddr0, <<"/">>) of + [IpAddr, MaskLen] -> + {ok, IpAddr, binary_to_integer(MaskLen)}; + _ -> + {ok, IpAddr0, 24} + end + catch + _:_ -> + {error, {invalid_ipaddr, IpAddr0}} + end; +parse_ipaddr(IpAddr0) -> + {error, {invalid_ipaddr, IpAddr0}}. + +set_network_bind(0) -> + ok; +set_network_bind(Count) when is_integer(Count) -> + {ok, BindWidth} = application:get_env(sdlan, band_width), + NetworkBindWidth = BindWidth div Count, + application:set_env(sdlan, network_bind_width, NetworkBindWidth), + throttle:setup(sdlan_network, NetworkBindWidth, per_second). diff --git a/src/sdlan_pb.erl b/src/sdlan_pb.erl new file mode 100644 index 0000000..379aff4 --- /dev/null +++ b/src/sdlan_pb.erl @@ -0,0 +1,4849 @@ +%% -*- coding: utf-8 -*- +%% @private +%% Automatically @generated, do not edit +%% Generated by gpb_compile version 4.21.7 +%% Version source: file +-module(sdlan_pb). + +-export([encode_msg/1, encode_msg/2, encode_msg/3]). +-export([decode_msg/2, decode_msg/3]). +-export([merge_msgs/2, merge_msgs/3, merge_msgs/4]). +-export([verify_msg/1, verify_msg/2, verify_msg/3]). +-export([get_msg_defs/0]). +-export([get_msg_names/0]). +-export([get_group_names/0]). +-export([get_msg_or_group_names/0]). +-export([get_enum_names/0]). +-export([find_msg_def/1, fetch_msg_def/1]). +-export([find_enum_def/1, fetch_enum_def/1]). +-export([enum_symbol_by_value/2, enum_value_by_symbol/2]). +-export([get_service_names/0]). +-export([get_service_def/1]). +-export([get_rpc_names/1]). +-export([find_rpc_def/2, fetch_rpc_def/2]). +-export([fqbin_to_service_name/1]). +-export([service_name_to_fqbin/1]). +-export([fqbins_to_service_and_rpc_name/2]). +-export([service_and_rpc_name_to_fqbins/2]). +-export([fqbin_to_msg_name/1]). +-export([msg_name_to_fqbin/1]). +-export([fqbin_to_enum_name/1]). +-export([enum_name_to_fqbin/1]). +-export([get_package_name/0]). +-export([uses_packages/0]). +-export([source_basename/0]). +-export([get_all_source_basenames/0]). +-export([get_all_proto_names/0]). +-export([get_msg_containment/1]). +-export([get_pkg_containment/1]). +-export([get_service_containment/1]). +-export([get_rpc_containment/1]). +-export([get_enum_containment/1]). +-export([get_proto_by_msg_name_as_fqbin/1]). +-export([get_proto_by_service_name_as_fqbin/1]). +-export([get_proto_by_enum_name_as_fqbin/1]). +-export([get_protos_by_pkg_name_as_fqbin/1]). +-export([gpb_version_as_string/0, gpb_version_as_list/0]). +-export([gpb_version_source/0]). + +-include("sdlan_pb.hrl"). +-include_lib("gpb/include/gpb.hrl"). + +%% enumerated types + +-export_type([]). + +%% message types +-type 'SDLV4Info'() :: #'SDLV4Info'{}. + +-type 'SDLV6Info'() :: #'SDLV6Info'{}. + +-type 'SDLV6AssistProbe'() :: #'SDLV6AssistProbe'{}. + +-type 'SDLV6AssistProbeReply'() :: #'SDLV6AssistProbeReply'{}. + +-type 'SDLWelcome'() :: #'SDLWelcome'{}. + +-type 'SDLRegisterSuper'() :: #'SDLRegisterSuper'{}. + +-type 'SDLRegisterSuperAck'() :: #'SDLRegisterSuperAck'{}. + +-type 'SDLRegisterSuperNak'() :: #'SDLRegisterSuperNak'{}. + +-type 'SDLQueryInfo'() :: #'SDLQueryInfo'{}. + +-type 'SDLPeerInfo'() :: #'SDLPeerInfo'{}. + +-type 'SDLArpRequest'() :: #'SDLArpRequest'{}. + +-type 'SDLArpResponse'() :: #'SDLArpResponse'{}. + +-type 'SDLPolicyRequest'() :: #'SDLPolicyRequest'{}. + +-type 'SDLPolicyResponse'() :: #'SDLPolicyResponse'{}. + +-type 'SDLEvent.NatChanged'() :: #'SDLEvent.NatChanged'{}. + +-type 'SDLEvent.SendRegister'() :: #'SDLEvent.SendRegister'{}. + +-type 'SDLEvent.NetworkShutdown'() :: #'SDLEvent.NetworkShutdown'{}. + +-type 'SDLEvent'() :: #'SDLEvent'{}. + +-type 'SDLCommand.ExitNodeControl'() :: #'SDLCommand.ExitNodeControl'{}. + +-type 'SDLCommand'() :: #'SDLCommand'{}. + +-type 'SDLCommandAck'() :: #'SDLCommandAck'{}. + +-type 'SDLStunRequest'() :: #'SDLStunRequest'{}. + +-type 'SDLStunReply'() :: #'SDLStunReply'{}. + +-type 'SDLData'() :: #'SDLData'{}. + +-type 'SDLStunProbe'() :: #'SDLStunProbe'{}. + +-type 'SDLStunProbeReply'() :: #'SDLStunProbeReply'{}. + +-type 'SDLRegister'() :: #'SDLRegister'{}. + +-type 'SDLRegisterAck'() :: #'SDLRegisterAck'{}. + +-export_type(['SDLV4Info'/0, 'SDLV6Info'/0, 'SDLV6AssistProbe'/0, 'SDLV6AssistProbeReply'/0, 'SDLWelcome'/0, 'SDLRegisterSuper'/0, 'SDLRegisterSuperAck'/0, 'SDLRegisterSuperNak'/0, 'SDLQueryInfo'/0, 'SDLPeerInfo'/0, 'SDLArpRequest'/0, 'SDLArpResponse'/0, 'SDLPolicyRequest'/0, 'SDLPolicyResponse'/0, 'SDLEvent.NatChanged'/0, 'SDLEvent.SendRegister'/0, 'SDLEvent.NetworkShutdown'/0, 'SDLEvent'/0, 'SDLCommand.ExitNodeControl'/0, 'SDLCommand'/0, 'SDLCommandAck'/0, 'SDLStunRequest'/0, 'SDLStunReply'/0, 'SDLData'/0, 'SDLStunProbe'/0, 'SDLStunProbeReply'/0, 'SDLRegister'/0, 'SDLRegisterAck'/0]). +-type '$msg_name'() :: 'SDLV4Info' | 'SDLV6Info' | 'SDLV6AssistProbe' | 'SDLV6AssistProbeReply' | 'SDLWelcome' | 'SDLRegisterSuper' | 'SDLRegisterSuperAck' | 'SDLRegisterSuperNak' | 'SDLQueryInfo' | 'SDLPeerInfo' | 'SDLArpRequest' | 'SDLArpResponse' | 'SDLPolicyRequest' | 'SDLPolicyResponse' | 'SDLEvent.NatChanged' | 'SDLEvent.SendRegister' | 'SDLEvent.NetworkShutdown' | 'SDLEvent' | 'SDLCommand.ExitNodeControl' | 'SDLCommand' | 'SDLCommandAck' | 'SDLStunRequest' | 'SDLStunReply' | 'SDLData' | 'SDLStunProbe' | 'SDLStunProbeReply' | 'SDLRegister' | 'SDLRegisterAck'. +-type '$msg'() :: 'SDLV4Info'() | 'SDLV6Info'() | 'SDLV6AssistProbe'() | 'SDLV6AssistProbeReply'() | 'SDLWelcome'() | 'SDLRegisterSuper'() | 'SDLRegisterSuperAck'() | 'SDLRegisterSuperNak'() | 'SDLQueryInfo'() | 'SDLPeerInfo'() | 'SDLArpRequest'() | 'SDLArpResponse'() | 'SDLPolicyRequest'() | 'SDLPolicyResponse'() | 'SDLEvent.NatChanged'() | 'SDLEvent.SendRegister'() | 'SDLEvent.NetworkShutdown'() | 'SDLEvent'() | 'SDLCommand.ExitNodeControl'() | 'SDLCommand'() | 'SDLCommandAck'() | 'SDLStunRequest'() | 'SDLStunReply'() | 'SDLData'() | 'SDLStunProbe'() | 'SDLStunProbeReply'() | 'SDLRegister'() | 'SDLRegisterAck'(). +-export_type(['$msg_name'/0, '$msg'/0]). + +-if(?OTP_RELEASE >= 24). +-dialyzer({no_underspecs, encode_msg/1}). +-endif. +-spec encode_msg('$msg'()) -> binary(). +encode_msg(Msg) when tuple_size(Msg) >= 1 -> encode_msg(Msg, element(1, Msg), []). + +-if(?OTP_RELEASE >= 24). +-dialyzer({no_underspecs, encode_msg/2}). +-endif. +-spec encode_msg('$msg'(), '$msg_name'() | list()) -> binary(). +encode_msg(Msg, MsgName) when is_atom(MsgName) -> encode_msg(Msg, MsgName, []); +encode_msg(Msg, Opts) when tuple_size(Msg) >= 1, is_list(Opts) -> encode_msg(Msg, element(1, Msg), Opts). + +-if(?OTP_RELEASE >= 24). +-dialyzer({no_underspecs, encode_msg/3}). +-endif. +-spec encode_msg('$msg'(), '$msg_name'(), list()) -> binary(). +encode_msg(Msg, MsgName, Opts) -> + case proplists:get_bool(verify, Opts) of + true -> verify_msg(Msg, MsgName, Opts); + false -> ok + end, + TrUserData = proplists:get_value(user_data, Opts), + case MsgName of + 'SDLV4Info' -> encode_msg_SDLV4Info(id(Msg, TrUserData), TrUserData); + 'SDLV6Info' -> encode_msg_SDLV6Info(id(Msg, TrUserData), TrUserData); + 'SDLV6AssistProbe' -> encode_msg_SDLV6AssistProbe(id(Msg, TrUserData), TrUserData); + 'SDLV6AssistProbeReply' -> encode_msg_SDLV6AssistProbeReply(id(Msg, TrUserData), TrUserData); + 'SDLWelcome' -> encode_msg_SDLWelcome(id(Msg, TrUserData), TrUserData); + 'SDLRegisterSuper' -> encode_msg_SDLRegisterSuper(id(Msg, TrUserData), TrUserData); + 'SDLRegisterSuperAck' -> encode_msg_SDLRegisterSuperAck(id(Msg, TrUserData), TrUserData); + 'SDLRegisterSuperNak' -> encode_msg_SDLRegisterSuperNak(id(Msg, TrUserData), TrUserData); + 'SDLQueryInfo' -> encode_msg_SDLQueryInfo(id(Msg, TrUserData), TrUserData); + 'SDLPeerInfo' -> encode_msg_SDLPeerInfo(id(Msg, TrUserData), TrUserData); + 'SDLArpRequest' -> encode_msg_SDLArpRequest(id(Msg, TrUserData), TrUserData); + 'SDLArpResponse' -> encode_msg_SDLArpResponse(id(Msg, TrUserData), TrUserData); + 'SDLPolicyRequest' -> encode_msg_SDLPolicyRequest(id(Msg, TrUserData), TrUserData); + 'SDLPolicyResponse' -> encode_msg_SDLPolicyResponse(id(Msg, TrUserData), TrUserData); + 'SDLEvent.NatChanged' -> 'encode_msg_SDLEvent.NatChanged'(id(Msg, TrUserData), TrUserData); + 'SDLEvent.SendRegister' -> 'encode_msg_SDLEvent.SendRegister'(id(Msg, TrUserData), TrUserData); + 'SDLEvent.NetworkShutdown' -> 'encode_msg_SDLEvent.NetworkShutdown'(id(Msg, TrUserData), TrUserData); + 'SDLEvent' -> encode_msg_SDLEvent(id(Msg, TrUserData), TrUserData); + 'SDLCommand.ExitNodeControl' -> 'encode_msg_SDLCommand.ExitNodeControl'(id(Msg, TrUserData), TrUserData); + 'SDLCommand' -> encode_msg_SDLCommand(id(Msg, TrUserData), TrUserData); + 'SDLCommandAck' -> encode_msg_SDLCommandAck(id(Msg, TrUserData), TrUserData); + 'SDLStunRequest' -> encode_msg_SDLStunRequest(id(Msg, TrUserData), TrUserData); + 'SDLStunReply' -> encode_msg_SDLStunReply(id(Msg, TrUserData), TrUserData); + 'SDLData' -> encode_msg_SDLData(id(Msg, TrUserData), TrUserData); + 'SDLStunProbe' -> encode_msg_SDLStunProbe(id(Msg, TrUserData), TrUserData); + 'SDLStunProbeReply' -> encode_msg_SDLStunProbeReply(id(Msg, TrUserData), TrUserData); + 'SDLRegister' -> encode_msg_SDLRegister(id(Msg, TrUserData), TrUserData); + 'SDLRegisterAck' -> encode_msg_SDLRegisterAck(id(Msg, TrUserData), TrUserData) + end. + + +encode_msg_SDLV4Info(Msg, TrUserData) -> encode_msg_SDLV4Info(Msg, <<>>, TrUserData). + + +encode_msg_SDLV4Info(#'SDLV4Info'{port = F1, v4 = F2, nat_type = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end, + if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end. + +encode_msg_SDLV6Info(Msg, TrUserData) -> encode_msg_SDLV6Info(Msg, <<>>, TrUserData). + + +encode_msg_SDLV6Info(#'SDLV6Info'{port = F1, v6 = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end. + +encode_msg_SDLV6AssistProbe(Msg, TrUserData) -> encode_msg_SDLV6AssistProbe(Msg, <<>>, TrUserData). + + +encode_msg_SDLV6AssistProbe(#'SDLV6AssistProbe'{pkt_id = F1}, Bin, TrUserData) -> + if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end. + +encode_msg_SDLV6AssistProbeReply(Msg, TrUserData) -> encode_msg_SDLV6AssistProbeReply(Msg, <<>>, TrUserData). + + +encode_msg_SDLV6AssistProbeReply(#'SDLV6AssistProbeReply'{pkt_id = F1, v6_info = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= undefined -> B1; + true -> e_mfield_SDLV6AssistProbeReply_v6_info(TrF2, <>, TrUserData) + end + end + end. + +encode_msg_SDLWelcome(Msg, TrUserData) -> encode_msg_SDLWelcome(Msg, <<>>, TrUserData). + + +encode_msg_SDLWelcome(#'SDLWelcome'{version = F1, max_bidi_streams = F2, max_packet_size = F3, heartbeat_sec = F4, ipv6_assist = F5}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end, + B4 = if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + if TrF4 =:= 0 -> B3; + true -> e_varint(TrF4, <>, TrUserData) + end + end + end, + if F5 == undefined -> B4; + true -> + begin + TrF5 = id(F5, TrUserData), + if TrF5 =:= undefined -> B4; + true -> e_mfield_SDLWelcome_ipv6_assist(TrF5, <>, TrUserData) + end + end + end. + +encode_msg_SDLRegisterSuper(Msg, TrUserData) -> encode_msg_SDLRegisterSuper(Msg, <<>>, TrUserData). + + +encode_msg_SDLRegisterSuper(#'SDLRegisterSuper'{client_id = F1, network_id = F2, mac = F3, ip = F4, mask_len = F5, hostname = F6, pub_key = F7, access_token = F8}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case is_empty_string(TrF1) of + true -> Bin; + false -> e_type_string(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case iolist_size(TrF3) of + 0 -> B2; + _ -> e_type_bytes(TrF3, <>, TrUserData) + end + end + end, + B4 = if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + if TrF4 =:= 0 -> B3; + true -> e_varint(TrF4, <>, TrUserData) + end + end + end, + B5 = if F5 == undefined -> B4; + true -> + begin + TrF5 = id(F5, TrUserData), + if TrF5 =:= 0 -> B4; + true -> e_varint(TrF5, <>, TrUserData) + end + end + end, + B6 = if F6 == undefined -> B5; + true -> + begin + TrF6 = id(F6, TrUserData), + case is_empty_string(TrF6) of + true -> B5; + false -> e_type_string(TrF6, <>, TrUserData) + end + end + end, + B7 = if F7 == undefined -> B6; + true -> + begin + TrF7 = id(F7, TrUserData), + case is_empty_string(TrF7) of + true -> B6; + false -> e_type_string(TrF7, <>, TrUserData) + end + end + end, + if F8 == undefined -> B7; + true -> + begin + TrF8 = id(F8, TrUserData), + case is_empty_string(TrF8) of + true -> B7; + false -> e_type_string(TrF8, <>, TrUserData) + end + end + end. + +encode_msg_SDLRegisterSuperAck(Msg, TrUserData) -> encode_msg_SDLRegisterSuperAck(Msg, <<>>, TrUserData). + + +encode_msg_SDLRegisterSuperAck(#'SDLRegisterSuperAck'{algorithm = F1, key = F2, region_id = F3, session_token = F4}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case is_empty_string(TrF1) of + true -> Bin; + false -> e_type_string(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end, + if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + case iolist_size(TrF4) of + 0 -> B3; + _ -> e_type_bytes(TrF4, <>, TrUserData) + end + end + end. + +encode_msg_SDLRegisterSuperNak(Msg, TrUserData) -> encode_msg_SDLRegisterSuperNak(Msg, <<>>, TrUserData). + + +encode_msg_SDLRegisterSuperNak(#'SDLRegisterSuperNak'{error_code = F1, error_message = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case is_empty_string(TrF2) of + true -> B1; + false -> e_type_string(TrF2, <>, TrUserData) + end + end + end. + +encode_msg_SDLQueryInfo(Msg, TrUserData) -> encode_msg_SDLQueryInfo(Msg, <<>>, TrUserData). + + +encode_msg_SDLQueryInfo(#'SDLQueryInfo'{dst_mac = F1}, Bin, TrUserData) -> + if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case iolist_size(TrF1) of + 0 -> Bin; + _ -> e_type_bytes(TrF1, <>, TrUserData) + end + end + end. + +encode_msg_SDLPeerInfo(Msg, TrUserData) -> encode_msg_SDLPeerInfo(Msg, <<>>, TrUserData). + + +encode_msg_SDLPeerInfo(#'SDLPeerInfo'{dst_mac = F1, v4_info = F2, v6_info = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case iolist_size(TrF1) of + 0 -> Bin; + _ -> e_type_bytes(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> begin TrF2 = id(F2, TrUserData), e_mfield_SDLPeerInfo_v4_info(TrF2, <>, TrUserData) end + end, + if F3 == undefined -> B2; + true -> begin TrF3 = id(F3, TrUserData), e_mfield_SDLPeerInfo_v6_info(TrF3, <>, TrUserData) end + end. + +encode_msg_SDLArpRequest(Msg, TrUserData) -> encode_msg_SDLArpRequest(Msg, <<>>, TrUserData). + + +encode_msg_SDLArpRequest(#'SDLArpRequest'{target_ip = F1, origin_ip = F2, context = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case iolist_size(TrF3) of + 0 -> B2; + _ -> e_type_bytes(TrF3, <>, TrUserData) + end + end + end. + +encode_msg_SDLArpResponse(Msg, TrUserData) -> encode_msg_SDLArpResponse(Msg, <<>>, TrUserData). + + +encode_msg_SDLArpResponse(#'SDLArpResponse'{target_ip = F1, target_mac = F2, origin_ip = F3, context = F4}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end, + if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + case iolist_size(TrF4) of + 0 -> B3; + _ -> e_type_bytes(TrF4, <>, TrUserData) + end + end + end. + +encode_msg_SDLPolicyRequest(Msg, TrUserData) -> encode_msg_SDLPolicyRequest(Msg, <<>>, TrUserData). + + +encode_msg_SDLPolicyRequest(#'SDLPolicyRequest'{src_identity_id = F1, dst_identity_id = F2, version = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end. + +encode_msg_SDLPolicyResponse(Msg, TrUserData) -> encode_msg_SDLPolicyResponse(Msg, <<>>, TrUserData). + + +encode_msg_SDLPolicyResponse(#'SDLPolicyResponse'{src_identity_id = F1, dst_identity_id = F2, version = F3, rules = F4}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end, + if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + case iolist_size(TrF4) of + 0 -> B3; + _ -> e_type_bytes(TrF4, <>, TrUserData) + end + end + end. + +'encode_msg_SDLEvent.NatChanged'(Msg, TrUserData) -> 'encode_msg_SDLEvent.NatChanged'(Msg, <<>>, TrUserData). + + +'encode_msg_SDLEvent.NatChanged'(#'SDLEvent.NatChanged'{mac = F1, ip = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case iolist_size(TrF1) of + 0 -> Bin; + _ -> e_type_bytes(TrF1, <>, TrUserData) + end + end + end, + if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end. + +'encode_msg_SDLEvent.SendRegister'(Msg, TrUserData) -> 'encode_msg_SDLEvent.SendRegister'(Msg, <<>>, TrUserData). + + +'encode_msg_SDLEvent.SendRegister'(#'SDLEvent.SendRegister'{dst_mac = F1, nat_ip = F2, nat_port = F3, nat_type = F4, v6_info = F5}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case iolist_size(TrF1) of + 0 -> Bin; + _ -> e_type_bytes(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end, + B4 = if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + if TrF4 =:= 0 -> B3; + true -> e_varint(TrF4, <>, TrUserData) + end + end + end, + if F5 == undefined -> B4; + true -> begin TrF5 = id(F5, TrUserData), 'e_mfield_SDLEvent.SendRegister_v6_info'(TrF5, <>, TrUserData) end + end. + +'encode_msg_SDLEvent.NetworkShutdown'(Msg, TrUserData) -> 'encode_msg_SDLEvent.NetworkShutdown'(Msg, <<>>, TrUserData). + + +'encode_msg_SDLEvent.NetworkShutdown'(#'SDLEvent.NetworkShutdown'{message = F1}, Bin, TrUserData) -> + if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case is_empty_string(TrF1) of + true -> Bin; + false -> e_type_string(TrF1, <>, TrUserData) + end + end + end. + +encode_msg_SDLEvent(Msg, TrUserData) -> encode_msg_SDLEvent(Msg, <<>>, TrUserData). + + +encode_msg_SDLEvent(#'SDLEvent'{event = F1}, Bin, TrUserData) -> + if F1 =:= undefined -> Bin; + true -> + case id(F1, TrUserData) of + {nat_changed, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_mfield_SDLEvent_nat_changed(TrTF1, <>, TrUserData) end; + {send_register, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_mfield_SDLEvent_send_register(TrTF1, <>, TrUserData) end; + {shutdown, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_mfield_SDLEvent_shutdown(TrTF1, <>, TrUserData) end + end + end. + +'encode_msg_SDLCommand.ExitNodeControl'(Msg, TrUserData) -> 'encode_msg_SDLCommand.ExitNodeControl'(Msg, <<>>, TrUserData). + + +'encode_msg_SDLCommand.ExitNodeControl'(#'SDLCommand.ExitNodeControl'{action = F1, remark = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_type_int32(TrF1, <>, TrUserData) + end + end + end, + if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case is_empty_string(TrF2) of + true -> B1; + false -> e_type_string(TrF2, <>, TrUserData) + end + end + end. + +encode_msg_SDLCommand(Msg, TrUserData) -> encode_msg_SDLCommand(Msg, <<>>, TrUserData). + + +encode_msg_SDLCommand(#'SDLCommand'{pkt_id = F1, command = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + if F2 =:= undefined -> B1; + true -> case id(F2, TrUserData) of {exit_node, TF2} -> begin TrTF2 = id(TF2, TrUserData), e_mfield_SDLCommand_exit_node(TrTF2, <>, TrUserData) end end + end. + +encode_msg_SDLCommandAck(Msg, TrUserData) -> encode_msg_SDLCommandAck(Msg, <<>>, TrUserData). + + +encode_msg_SDLCommandAck(#'SDLCommandAck'{pkt_id = F1, code = F2, message = F3, data = F4}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_type_int32(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case is_empty_string(TrF3) of + true -> B2; + false -> e_type_string(TrF3, <>, TrUserData) + end + end + end, + if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + case iolist_size(TrF4) of + 0 -> B3; + _ -> e_type_bytes(TrF4, <>, TrUserData) + end + end + end. + +encode_msg_SDLStunRequest(Msg, TrUserData) -> encode_msg_SDLStunRequest(Msg, <<>>, TrUserData). + + +encode_msg_SDLStunRequest(#'SDLStunRequest'{client_id = F1, network_id = F2, mac = F3, ip = F4, nat_type = F5, v6_info = F6, session_token = F7}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case is_empty_string(TrF1) of + true -> Bin; + false -> e_type_string(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case iolist_size(TrF3) of + 0 -> B2; + _ -> e_type_bytes(TrF3, <>, TrUserData) + end + end + end, + B4 = if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + if TrF4 =:= 0 -> B3; + true -> e_varint(TrF4, <>, TrUserData) + end + end + end, + B5 = if F5 == undefined -> B4; + true -> + begin + TrF5 = id(F5, TrUserData), + if TrF5 =:= 0 -> B4; + true -> e_varint(TrF5, <>, TrUserData) + end + end + end, + B6 = if F6 == undefined -> B5; + true -> begin TrF6 = id(F6, TrUserData), e_mfield_SDLStunRequest_v6_info(TrF6, <>, TrUserData) end + end, + if F7 == undefined -> B6; + true -> + begin + TrF7 = id(F7, TrUserData), + case iolist_size(TrF7) of + 0 -> B6; + _ -> e_type_bytes(TrF7, <>, TrUserData) + end + end + end. + +encode_msg_SDLStunReply(_Msg, _TrUserData) -> <<>>. + +encode_msg_SDLData(Msg, TrUserData) -> encode_msg_SDLData(Msg, <<>>, TrUserData). + + +encode_msg_SDLData(#'SDLData'{network_id = F1, src_mac = F2, dst_mac = F3, is_p2p = F4, ttl = F5, data = F6, session_token = F7, identity_id = F8}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case iolist_size(TrF3) of + 0 -> B2; + _ -> e_type_bytes(TrF3, <>, TrUserData) + end + end + end, + B4 = if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + if TrF4 =:= false -> B3; + true -> e_type_bool(TrF4, <>, TrUserData) + end + end + end, + B5 = if F5 == undefined -> B4; + true -> + begin + TrF5 = id(F5, TrUserData), + if TrF5 =:= 0 -> B4; + true -> e_varint(TrF5, <>, TrUserData) + end + end + end, + B6 = if F6 == undefined -> B5; + true -> + begin + TrF6 = id(F6, TrUserData), + case iolist_size(TrF6) of + 0 -> B5; + _ -> e_type_bytes(TrF6, <>, TrUserData) + end + end + end, + B7 = if F7 == undefined -> B6; + true -> + begin + TrF7 = id(F7, TrUserData), + case iolist_size(TrF7) of + 0 -> B6; + _ -> e_type_bytes(TrF7, <>, TrUserData) + end + end + end, + if F8 == undefined -> B7; + true -> + begin + TrF8 = id(F8, TrUserData), + if TrF8 =:= 0 -> B7; + true -> e_varint(TrF8, <>, TrUserData) + end + end + end. + +encode_msg_SDLStunProbe(Msg, TrUserData) -> encode_msg_SDLStunProbe(Msg, <<>>, TrUserData). + + +encode_msg_SDLStunProbe(#'SDLStunProbe'{cookie = F1, attr = F2, step = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end. + +encode_msg_SDLStunProbeReply(Msg, TrUserData) -> encode_msg_SDLStunProbeReply(Msg, <<>>, TrUserData). + + +encode_msg_SDLStunProbeReply(#'SDLStunProbeReply'{cookie = F1, step = F2, port = F3, ip = F4}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + if TrF2 =:= 0 -> B1; + true -> e_varint(TrF2, <>, TrUserData) + end + end + end, + B3 = if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + if TrF3 =:= 0 -> B2; + true -> e_varint(TrF3, <>, TrUserData) + end + end + end, + if F4 == undefined -> B3; + true -> + begin + TrF4 = id(F4, TrUserData), + if TrF4 =:= 0 -> B3; + true -> e_varint(TrF4, <>, TrUserData) + end + end + end. + +encode_msg_SDLRegister(Msg, TrUserData) -> encode_msg_SDLRegister(Msg, <<>>, TrUserData). + + +encode_msg_SDLRegister(#'SDLRegister'{network_id = F1, src_mac = F2, dst_mac = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end, + if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case iolist_size(TrF3) of + 0 -> B2; + _ -> e_type_bytes(TrF3, <>, TrUserData) + end + end + end. + +encode_msg_SDLRegisterAck(Msg, TrUserData) -> encode_msg_SDLRegisterAck(Msg, <<>>, TrUserData). + + +encode_msg_SDLRegisterAck(#'SDLRegisterAck'{network_id = F1, src_mac = F2, dst_mac = F3}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_varint(TrF1, <>, TrUserData) + end + end + end, + B2 = if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case iolist_size(TrF2) of + 0 -> B1; + _ -> e_type_bytes(TrF2, <>, TrUserData) + end + end + end, + if F3 == undefined -> B2; + true -> + begin + TrF3 = id(F3, TrUserData), + case iolist_size(TrF3) of + 0 -> B2; + _ -> e_type_bytes(TrF3, <>, TrUserData) + end + end + end. + +e_mfield_SDLV6AssistProbeReply_v6_info(Msg, Bin, TrUserData) -> + SubBin = encode_msg_SDLV6Info(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLWelcome_ipv6_assist(Msg, Bin, TrUserData) -> + SubBin = encode_msg_SDLV6Info(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLPeerInfo_v4_info(Msg, Bin, TrUserData) -> + SubBin = encode_msg_SDLV4Info(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLPeerInfo_v6_info(Msg, Bin, TrUserData) -> + SubBin = encode_msg_SDLV6Info(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +'e_mfield_SDLEvent.SendRegister_v6_info'(Msg, Bin, TrUserData) -> + SubBin = encode_msg_SDLV6Info(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLEvent_nat_changed(Msg, Bin, TrUserData) -> + SubBin = 'encode_msg_SDLEvent.NatChanged'(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLEvent_send_register(Msg, Bin, TrUserData) -> + SubBin = 'encode_msg_SDLEvent.SendRegister'(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLEvent_shutdown(Msg, Bin, TrUserData) -> + SubBin = 'encode_msg_SDLEvent.NetworkShutdown'(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLCommand_exit_node(Msg, Bin, TrUserData) -> + SubBin = 'encode_msg_SDLCommand.ExitNodeControl'(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_SDLStunRequest_v6_info(Msg, Bin, TrUserData) -> + SubBin = encode_msg_SDLV6Info(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +-compile({nowarn_unused_function,e_type_sint/3}). +e_type_sint(Value, Bin, _TrUserData) when Value >= 0 -> e_varint(Value * 2, Bin); +e_type_sint(Value, Bin, _TrUserData) -> e_varint(Value * -2 - 1, Bin). + +-compile({nowarn_unused_function,e_type_int32/3}). +e_type_int32(Value, Bin, _TrUserData) when 0 =< Value, Value =< 127 -> <>; +e_type_int32(Value, Bin, _TrUserData) -> + <> = <>, + e_varint(N, Bin). + +-compile({nowarn_unused_function,e_type_int64/3}). +e_type_int64(Value, Bin, _TrUserData) when 0 =< Value, Value =< 127 -> <>; +e_type_int64(Value, Bin, _TrUserData) -> + <> = <>, + e_varint(N, Bin). + +-compile({nowarn_unused_function,e_type_bool/3}). +e_type_bool(true, Bin, _TrUserData) -> <>; +e_type_bool(false, Bin, _TrUserData) -> <>; +e_type_bool(1, Bin, _TrUserData) -> <>; +e_type_bool(0, Bin, _TrUserData) -> <>. + +-compile({nowarn_unused_function,e_type_string/3}). +e_type_string(S, Bin, _TrUserData) -> + Utf8 = unicode:characters_to_binary(S), + Bin2 = e_varint(byte_size(Utf8), Bin), + <>. + +-compile({nowarn_unused_function,e_type_bytes/3}). +e_type_bytes(Bytes, Bin, _TrUserData) when is_binary(Bytes) -> + Bin2 = e_varint(byte_size(Bytes), Bin), + <>; +e_type_bytes(Bytes, Bin, _TrUserData) when is_list(Bytes) -> + BytesBin = iolist_to_binary(Bytes), + Bin2 = e_varint(byte_size(BytesBin), Bin), + <>. + +-compile({nowarn_unused_function,e_type_fixed32/3}). +e_type_fixed32(Value, Bin, _TrUserData) -> <>. + +-compile({nowarn_unused_function,e_type_sfixed32/3}). +e_type_sfixed32(Value, Bin, _TrUserData) -> <>. + +-compile({nowarn_unused_function,e_type_fixed64/3}). +e_type_fixed64(Value, Bin, _TrUserData) -> <>. + +-compile({nowarn_unused_function,e_type_sfixed64/3}). +e_type_sfixed64(Value, Bin, _TrUserData) -> <>. + +-compile({nowarn_unused_function,e_type_float/3}). +e_type_float(V, Bin, _) when is_number(V) -> <>; +e_type_float(infinity, Bin, _) -> <>; +e_type_float('-infinity', Bin, _) -> <>; +e_type_float(nan, Bin, _) -> <>. + +-compile({nowarn_unused_function,e_type_double/3}). +e_type_double(V, Bin, _) when is_number(V) -> <>; +e_type_double(infinity, Bin, _) -> <>; +e_type_double('-infinity', Bin, _) -> <>; +e_type_double(nan, Bin, _) -> <>. + +-compile({nowarn_unused_function,e_unknown_elems/2}). +e_unknown_elems([Elem | Rest], Bin) -> + BinR = case Elem of + {varint, FNum, N} -> + BinF = e_varint(FNum bsl 3, Bin), + e_varint(N, BinF); + {length_delimited, FNum, Data} -> + BinF = e_varint(FNum bsl 3 bor 2, Bin), + BinL = e_varint(byte_size(Data), BinF), + <>; + {group, FNum, GroupFields} -> + Bin1 = e_varint(FNum bsl 3 bor 3, Bin), + Bin2 = e_unknown_elems(GroupFields, Bin1), + e_varint(FNum bsl 3 bor 4, Bin2); + {fixed32, FNum, V} -> + BinF = e_varint(FNum bsl 3 bor 5, Bin), + <>; + {fixed64, FNum, V} -> + BinF = e_varint(FNum bsl 3 bor 1, Bin), + <> + end, + e_unknown_elems(Rest, BinR); +e_unknown_elems([], Bin) -> Bin. + +-compile({nowarn_unused_function,e_varint/3}). +e_varint(N, Bin, _TrUserData) -> e_varint(N, Bin). + +-compile({nowarn_unused_function,e_varint/2}). +e_varint(N, Bin) when N =< 127 -> <>; +e_varint(N, Bin) -> + Bin2 = <>, + e_varint(N bsr 7, Bin2). + +is_empty_string("") -> true; +is_empty_string(<<>>) -> true; +is_empty_string(L) when is_list(L) -> not string_has_chars(L); +is_empty_string(B) when is_binary(B) -> false. + +string_has_chars([C | _]) when is_integer(C) -> true; +string_has_chars([H | T]) -> + case string_has_chars(H) of + true -> true; + false -> string_has_chars(T) + end; +string_has_chars(B) when is_binary(B), byte_size(B) =/= 0 -> true; +string_has_chars(C) when is_integer(C) -> true; +string_has_chars(<<>>) -> false; +string_has_chars([]) -> false. + + +decode_msg(Bin, MsgName) when is_binary(Bin) -> decode_msg(Bin, MsgName, []). + +decode_msg(Bin, MsgName, Opts) when is_binary(Bin) -> + TrUserData = proplists:get_value(user_data, Opts), + decode_msg_1_catch(Bin, MsgName, TrUserData). + +-ifdef('OTP_RELEASE'). +decode_msg_1_catch(Bin, MsgName, TrUserData) -> + try decode_msg_2_doit(MsgName, Bin, TrUserData) + catch + error:{gpb_error,_}=Reason:StackTrace -> + erlang:raise(error, Reason, StackTrace); + Class:Reason:StackTrace -> error({gpb_error,{decoding_failure, {Bin, MsgName, {Class, Reason, StackTrace}}}}) + end. +-else. +decode_msg_1_catch(Bin, MsgName, TrUserData) -> + try decode_msg_2_doit(MsgName, Bin, TrUserData) + catch + error:{gpb_error,_}=Reason -> + erlang:raise(error, Reason, + erlang:get_stacktrace()); + Class:Reason -> + StackTrace = erlang:get_stacktrace(), + error({gpb_error,{decoding_failure, {Bin, MsgName, {Class, Reason, StackTrace}}}}) + end. +-endif. + +decode_msg_2_doit('SDLV4Info', Bin, TrUserData) -> id(decode_msg_SDLV4Info(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLV6Info', Bin, TrUserData) -> id(decode_msg_SDLV6Info(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLV6AssistProbe', Bin, TrUserData) -> id(decode_msg_SDLV6AssistProbe(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLV6AssistProbeReply', Bin, TrUserData) -> id(decode_msg_SDLV6AssistProbeReply(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLWelcome', Bin, TrUserData) -> id(decode_msg_SDLWelcome(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLRegisterSuper', Bin, TrUserData) -> id(decode_msg_SDLRegisterSuper(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLRegisterSuperAck', Bin, TrUserData) -> id(decode_msg_SDLRegisterSuperAck(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLRegisterSuperNak', Bin, TrUserData) -> id(decode_msg_SDLRegisterSuperNak(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLQueryInfo', Bin, TrUserData) -> id(decode_msg_SDLQueryInfo(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLPeerInfo', Bin, TrUserData) -> id(decode_msg_SDLPeerInfo(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLArpRequest', Bin, TrUserData) -> id(decode_msg_SDLArpRequest(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLArpResponse', Bin, TrUserData) -> id(decode_msg_SDLArpResponse(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLPolicyRequest', Bin, TrUserData) -> id(decode_msg_SDLPolicyRequest(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLPolicyResponse', Bin, TrUserData) -> id(decode_msg_SDLPolicyResponse(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLEvent.NatChanged', Bin, TrUserData) -> id('decode_msg_SDLEvent.NatChanged'(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLEvent.SendRegister', Bin, TrUserData) -> id('decode_msg_SDLEvent.SendRegister'(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLEvent.NetworkShutdown', Bin, TrUserData) -> id('decode_msg_SDLEvent.NetworkShutdown'(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLEvent', Bin, TrUserData) -> id(decode_msg_SDLEvent(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLCommand.ExitNodeControl', Bin, TrUserData) -> id('decode_msg_SDLCommand.ExitNodeControl'(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLCommand', Bin, TrUserData) -> id(decode_msg_SDLCommand(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLCommandAck', Bin, TrUserData) -> id(decode_msg_SDLCommandAck(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLStunRequest', Bin, TrUserData) -> id(decode_msg_SDLStunRequest(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLStunReply', Bin, TrUserData) -> id(decode_msg_SDLStunReply(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLData', Bin, TrUserData) -> id(decode_msg_SDLData(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLStunProbe', Bin, TrUserData) -> id(decode_msg_SDLStunProbe(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLStunProbeReply', Bin, TrUserData) -> id(decode_msg_SDLStunProbeReply(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLRegister', Bin, TrUserData) -> id(decode_msg_SDLRegister(Bin, TrUserData), TrUserData); +decode_msg_2_doit('SDLRegisterAck', Bin, TrUserData) -> id(decode_msg_SDLRegisterAck(Bin, TrUserData), TrUserData). + + + +decode_msg_SDLV4Info(Bin, TrUserData) -> dfp_read_field_def_SDLV4Info(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), TrUserData). + +dfp_read_field_def_SDLV4Info(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLV4Info_port(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLV4Info(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLV4Info_v4(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLV4Info(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLV4Info_nat_type(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLV4Info(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLV4Info'{port = F@_1, v4 = F@_2, nat_type = F@_3}; +dfp_read_field_def_SDLV4Info(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLV4Info(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLV4Info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLV4Info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLV4Info(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLV4Info_port(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 18 -> d_field_SDLV4Info_v4(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 24 -> d_field_SDLV4Info_nat_type(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLV4Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLV4Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLV4Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLV4Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLV4Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLV4Info(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLV4Info'{port = F@_1, v4 = F@_2, nat_type = F@_3}. + +d_field_SDLV4Info_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLV4Info_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLV4Info_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLV4Info(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLV4Info_v4(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLV4Info_v4(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLV4Info_v4(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLV4Info(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). + +d_field_SDLV4Info_nat_type(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLV4Info_nat_type(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLV4Info_nat_type(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLV4Info(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). + +skip_varint_SDLV4Info(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLV4Info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLV4Info(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLV4Info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLV4Info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLV4Info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLV4Info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLV4Info(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLV4Info(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLV4Info(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLV4Info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLV4Info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLV4Info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLV4Info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +decode_msg_SDLV6Info(Bin, TrUserData) -> dfp_read_field_def_SDLV6Info(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLV6Info(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLV6Info_port(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLV6Info(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLV6Info_v6(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLV6Info(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLV6Info'{port = F@_1, v6 = F@_2}; +dfp_read_field_def_SDLV6Info(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_SDLV6Info(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +dg_read_field_def_SDLV6Info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLV6Info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +dg_read_field_def_SDLV6Info(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLV6Info_port(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 18 -> d_field_SDLV6Info_v6(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLV6Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> skip_64_SDLV6Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> skip_length_delimited_SDLV6Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> skip_group_SDLV6Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> skip_32_SDLV6Info(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +dg_read_field_def_SDLV6Info(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLV6Info'{port = F@_1, v6 = F@_2}. + +d_field_SDLV6Info_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLV6Info_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLV6Info_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLV6Info(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +d_field_SDLV6Info_v6(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLV6Info_v6(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLV6Info_v6(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLV6Info(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). + +skip_varint_SDLV6Info(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_SDLV6Info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +skip_varint_SDLV6Info(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLV6Info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_length_delimited_SDLV6Info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_SDLV6Info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +skip_length_delimited_SDLV6Info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLV6Info(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +skip_group_SDLV6Info(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLV6Info(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +skip_32_SDLV6Info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLV6Info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_64_SDLV6Info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLV6Info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +decode_msg_SDLV6AssistProbe(Bin, TrUserData) -> dfp_read_field_def_SDLV6AssistProbe(Bin, 0, 0, 0, id(0, TrUserData), TrUserData). + +dfp_read_field_def_SDLV6AssistProbe(<<8, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_SDLV6AssistProbe_pkt_id(Rest, Z1, Z2, F, F@_1, TrUserData); +dfp_read_field_def_SDLV6AssistProbe(<<>>, 0, 0, _, F@_1, _) -> #'SDLV6AssistProbe'{pkt_id = F@_1}; +dfp_read_field_def_SDLV6AssistProbe(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_SDLV6AssistProbe(Other, Z1, Z2, F, F@_1, TrUserData). + +dg_read_field_def_SDLV6AssistProbe(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLV6AssistProbe(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +dg_read_field_def_SDLV6AssistProbe(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLV6AssistProbe_pkt_id(Rest, 0, 0, 0, F@_1, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLV6AssistProbe(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 1 -> skip_64_SDLV6AssistProbe(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 2 -> skip_length_delimited_SDLV6AssistProbe(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 3 -> skip_group_SDLV6AssistProbe(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 5 -> skip_32_SDLV6AssistProbe(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) + end + end; +dg_read_field_def_SDLV6AssistProbe(<<>>, 0, 0, _, F@_1, _) -> #'SDLV6AssistProbe'{pkt_id = F@_1}. + +d_field_SDLV6AssistProbe_pkt_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_SDLV6AssistProbe_pkt_id(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +d_field_SDLV6AssistProbe_pkt_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLV6AssistProbe(RestF, 0, 0, F, NewFValue, TrUserData). + +skip_varint_SDLV6AssistProbe(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_SDLV6AssistProbe(Rest, Z1, Z2, F, F@_1, TrUserData); +skip_varint_SDLV6AssistProbe(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLV6AssistProbe(Rest, Z1, Z2, F, F@_1, TrUserData). + +skip_length_delimited_SDLV6AssistProbe(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> skip_length_delimited_SDLV6AssistProbe(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +skip_length_delimited_SDLV6AssistProbe(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLV6AssistProbe(Rest2, 0, 0, F, F@_1, TrUserData). + +skip_group_SDLV6AssistProbe(Bin, _, Z2, FNum, F@_1, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLV6AssistProbe(Rest, 0, Z2, FNum, F@_1, TrUserData). + +skip_32_SDLV6AssistProbe(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLV6AssistProbe(Rest, Z1, Z2, F, F@_1, TrUserData). + +skip_64_SDLV6AssistProbe(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLV6AssistProbe(Rest, Z1, Z2, F, F@_1, TrUserData). + +decode_msg_SDLV6AssistProbeReply(Bin, TrUserData) -> dfp_read_field_def_SDLV6AssistProbeReply(Bin, 0, 0, 0, id(0, TrUserData), id(undefined, TrUserData), TrUserData). + +dfp_read_field_def_SDLV6AssistProbeReply(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLV6AssistProbeReply_pkt_id(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLV6AssistProbeReply(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLV6AssistProbeReply_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLV6AssistProbeReply(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLV6AssistProbeReply'{pkt_id = F@_1, v6_info = F@_2}; +dfp_read_field_def_SDLV6AssistProbeReply(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_SDLV6AssistProbeReply(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +dg_read_field_def_SDLV6AssistProbeReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLV6AssistProbeReply(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +dg_read_field_def_SDLV6AssistProbeReply(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLV6AssistProbeReply_pkt_id(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 18 -> d_field_SDLV6AssistProbeReply_v6_info(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLV6AssistProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> skip_64_SDLV6AssistProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> skip_length_delimited_SDLV6AssistProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> skip_group_SDLV6AssistProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> skip_32_SDLV6AssistProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +dg_read_field_def_SDLV6AssistProbeReply(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLV6AssistProbeReply'{pkt_id = F@_1, v6_info = F@_2}. + +d_field_SDLV6AssistProbeReply_pkt_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLV6AssistProbeReply_pkt_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLV6AssistProbeReply_pkt_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLV6AssistProbeReply(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +d_field_SDLV6AssistProbeReply_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLV6AssistProbeReply_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLV6AssistProbeReply_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_SDLV6Info(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLV6AssistProbeReply(RestF, + 0, + 0, + F, + F@_1, + if Prev == undefined -> NewFValue; + true -> merge_msg_SDLV6Info(Prev, NewFValue, TrUserData) + end, + TrUserData). + +skip_varint_SDLV6AssistProbeReply(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_SDLV6AssistProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +skip_varint_SDLV6AssistProbeReply(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLV6AssistProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_length_delimited_SDLV6AssistProbeReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_SDLV6AssistProbeReply(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +skip_length_delimited_SDLV6AssistProbeReply(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLV6AssistProbeReply(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +skip_group_SDLV6AssistProbeReply(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLV6AssistProbeReply(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +skip_32_SDLV6AssistProbeReply(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLV6AssistProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_64_SDLV6AssistProbeReply(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLV6AssistProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +decode_msg_SDLWelcome(Bin, TrUserData) -> dfp_read_field_def_SDLWelcome(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), id(undefined, TrUserData), TrUserData). + +dfp_read_field_def_SDLWelcome(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_SDLWelcome_version(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_SDLWelcome(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_SDLWelcome_max_bidi_streams(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_SDLWelcome(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_SDLWelcome_max_packet_size(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_SDLWelcome(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_SDLWelcome_heartbeat_sec(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_SDLWelcome(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_SDLWelcome_ipv6_assist(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_SDLWelcome(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #'SDLWelcome'{version = F@_1, max_bidi_streams = F@_2, max_packet_size = F@_3, heartbeat_sec = F@_4, ipv6_assist = F@_5}; +dfp_read_field_def_SDLWelcome(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dg_read_field_def_SDLWelcome(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +dg_read_field_def_SDLWelcome(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLWelcome(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dg_read_field_def_SDLWelcome(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLWelcome_version(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 16 -> d_field_SDLWelcome_max_bidi_streams(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 24 -> d_field_SDLWelcome_max_packet_size(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 32 -> d_field_SDLWelcome_heartbeat_sec(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 42 -> d_field_SDLWelcome_ipv6_assist(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLWelcome(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 1 -> skip_64_SDLWelcome(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 2 -> skip_length_delimited_SDLWelcome(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 3 -> skip_group_SDLWelcome(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 5 -> skip_32_SDLWelcome(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) + end + end; +dg_read_field_def_SDLWelcome(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #'SDLWelcome'{version = F@_1, max_bidi_streams = F@_2, max_packet_size = F@_3, heartbeat_sec = F@_4, ipv6_assist = F@_5}. + +d_field_SDLWelcome_version(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_SDLWelcome_version(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_SDLWelcome_version(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLWelcome(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, TrUserData). + +d_field_SDLWelcome_max_bidi_streams(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_SDLWelcome_max_bidi_streams(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_SDLWelcome_max_bidi_streams(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLWelcome(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData). + +d_field_SDLWelcome_max_packet_size(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_SDLWelcome_max_packet_size(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_SDLWelcome_max_packet_size(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLWelcome(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData). + +d_field_SDLWelcome_heartbeat_sec(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_SDLWelcome_heartbeat_sec(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_SDLWelcome_heartbeat_sec(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLWelcome(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData). + +d_field_SDLWelcome_ipv6_assist(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_SDLWelcome_ipv6_assist(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_SDLWelcome_ipv6_assist(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_SDLV6Info(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLWelcome(RestF, + 0, + 0, + F, + F@_1, + F@_2, + F@_3, + F@_4, + if Prev == undefined -> NewFValue; + true -> merge_msg_SDLV6Info(Prev, NewFValue, TrUserData) + end, + TrUserData). + +skip_varint_SDLWelcome(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> skip_varint_SDLWelcome(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +skip_varint_SDLWelcome(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_SDLWelcome(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +skip_length_delimited_SDLWelcome(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> skip_length_delimited_SDLWelcome(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +skip_length_delimited_SDLWelcome(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLWelcome(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +skip_group_SDLWelcome(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLWelcome(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +skip_32_SDLWelcome(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_SDLWelcome(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +skip_64_SDLWelcome(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_SDLWelcome(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +decode_msg_SDLRegisterSuper(Bin, TrUserData) -> + dfp_read_field_def_SDLRegisterSuper(Bin, 0, 0, 0, id(<<>>, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLRegisterSuper(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_client_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<40, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_mask_len(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<50, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_hostname(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<58, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_pub_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<66, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLRegisterSuper_access_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLRegisterSuper(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> + #'SDLRegisterSuper'{client_id = F@_1, network_id = F@_2, mac = F@_3, ip = F@_4, mask_len = F@_5, hostname = F@_6, pub_key = F@_7, access_token = F@_8}; +dfp_read_field_def_SDLRegisterSuper(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dg_read_field_def_SDLRegisterSuper(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +dg_read_field_def_SDLRegisterSuper(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 32 - 7 -> + dg_read_field_def_SDLRegisterSuper(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dg_read_field_def_SDLRegisterSuper(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> d_field_SDLRegisterSuper_client_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 16 -> d_field_SDLRegisterSuper_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 26 -> d_field_SDLRegisterSuper_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 32 -> d_field_SDLRegisterSuper_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 40 -> d_field_SDLRegisterSuper_mask_len(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 50 -> d_field_SDLRegisterSuper_hostname(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 58 -> d_field_SDLRegisterSuper_pub_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 66 -> d_field_SDLRegisterSuper_access_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLRegisterSuper(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 1 -> skip_64_SDLRegisterSuper(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 2 -> skip_length_delimited_SDLRegisterSuper(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 3 -> skip_group_SDLRegisterSuper(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 5 -> skip_32_SDLRegisterSuper(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) + end + end; +dg_read_field_def_SDLRegisterSuper(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> + #'SDLRegisterSuper'{client_id = F@_1, network_id = F@_2, mac = F@_3, ip = F@_4, mask_len = F@_5, hostname = F@_6, pub_key = F@_7, access_token = F@_8}. + +d_field_SDLRegisterSuper_client_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_client_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_client_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLRegisterSuper_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLRegisterSuper_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLRegisterSuper_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLRegisterSuper_mask_len(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_mask_len(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_mask_len(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLRegisterSuper_hostname(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_hostname(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_hostname(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, NewFValue, F@_7, F@_8, TrUserData). + +d_field_SDLRegisterSuper_pub_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_pub_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_pub_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, NewFValue, F@_8, TrUserData). + +d_field_SDLRegisterSuper_access_token(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLRegisterSuper_access_token(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLRegisterSuper_access_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuper(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, NewFValue, TrUserData). + +skip_varint_SDLRegisterSuper(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> skip_varint_SDLRegisterSuper(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +skip_varint_SDLRegisterSuper(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_SDLRegisterSuper(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_length_delimited_SDLRegisterSuper(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + skip_length_delimited_SDLRegisterSuper(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +skip_length_delimited_SDLRegisterSuper(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLRegisterSuper(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_group_SDLRegisterSuper(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLRegisterSuper(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_32_SDLRegisterSuper(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_SDLRegisterSuper(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_64_SDLRegisterSuper(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_SDLRegisterSuper(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +decode_msg_SDLRegisterSuperAck(Bin, TrUserData) -> dfp_read_field_def_SDLRegisterSuperAck(Bin, 0, 0, 0, id(<<>>, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLRegisterSuperAck(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLRegisterSuperAck_algorithm(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLRegisterSuperAck(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLRegisterSuperAck_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLRegisterSuperAck(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLRegisterSuperAck_region_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLRegisterSuperAck(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLRegisterSuperAck_session_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLRegisterSuperAck(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLRegisterSuperAck'{algorithm = F@_1, key = F@_2, region_id = F@_3, session_token = F@_4}; +dfp_read_field_def_SDLRegisterSuperAck(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dg_read_field_def_SDLRegisterSuperAck(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +dg_read_field_def_SDLRegisterSuperAck(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLRegisterSuperAck(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dg_read_field_def_SDLRegisterSuperAck(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> d_field_SDLRegisterSuperAck_algorithm(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 18 -> d_field_SDLRegisterSuperAck_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 24 -> d_field_SDLRegisterSuperAck_region_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 34 -> d_field_SDLRegisterSuperAck_session_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLRegisterSuperAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 1 -> skip_64_SDLRegisterSuperAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 2 -> skip_length_delimited_SDLRegisterSuperAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 3 -> skip_group_SDLRegisterSuperAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 5 -> skip_32_SDLRegisterSuperAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData) + end + end; +dg_read_field_def_SDLRegisterSuperAck(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLRegisterSuperAck'{algorithm = F@_1, key = F@_2, region_id = F@_3, session_token = F@_4}. + +d_field_SDLRegisterSuperAck_algorithm(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLRegisterSuperAck_algorithm(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLRegisterSuperAck_algorithm(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuperAck(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, TrUserData). + +d_field_SDLRegisterSuperAck_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLRegisterSuperAck_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLRegisterSuperAck_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuperAck(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, TrUserData). + +d_field_SDLRegisterSuperAck_region_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLRegisterSuperAck_region_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLRegisterSuperAck_region_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegisterSuperAck(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, TrUserData). + +d_field_SDLRegisterSuperAck_session_token(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLRegisterSuperAck_session_token(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLRegisterSuperAck_session_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuperAck(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, TrUserData). + +skip_varint_SDLRegisterSuperAck(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> skip_varint_SDLRegisterSuperAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_varint_SDLRegisterSuperAck(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLRegisterSuperAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_length_delimited_SDLRegisterSuperAck(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> skip_length_delimited_SDLRegisterSuperAck(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_length_delimited_SDLRegisterSuperAck(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLRegisterSuperAck(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_group_SDLRegisterSuperAck(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLRegisterSuperAck(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_32_SDLRegisterSuperAck(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLRegisterSuperAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_64_SDLRegisterSuperAck(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLRegisterSuperAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +decode_msg_SDLRegisterSuperNak(Bin, TrUserData) -> dfp_read_field_def_SDLRegisterSuperNak(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLRegisterSuperNak(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLRegisterSuperNak_error_code(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLRegisterSuperNak(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLRegisterSuperNak_error_message(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLRegisterSuperNak(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLRegisterSuperNak'{error_code = F@_1, error_message = F@_2}; +dfp_read_field_def_SDLRegisterSuperNak(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_SDLRegisterSuperNak(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +dg_read_field_def_SDLRegisterSuperNak(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLRegisterSuperNak(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +dg_read_field_def_SDLRegisterSuperNak(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLRegisterSuperNak_error_code(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 18 -> d_field_SDLRegisterSuperNak_error_message(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLRegisterSuperNak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> skip_64_SDLRegisterSuperNak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> skip_length_delimited_SDLRegisterSuperNak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> skip_group_SDLRegisterSuperNak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> skip_32_SDLRegisterSuperNak(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +dg_read_field_def_SDLRegisterSuperNak(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLRegisterSuperNak'{error_code = F@_1, error_message = F@_2}. + +d_field_SDLRegisterSuperNak_error_code(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLRegisterSuperNak_error_code(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLRegisterSuperNak_error_code(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegisterSuperNak(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +d_field_SDLRegisterSuperNak_error_message(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLRegisterSuperNak_error_message(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLRegisterSuperNak_error_message(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterSuperNak(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). + +skip_varint_SDLRegisterSuperNak(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_SDLRegisterSuperNak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +skip_varint_SDLRegisterSuperNak(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLRegisterSuperNak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_length_delimited_SDLRegisterSuperNak(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_SDLRegisterSuperNak(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +skip_length_delimited_SDLRegisterSuperNak(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLRegisterSuperNak(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +skip_group_SDLRegisterSuperNak(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLRegisterSuperNak(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +skip_32_SDLRegisterSuperNak(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLRegisterSuperNak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_64_SDLRegisterSuperNak(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLRegisterSuperNak(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +decode_msg_SDLQueryInfo(Bin, TrUserData) -> dfp_read_field_def_SDLQueryInfo(Bin, 0, 0, 0, id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLQueryInfo(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_SDLQueryInfo_dst_mac(Rest, Z1, Z2, F, F@_1, TrUserData); +dfp_read_field_def_SDLQueryInfo(<<>>, 0, 0, _, F@_1, _) -> #'SDLQueryInfo'{dst_mac = F@_1}; +dfp_read_field_def_SDLQueryInfo(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_SDLQueryInfo(Other, Z1, Z2, F, F@_1, TrUserData). + +dg_read_field_def_SDLQueryInfo(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLQueryInfo(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +dg_read_field_def_SDLQueryInfo(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> d_field_SDLQueryInfo_dst_mac(Rest, 0, 0, 0, F@_1, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLQueryInfo(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 1 -> skip_64_SDLQueryInfo(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 2 -> skip_length_delimited_SDLQueryInfo(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 3 -> skip_group_SDLQueryInfo(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 5 -> skip_32_SDLQueryInfo(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) + end + end; +dg_read_field_def_SDLQueryInfo(<<>>, 0, 0, _, F@_1, _) -> #'SDLQueryInfo'{dst_mac = F@_1}. + +d_field_SDLQueryInfo_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_SDLQueryInfo_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +d_field_SDLQueryInfo_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLQueryInfo(RestF, 0, 0, F, NewFValue, TrUserData). + +skip_varint_SDLQueryInfo(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_SDLQueryInfo(Rest, Z1, Z2, F, F@_1, TrUserData); +skip_varint_SDLQueryInfo(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLQueryInfo(Rest, Z1, Z2, F, F@_1, TrUserData). + +skip_length_delimited_SDLQueryInfo(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> skip_length_delimited_SDLQueryInfo(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +skip_length_delimited_SDLQueryInfo(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLQueryInfo(Rest2, 0, 0, F, F@_1, TrUserData). + +skip_group_SDLQueryInfo(Bin, _, Z2, FNum, F@_1, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLQueryInfo(Rest, 0, Z2, FNum, F@_1, TrUserData). + +skip_32_SDLQueryInfo(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLQueryInfo(Rest, Z1, Z2, F, F@_1, TrUserData). + +skip_64_SDLQueryInfo(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLQueryInfo(Rest, Z1, Z2, F, F@_1, TrUserData). + +decode_msg_SDLPeerInfo(Bin, TrUserData) -> dfp_read_field_def_SDLPeerInfo(Bin, 0, 0, 0, id(<<>>, TrUserData), id(undefined, TrUserData), id(undefined, TrUserData), TrUserData). + +dfp_read_field_def_SDLPeerInfo(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLPeerInfo_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLPeerInfo(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLPeerInfo_v4_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLPeerInfo(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLPeerInfo_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLPeerInfo(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLPeerInfo'{dst_mac = F@_1, v4_info = F@_2, v6_info = F@_3}; +dfp_read_field_def_SDLPeerInfo(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLPeerInfo(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLPeerInfo(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLPeerInfo(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLPeerInfo(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> d_field_SDLPeerInfo_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 18 -> d_field_SDLPeerInfo_v4_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 26 -> d_field_SDLPeerInfo_v6_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLPeerInfo(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLPeerInfo(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLPeerInfo(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLPeerInfo(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLPeerInfo(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLPeerInfo(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLPeerInfo'{dst_mac = F@_1, v4_info = F@_2, v6_info = F@_3}. + +d_field_SDLPeerInfo_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLPeerInfo_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLPeerInfo_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLPeerInfo(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLPeerInfo_v4_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLPeerInfo_v4_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLPeerInfo_v4_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, Prev, F@_3, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_SDLV4Info(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLPeerInfo(RestF, + 0, + 0, + F, + F@_1, + if Prev == undefined -> NewFValue; + true -> merge_msg_SDLV4Info(Prev, NewFValue, TrUserData) + end, + F@_3, + TrUserData). + +d_field_SDLPeerInfo_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLPeerInfo_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLPeerInfo_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_SDLV6Info(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLPeerInfo(RestF, + 0, + 0, + F, + F@_1, + F@_2, + if Prev == undefined -> NewFValue; + true -> merge_msg_SDLV6Info(Prev, NewFValue, TrUserData) + end, + TrUserData). + +skip_varint_SDLPeerInfo(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLPeerInfo(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLPeerInfo(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLPeerInfo(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLPeerInfo(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLPeerInfo(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLPeerInfo(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLPeerInfo(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLPeerInfo(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLPeerInfo(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLPeerInfo(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLPeerInfo(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLPeerInfo(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLPeerInfo(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +decode_msg_SDLArpRequest(Bin, TrUserData) -> dfp_read_field_def_SDLArpRequest(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLArpRequest(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLArpRequest_target_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLArpRequest(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLArpRequest_origin_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLArpRequest(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLArpRequest_context(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLArpRequest(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLArpRequest'{target_ip = F@_1, origin_ip = F@_2, context = F@_3}; +dfp_read_field_def_SDLArpRequest(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLArpRequest(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLArpRequest(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLArpRequest(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLArpRequest(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLArpRequest_target_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 16 -> d_field_SDLArpRequest_origin_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 26 -> d_field_SDLArpRequest_context(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLArpRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLArpRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLArpRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLArpRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLArpRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLArpRequest(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLArpRequest'{target_ip = F@_1, origin_ip = F@_2, context = F@_3}. + +d_field_SDLArpRequest_target_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLArpRequest_target_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLArpRequest_target_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLArpRequest(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLArpRequest_origin_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLArpRequest_origin_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLArpRequest_origin_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLArpRequest(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). + +d_field_SDLArpRequest_context(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLArpRequest_context(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLArpRequest_context(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLArpRequest(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). + +skip_varint_SDLArpRequest(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLArpRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLArpRequest(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLArpRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLArpRequest(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLArpRequest(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLArpRequest(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLArpRequest(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLArpRequest(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLArpRequest(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLArpRequest(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLArpRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLArpRequest(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLArpRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +decode_msg_SDLArpResponse(Bin, TrUserData) -> dfp_read_field_def_SDLArpResponse(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLArpResponse(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLArpResponse_target_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLArpResponse(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLArpResponse_target_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLArpResponse(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLArpResponse_origin_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLArpResponse(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLArpResponse_context(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLArpResponse(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLArpResponse'{target_ip = F@_1, target_mac = F@_2, origin_ip = F@_3, context = F@_4}; +dfp_read_field_def_SDLArpResponse(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dg_read_field_def_SDLArpResponse(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +dg_read_field_def_SDLArpResponse(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLArpResponse(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dg_read_field_def_SDLArpResponse(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLArpResponse_target_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 18 -> d_field_SDLArpResponse_target_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 24 -> d_field_SDLArpResponse_origin_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 34 -> d_field_SDLArpResponse_context(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLArpResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 1 -> skip_64_SDLArpResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 2 -> skip_length_delimited_SDLArpResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 3 -> skip_group_SDLArpResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 5 -> skip_32_SDLArpResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData) + end + end; +dg_read_field_def_SDLArpResponse(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLArpResponse'{target_ip = F@_1, target_mac = F@_2, origin_ip = F@_3, context = F@_4}. + +d_field_SDLArpResponse_target_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLArpResponse_target_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLArpResponse_target_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLArpResponse(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, TrUserData). + +d_field_SDLArpResponse_target_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLArpResponse_target_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLArpResponse_target_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLArpResponse(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, TrUserData). + +d_field_SDLArpResponse_origin_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLArpResponse_origin_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLArpResponse_origin_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLArpResponse(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, TrUserData). + +d_field_SDLArpResponse_context(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLArpResponse_context(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLArpResponse_context(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLArpResponse(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, TrUserData). + +skip_varint_SDLArpResponse(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> skip_varint_SDLArpResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_varint_SDLArpResponse(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLArpResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_length_delimited_SDLArpResponse(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> skip_length_delimited_SDLArpResponse(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_length_delimited_SDLArpResponse(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLArpResponse(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_group_SDLArpResponse(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLArpResponse(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_32_SDLArpResponse(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLArpResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_64_SDLArpResponse(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLArpResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +decode_msg_SDLPolicyRequest(Bin, TrUserData) -> dfp_read_field_def_SDLPolicyRequest(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), TrUserData). + +dfp_read_field_def_SDLPolicyRequest(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLPolicyRequest_src_identity_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLPolicyRequest(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLPolicyRequest_dst_identity_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLPolicyRequest(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLPolicyRequest_version(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLPolicyRequest(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLPolicyRequest'{src_identity_id = F@_1, dst_identity_id = F@_2, version = F@_3}; +dfp_read_field_def_SDLPolicyRequest(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLPolicyRequest(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLPolicyRequest(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLPolicyRequest(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLPolicyRequest(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLPolicyRequest_src_identity_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 16 -> d_field_SDLPolicyRequest_dst_identity_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 24 -> d_field_SDLPolicyRequest_version(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLPolicyRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLPolicyRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLPolicyRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLPolicyRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLPolicyRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLPolicyRequest(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLPolicyRequest'{src_identity_id = F@_1, dst_identity_id = F@_2, version = F@_3}. + +d_field_SDLPolicyRequest_src_identity_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLPolicyRequest_src_identity_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLPolicyRequest_src_identity_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLPolicyRequest(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLPolicyRequest_dst_identity_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLPolicyRequest_dst_identity_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLPolicyRequest_dst_identity_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLPolicyRequest(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). + +d_field_SDLPolicyRequest_version(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLPolicyRequest_version(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLPolicyRequest_version(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLPolicyRequest(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). + +skip_varint_SDLPolicyRequest(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLPolicyRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLPolicyRequest(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLPolicyRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLPolicyRequest(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLPolicyRequest(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLPolicyRequest(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLPolicyRequest(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLPolicyRequest(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLPolicyRequest(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLPolicyRequest(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLPolicyRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLPolicyRequest(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLPolicyRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +decode_msg_SDLPolicyResponse(Bin, TrUserData) -> dfp_read_field_def_SDLPolicyResponse(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLPolicyResponse(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLPolicyResponse_src_identity_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLPolicyResponse(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLPolicyResponse_dst_identity_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLPolicyResponse(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLPolicyResponse_version(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLPolicyResponse(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLPolicyResponse_rules(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLPolicyResponse(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLPolicyResponse'{src_identity_id = F@_1, dst_identity_id = F@_2, version = F@_3, rules = F@_4}; +dfp_read_field_def_SDLPolicyResponse(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dg_read_field_def_SDLPolicyResponse(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +dg_read_field_def_SDLPolicyResponse(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLPolicyResponse(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dg_read_field_def_SDLPolicyResponse(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLPolicyResponse_src_identity_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 16 -> d_field_SDLPolicyResponse_dst_identity_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 24 -> d_field_SDLPolicyResponse_version(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 34 -> d_field_SDLPolicyResponse_rules(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLPolicyResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 1 -> skip_64_SDLPolicyResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 2 -> skip_length_delimited_SDLPolicyResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 3 -> skip_group_SDLPolicyResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 5 -> skip_32_SDLPolicyResponse(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData) + end + end; +dg_read_field_def_SDLPolicyResponse(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLPolicyResponse'{src_identity_id = F@_1, dst_identity_id = F@_2, version = F@_3, rules = F@_4}. + +d_field_SDLPolicyResponse_src_identity_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLPolicyResponse_src_identity_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLPolicyResponse_src_identity_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLPolicyResponse(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, TrUserData). + +d_field_SDLPolicyResponse_dst_identity_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLPolicyResponse_dst_identity_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLPolicyResponse_dst_identity_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLPolicyResponse(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, TrUserData). + +d_field_SDLPolicyResponse_version(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLPolicyResponse_version(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLPolicyResponse_version(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLPolicyResponse(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, TrUserData). + +d_field_SDLPolicyResponse_rules(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLPolicyResponse_rules(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLPolicyResponse_rules(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLPolicyResponse(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, TrUserData). + +skip_varint_SDLPolicyResponse(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> skip_varint_SDLPolicyResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_varint_SDLPolicyResponse(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLPolicyResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_length_delimited_SDLPolicyResponse(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> skip_length_delimited_SDLPolicyResponse(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_length_delimited_SDLPolicyResponse(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLPolicyResponse(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_group_SDLPolicyResponse(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLPolicyResponse(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_32_SDLPolicyResponse(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLPolicyResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_64_SDLPolicyResponse(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLPolicyResponse(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +'decode_msg_SDLEvent.NatChanged'(Bin, TrUserData) -> 'dfp_read_field_def_SDLEvent.NatChanged'(Bin, 0, 0, 0, id(<<>>, TrUserData), id(0, TrUserData), TrUserData). + +'dfp_read_field_def_SDLEvent.NatChanged'(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'd_field_SDLEvent.NatChanged_mac'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'dfp_read_field_def_SDLEvent.NatChanged'(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'd_field_SDLEvent.NatChanged_ip'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'dfp_read_field_def_SDLEvent.NatChanged'(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLEvent.NatChanged'{mac = F@_1, ip = F@_2}; +'dfp_read_field_def_SDLEvent.NatChanged'(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dg_read_field_def_SDLEvent.NatChanged'(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'dg_read_field_def_SDLEvent.NatChanged'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> 'dg_read_field_def_SDLEvent.NatChanged'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'dg_read_field_def_SDLEvent.NatChanged'(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> 'd_field_SDLEvent.NatChanged_mac'(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 16 -> 'd_field_SDLEvent.NatChanged_ip'(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> 'skip_varint_SDLEvent.NatChanged'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> 'skip_64_SDLEvent.NatChanged'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> 'skip_length_delimited_SDLEvent.NatChanged'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> 'skip_group_SDLEvent.NatChanged'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> 'skip_32_SDLEvent.NatChanged'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +'dg_read_field_def_SDLEvent.NatChanged'(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLEvent.NatChanged'{mac = F@_1, ip = F@_2}. + +'d_field_SDLEvent.NatChanged_mac'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'd_field_SDLEvent.NatChanged_mac'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'d_field_SDLEvent.NatChanged_mac'(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + 'dfp_read_field_def_SDLEvent.NatChanged'(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +'d_field_SDLEvent.NatChanged_ip'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'd_field_SDLEvent.NatChanged_ip'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'d_field_SDLEvent.NatChanged_ip'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + 'dfp_read_field_def_SDLEvent.NatChanged'(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). + +'skip_varint_SDLEvent.NatChanged'(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'skip_varint_SDLEvent.NatChanged'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'skip_varint_SDLEvent.NatChanged'(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_SDLEvent.NatChanged'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'skip_length_delimited_SDLEvent.NatChanged'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'skip_length_delimited_SDLEvent.NatChanged'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'skip_length_delimited_SDLEvent.NatChanged'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + 'dfp_read_field_def_SDLEvent.NatChanged'(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +'skip_group_SDLEvent.NatChanged'(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + 'dfp_read_field_def_SDLEvent.NatChanged'(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +'skip_32_SDLEvent.NatChanged'(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_SDLEvent.NatChanged'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'skip_64_SDLEvent.NatChanged'(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_SDLEvent.NatChanged'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'decode_msg_SDLEvent.SendRegister'(Bin, TrUserData) -> 'dfp_read_field_def_SDLEvent.SendRegister'(Bin, 0, 0, 0, id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), id(undefined, TrUserData), TrUserData). + +'dfp_read_field_def_SDLEvent.SendRegister'(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'd_field_SDLEvent.SendRegister_dst_mac'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'dfp_read_field_def_SDLEvent.SendRegister'(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'd_field_SDLEvent.SendRegister_nat_ip'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'dfp_read_field_def_SDLEvent.SendRegister'(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'd_field_SDLEvent.SendRegister_nat_port'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'dfp_read_field_def_SDLEvent.SendRegister'(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'd_field_SDLEvent.SendRegister_nat_type'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'dfp_read_field_def_SDLEvent.SendRegister'(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'd_field_SDLEvent.SendRegister_v6_info'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'dfp_read_field_def_SDLEvent.SendRegister'(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #'SDLEvent.SendRegister'{dst_mac = F@_1, nat_ip = F@_2, nat_port = F@_3, nat_type = F@_4, v6_info = F@_5}; +'dfp_read_field_def_SDLEvent.SendRegister'(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'dg_read_field_def_SDLEvent.SendRegister'(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'dg_read_field_def_SDLEvent.SendRegister'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> + 'dg_read_field_def_SDLEvent.SendRegister'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'dg_read_field_def_SDLEvent.SendRegister'(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> 'd_field_SDLEvent.SendRegister_dst_mac'(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 16 -> 'd_field_SDLEvent.SendRegister_nat_ip'(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 24 -> 'd_field_SDLEvent.SendRegister_nat_port'(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 32 -> 'd_field_SDLEvent.SendRegister_nat_type'(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 42 -> 'd_field_SDLEvent.SendRegister_v6_info'(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + _ -> + case Key band 7 of + 0 -> 'skip_varint_SDLEvent.SendRegister'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 1 -> 'skip_64_SDLEvent.SendRegister'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 2 -> 'skip_length_delimited_SDLEvent.SendRegister'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 3 -> 'skip_group_SDLEvent.SendRegister'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 5 -> 'skip_32_SDLEvent.SendRegister'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) + end + end; +'dg_read_field_def_SDLEvent.SendRegister'(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #'SDLEvent.SendRegister'{dst_mac = F@_1, nat_ip = F@_2, nat_port = F@_3, nat_type = F@_4, v6_info = F@_5}. + +'d_field_SDLEvent.SendRegister_dst_mac'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> 'd_field_SDLEvent.SendRegister_dst_mac'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'d_field_SDLEvent.SendRegister_dst_mac'(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + 'dfp_read_field_def_SDLEvent.SendRegister'(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'d_field_SDLEvent.SendRegister_nat_ip'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> 'd_field_SDLEvent.SendRegister_nat_ip'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'d_field_SDLEvent.SendRegister_nat_ip'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + 'dfp_read_field_def_SDLEvent.SendRegister'(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData). + +'d_field_SDLEvent.SendRegister_nat_port'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> 'd_field_SDLEvent.SendRegister_nat_port'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'d_field_SDLEvent.SendRegister_nat_port'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + 'dfp_read_field_def_SDLEvent.SendRegister'(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData). + +'d_field_SDLEvent.SendRegister_nat_type'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> 'd_field_SDLEvent.SendRegister_nat_type'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'d_field_SDLEvent.SendRegister_nat_type'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + 'dfp_read_field_def_SDLEvent.SendRegister'(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData). + +'d_field_SDLEvent.SendRegister_v6_info'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> 'd_field_SDLEvent.SendRegister_v6_info'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'d_field_SDLEvent.SendRegister_v6_info'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_SDLV6Info(Bs, TrUserData), TrUserData), Rest2} end, + 'dfp_read_field_def_SDLEvent.SendRegister'(RestF, + 0, + 0, + F, + F@_1, + F@_2, + F@_3, + F@_4, + if Prev == undefined -> NewFValue; + true -> merge_msg_SDLV6Info(Prev, NewFValue, TrUserData) + end, + TrUserData). + +'skip_varint_SDLEvent.SendRegister'(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'skip_varint_SDLEvent.SendRegister'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'skip_varint_SDLEvent.SendRegister'(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'dfp_read_field_def_SDLEvent.SendRegister'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'skip_length_delimited_SDLEvent.SendRegister'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> + 'skip_length_delimited_SDLEvent.SendRegister'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +'skip_length_delimited_SDLEvent.SendRegister'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + 'dfp_read_field_def_SDLEvent.SendRegister'(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'skip_group_SDLEvent.SendRegister'(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + 'dfp_read_field_def_SDLEvent.SendRegister'(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'skip_32_SDLEvent.SendRegister'(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'dfp_read_field_def_SDLEvent.SendRegister'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'skip_64_SDLEvent.SendRegister'(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> 'dfp_read_field_def_SDLEvent.SendRegister'(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). + +'decode_msg_SDLEvent.NetworkShutdown'(Bin, TrUserData) -> 'dfp_read_field_def_SDLEvent.NetworkShutdown'(Bin, 0, 0, 0, id(<<>>, TrUserData), TrUserData). + +'dfp_read_field_def_SDLEvent.NetworkShutdown'(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'd_field_SDLEvent.NetworkShutdown_message'(Rest, Z1, Z2, F, F@_1, TrUserData); +'dfp_read_field_def_SDLEvent.NetworkShutdown'(<<>>, 0, 0, _, F@_1, _) -> #'SDLEvent.NetworkShutdown'{message = F@_1}; +'dfp_read_field_def_SDLEvent.NetworkShutdown'(Other, Z1, Z2, F, F@_1, TrUserData) -> 'dg_read_field_def_SDLEvent.NetworkShutdown'(Other, Z1, Z2, F, F@_1, TrUserData). + +'dg_read_field_def_SDLEvent.NetworkShutdown'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> 'dg_read_field_def_SDLEvent.NetworkShutdown'(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +'dg_read_field_def_SDLEvent.NetworkShutdown'(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> 'd_field_SDLEvent.NetworkShutdown_message'(Rest, 0, 0, 0, F@_1, TrUserData); + _ -> + case Key band 7 of + 0 -> 'skip_varint_SDLEvent.NetworkShutdown'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 1 -> 'skip_64_SDLEvent.NetworkShutdown'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 2 -> 'skip_length_delimited_SDLEvent.NetworkShutdown'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 3 -> 'skip_group_SDLEvent.NetworkShutdown'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 5 -> 'skip_32_SDLEvent.NetworkShutdown'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) + end + end; +'dg_read_field_def_SDLEvent.NetworkShutdown'(<<>>, 0, 0, _, F@_1, _) -> #'SDLEvent.NetworkShutdown'{message = F@_1}. + +'d_field_SDLEvent.NetworkShutdown_message'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> 'd_field_SDLEvent.NetworkShutdown_message'(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +'d_field_SDLEvent.NetworkShutdown_message'(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + 'dfp_read_field_def_SDLEvent.NetworkShutdown'(RestF, 0, 0, F, NewFValue, TrUserData). + +'skip_varint_SDLEvent.NetworkShutdown'(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'skip_varint_SDLEvent.NetworkShutdown'(Rest, Z1, Z2, F, F@_1, TrUserData); +'skip_varint_SDLEvent.NetworkShutdown'(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'dfp_read_field_def_SDLEvent.NetworkShutdown'(Rest, Z1, Z2, F, F@_1, TrUserData). + +'skip_length_delimited_SDLEvent.NetworkShutdown'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> 'skip_length_delimited_SDLEvent.NetworkShutdown'(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +'skip_length_delimited_SDLEvent.NetworkShutdown'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + 'dfp_read_field_def_SDLEvent.NetworkShutdown'(Rest2, 0, 0, F, F@_1, TrUserData). + +'skip_group_SDLEvent.NetworkShutdown'(Bin, _, Z2, FNum, F@_1, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + 'dfp_read_field_def_SDLEvent.NetworkShutdown'(Rest, 0, Z2, FNum, F@_1, TrUserData). + +'skip_32_SDLEvent.NetworkShutdown'(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'dfp_read_field_def_SDLEvent.NetworkShutdown'(Rest, Z1, Z2, F, F@_1, TrUserData). + +'skip_64_SDLEvent.NetworkShutdown'(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'dfp_read_field_def_SDLEvent.NetworkShutdown'(Rest, Z1, Z2, F, F@_1, TrUserData). + +decode_msg_SDLEvent(Bin, TrUserData) -> dfp_read_field_def_SDLEvent(Bin, 0, 0, 0, id(undefined, TrUserData), TrUserData). + +dfp_read_field_def_SDLEvent(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_SDLEvent_nat_changed(Rest, Z1, Z2, F, F@_1, TrUserData); +dfp_read_field_def_SDLEvent(<<18, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_SDLEvent_send_register(Rest, Z1, Z2, F, F@_1, TrUserData); +dfp_read_field_def_SDLEvent(<<26, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_SDLEvent_shutdown(Rest, Z1, Z2, F, F@_1, TrUserData); +dfp_read_field_def_SDLEvent(<<>>, 0, 0, _, F@_1, _) -> #'SDLEvent'{event = F@_1}; +dfp_read_field_def_SDLEvent(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_SDLEvent(Other, Z1, Z2, F, F@_1, TrUserData). + +dg_read_field_def_SDLEvent(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLEvent(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +dg_read_field_def_SDLEvent(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> d_field_SDLEvent_nat_changed(Rest, 0, 0, 0, F@_1, TrUserData); + 18 -> d_field_SDLEvent_send_register(Rest, 0, 0, 0, F@_1, TrUserData); + 26 -> d_field_SDLEvent_shutdown(Rest, 0, 0, 0, F@_1, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLEvent(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 1 -> skip_64_SDLEvent(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 2 -> skip_length_delimited_SDLEvent(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 3 -> skip_group_SDLEvent(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 5 -> skip_32_SDLEvent(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) + end + end; +dg_read_field_def_SDLEvent(<<>>, 0, 0, _, F@_1, _) -> #'SDLEvent'{event = F@_1}. + +d_field_SDLEvent_nat_changed(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_SDLEvent_nat_changed(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +d_field_SDLEvent_nat_changed(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id('decode_msg_SDLEvent.NatChanged'(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLEvent(RestF, + 0, + 0, + F, + case Prev of + undefined -> id({nat_changed, NewFValue}, TrUserData); + {nat_changed, MVPrev} -> id({nat_changed, 'merge_msg_SDLEvent.NatChanged'(MVPrev, NewFValue, TrUserData)}, TrUserData); + _ -> id({nat_changed, NewFValue}, TrUserData) + end, + TrUserData). + +d_field_SDLEvent_send_register(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_SDLEvent_send_register(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +d_field_SDLEvent_send_register(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id('decode_msg_SDLEvent.SendRegister'(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLEvent(RestF, + 0, + 0, + F, + case Prev of + undefined -> id({send_register, NewFValue}, TrUserData); + {send_register, MVPrev} -> id({send_register, 'merge_msg_SDLEvent.SendRegister'(MVPrev, NewFValue, TrUserData)}, TrUserData); + _ -> id({send_register, NewFValue}, TrUserData) + end, + TrUserData). + +d_field_SDLEvent_shutdown(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_SDLEvent_shutdown(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +d_field_SDLEvent_shutdown(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id('decode_msg_SDLEvent.NetworkShutdown'(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLEvent(RestF, + 0, + 0, + F, + case Prev of + undefined -> id({shutdown, NewFValue}, TrUserData); + {shutdown, MVPrev} -> id({shutdown, 'merge_msg_SDLEvent.NetworkShutdown'(MVPrev, NewFValue, TrUserData)}, TrUserData); + _ -> id({shutdown, NewFValue}, TrUserData) + end, + TrUserData). + +skip_varint_SDLEvent(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_SDLEvent(Rest, Z1, Z2, F, F@_1, TrUserData); +skip_varint_SDLEvent(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLEvent(Rest, Z1, Z2, F, F@_1, TrUserData). + +skip_length_delimited_SDLEvent(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> skip_length_delimited_SDLEvent(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +skip_length_delimited_SDLEvent(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLEvent(Rest2, 0, 0, F, F@_1, TrUserData). + +skip_group_SDLEvent(Bin, _, Z2, FNum, F@_1, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLEvent(Rest, 0, Z2, FNum, F@_1, TrUserData). + +skip_32_SDLEvent(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLEvent(Rest, Z1, Z2, F, F@_1, TrUserData). + +skip_64_SDLEvent(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_SDLEvent(Rest, Z1, Z2, F, F@_1, TrUserData). + +'decode_msg_SDLCommand.ExitNodeControl'(Bin, TrUserData) -> 'dfp_read_field_def_SDLCommand.ExitNodeControl'(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +'dfp_read_field_def_SDLCommand.ExitNodeControl'(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'd_field_SDLCommand.ExitNodeControl_action'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'dfp_read_field_def_SDLCommand.ExitNodeControl'(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'd_field_SDLCommand.ExitNodeControl_remark'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'dfp_read_field_def_SDLCommand.ExitNodeControl'(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLCommand.ExitNodeControl'{action = F@_1, remark = F@_2}; +'dfp_read_field_def_SDLCommand.ExitNodeControl'(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dg_read_field_def_SDLCommand.ExitNodeControl'(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'dg_read_field_def_SDLCommand.ExitNodeControl'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> 'dg_read_field_def_SDLCommand.ExitNodeControl'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'dg_read_field_def_SDLCommand.ExitNodeControl'(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> 'd_field_SDLCommand.ExitNodeControl_action'(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 18 -> 'd_field_SDLCommand.ExitNodeControl_remark'(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> 'skip_varint_SDLCommand.ExitNodeControl'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> 'skip_64_SDLCommand.ExitNodeControl'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> 'skip_length_delimited_SDLCommand.ExitNodeControl'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> 'skip_group_SDLCommand.ExitNodeControl'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> 'skip_32_SDLCommand.ExitNodeControl'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +'dg_read_field_def_SDLCommand.ExitNodeControl'(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLCommand.ExitNodeControl'{action = F@_1, remark = F@_2}. + +'d_field_SDLCommand.ExitNodeControl_action'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'd_field_SDLCommand.ExitNodeControl_action'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'d_field_SDLCommand.ExitNodeControl_action'(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = {begin <> = <<(X bsl N + Acc):32/unsigned-native>>, id(Res, TrUserData) end, Rest}, + 'dfp_read_field_def_SDLCommand.ExitNodeControl'(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +'d_field_SDLCommand.ExitNodeControl_remark'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'd_field_SDLCommand.ExitNodeControl_remark'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'d_field_SDLCommand.ExitNodeControl_remark'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + 'dfp_read_field_def_SDLCommand.ExitNodeControl'(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). + +'skip_varint_SDLCommand.ExitNodeControl'(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'skip_varint_SDLCommand.ExitNodeControl'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'skip_varint_SDLCommand.ExitNodeControl'(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_SDLCommand.ExitNodeControl'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'skip_length_delimited_SDLCommand.ExitNodeControl'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'skip_length_delimited_SDLCommand.ExitNodeControl'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'skip_length_delimited_SDLCommand.ExitNodeControl'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + 'dfp_read_field_def_SDLCommand.ExitNodeControl'(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +'skip_group_SDLCommand.ExitNodeControl'(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + 'dfp_read_field_def_SDLCommand.ExitNodeControl'(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +'skip_32_SDLCommand.ExitNodeControl'(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_SDLCommand.ExitNodeControl'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'skip_64_SDLCommand.ExitNodeControl'(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_SDLCommand.ExitNodeControl'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +decode_msg_SDLCommand(Bin, TrUserData) -> dfp_read_field_def_SDLCommand(Bin, 0, 0, 0, id(0, TrUserData), id(undefined, TrUserData), TrUserData). + +dfp_read_field_def_SDLCommand(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLCommand_pkt_id(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLCommand(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> d_field_SDLCommand_exit_node(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +dfp_read_field_def_SDLCommand(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLCommand'{pkt_id = F@_1, command = F@_2}; +dfp_read_field_def_SDLCommand(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dg_read_field_def_SDLCommand(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +dg_read_field_def_SDLCommand(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLCommand(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +dg_read_field_def_SDLCommand(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLCommand_pkt_id(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 18 -> d_field_SDLCommand_exit_node(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLCommand(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> skip_64_SDLCommand(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> skip_length_delimited_SDLCommand(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> skip_group_SDLCommand(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> skip_32_SDLCommand(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +dg_read_field_def_SDLCommand(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'SDLCommand'{pkt_id = F@_1, command = F@_2}. + +d_field_SDLCommand_pkt_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLCommand_pkt_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLCommand_pkt_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLCommand(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +d_field_SDLCommand_exit_node(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> d_field_SDLCommand_exit_node(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +d_field_SDLCommand_exit_node(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id('decode_msg_SDLCommand.ExitNodeControl'(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLCommand(RestF, + 0, + 0, + F, + F@_1, + case Prev of + undefined -> id({exit_node, NewFValue}, TrUserData); + {exit_node, MVPrev} -> id({exit_node, 'merge_msg_SDLCommand.ExitNodeControl'(MVPrev, NewFValue, TrUserData)}, TrUserData); + _ -> id({exit_node, NewFValue}, TrUserData) + end, + TrUserData). + +skip_varint_SDLCommand(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_varint_SDLCommand(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +skip_varint_SDLCommand(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLCommand(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_length_delimited_SDLCommand(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> skip_length_delimited_SDLCommand(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +skip_length_delimited_SDLCommand(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLCommand(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +skip_group_SDLCommand(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLCommand(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +skip_32_SDLCommand(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLCommand(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +skip_64_SDLCommand(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_SDLCommand(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +decode_msg_SDLCommandAck(Bin, TrUserData) -> dfp_read_field_def_SDLCommandAck(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLCommandAck(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLCommandAck_pkt_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLCommandAck(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLCommandAck_code(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLCommandAck(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLCommandAck_message(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLCommandAck(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLCommandAck_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLCommandAck(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLCommandAck'{pkt_id = F@_1, code = F@_2, message = F@_3, data = F@_4}; +dfp_read_field_def_SDLCommandAck(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dg_read_field_def_SDLCommandAck(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +dg_read_field_def_SDLCommandAck(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLCommandAck(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dg_read_field_def_SDLCommandAck(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLCommandAck_pkt_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 16 -> d_field_SDLCommandAck_code(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 26 -> d_field_SDLCommandAck_message(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 34 -> d_field_SDLCommandAck_data(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLCommandAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 1 -> skip_64_SDLCommandAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 2 -> skip_length_delimited_SDLCommandAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 3 -> skip_group_SDLCommandAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 5 -> skip_32_SDLCommandAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData) + end + end; +dg_read_field_def_SDLCommandAck(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLCommandAck'{pkt_id = F@_1, code = F@_2, message = F@_3, data = F@_4}. + +d_field_SDLCommandAck_pkt_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLCommandAck_pkt_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLCommandAck_pkt_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLCommandAck(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, TrUserData). + +d_field_SDLCommandAck_code(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLCommandAck_code(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLCommandAck_code(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {begin <> = <<(X bsl N + Acc):32/unsigned-native>>, id(Res, TrUserData) end, Rest}, + dfp_read_field_def_SDLCommandAck(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, TrUserData). + +d_field_SDLCommandAck_message(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLCommandAck_message(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLCommandAck_message(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLCommandAck(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, TrUserData). + +d_field_SDLCommandAck_data(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLCommandAck_data(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLCommandAck_data(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLCommandAck(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, TrUserData). + +skip_varint_SDLCommandAck(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> skip_varint_SDLCommandAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_varint_SDLCommandAck(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLCommandAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_length_delimited_SDLCommandAck(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> skip_length_delimited_SDLCommandAck(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_length_delimited_SDLCommandAck(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLCommandAck(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_group_SDLCommandAck(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLCommandAck(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_32_SDLCommandAck(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLCommandAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_64_SDLCommandAck(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLCommandAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +decode_msg_SDLStunRequest(Bin, TrUserData) -> + dfp_read_field_def_SDLStunRequest(Bin, 0, 0, 0, id(<<>>, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(undefined, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLStunRequest(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_client_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<40, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_nat_type(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<50, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<58, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> d_field_SDLStunRequest_session_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dfp_read_field_def_SDLStunRequest(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _) -> #'SDLStunRequest'{client_id = F@_1, network_id = F@_2, mac = F@_3, ip = F@_4, nat_type = F@_5, v6_info = F@_6, session_token = F@_7}; +dfp_read_field_def_SDLStunRequest(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dg_read_field_def_SDLStunRequest(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +dg_read_field_def_SDLStunRequest(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 32 - 7 -> + dg_read_field_def_SDLStunRequest(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +dg_read_field_def_SDLStunRequest(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> d_field_SDLStunRequest_client_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 16 -> d_field_SDLStunRequest_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 26 -> d_field_SDLStunRequest_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 32 -> d_field_SDLStunRequest_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 40 -> d_field_SDLStunRequest_nat_type(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 50 -> d_field_SDLStunRequest_v6_info(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 58 -> d_field_SDLStunRequest_session_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLStunRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 1 -> skip_64_SDLStunRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 2 -> skip_length_delimited_SDLStunRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 3 -> skip_group_SDLStunRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); + 5 -> skip_32_SDLStunRequest(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) + end + end; +dg_read_field_def_SDLStunRequest(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _) -> #'SDLStunRequest'{client_id = F@_1, network_id = F@_2, mac = F@_3, ip = F@_4, nat_type = F@_5, v6_info = F@_6, session_token = F@_7}. + +d_field_SDLStunRequest_client_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> + d_field_SDLStunRequest_client_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_client_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLStunRequest(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +d_field_SDLStunRequest_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> + d_field_SDLStunRequest_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunRequest(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +d_field_SDLStunRequest_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> d_field_SDLStunRequest_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, F@_7, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLStunRequest(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, F@_7, TrUserData). + +d_field_SDLStunRequest_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> d_field_SDLStunRequest_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, F@_6, F@_7, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunRequest(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, F@_6, F@_7, TrUserData). + +d_field_SDLStunRequest_nat_type(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> + d_field_SDLStunRequest_nat_type(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_nat_type(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, F@_7, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunRequest(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, F@_7, TrUserData). + +d_field_SDLStunRequest_v6_info(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> + d_field_SDLStunRequest_v6_info(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_v6_info(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, Prev, F@_7, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id(decode_msg_SDLV6Info(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_SDLStunRequest(RestF, + 0, + 0, + F, + F@_1, + F@_2, + F@_3, + F@_4, + F@_5, + if Prev == undefined -> NewFValue; + true -> merge_msg_SDLV6Info(Prev, NewFValue, TrUserData) + end, + F@_7, + TrUserData). + +d_field_SDLStunRequest_session_token(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> + d_field_SDLStunRequest_session_token(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +d_field_SDLStunRequest_session_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLStunRequest(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, NewFValue, TrUserData). + +skip_varint_SDLStunRequest(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> skip_varint_SDLStunRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +skip_varint_SDLStunRequest(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dfp_read_field_def_SDLStunRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +skip_length_delimited_SDLStunRequest(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) when N < 57 -> + skip_length_delimited_SDLStunRequest(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData); +skip_length_delimited_SDLStunRequest(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLStunRequest(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +skip_group_SDLStunRequest(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLStunRequest(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +skip_32_SDLStunRequest(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dfp_read_field_def_SDLStunRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +skip_64_SDLStunRequest(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData) -> dfp_read_field_def_SDLStunRequest(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, TrUserData). + +decode_msg_SDLStunReply(Bin, TrUserData) -> dfp_read_field_def_SDLStunReply(Bin, 0, 0, 0, TrUserData). + +dfp_read_field_def_SDLStunReply(<<>>, 0, 0, _, _) -> #'SDLStunReply'{}; +dfp_read_field_def_SDLStunReply(Other, Z1, Z2, F, TrUserData) -> dg_read_field_def_SDLStunReply(Other, Z1, Z2, F, TrUserData). + +dg_read_field_def_SDLStunReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLStunReply(Rest, N + 7, X bsl N + Acc, F, TrUserData); +dg_read_field_def_SDLStunReply(<<0:1, X:7, Rest/binary>>, N, Acc, _, TrUserData) -> + Key = X bsl N + Acc, + case Key band 7 of + 0 -> skip_varint_SDLStunReply(Rest, 0, 0, Key bsr 3, TrUserData); + 1 -> skip_64_SDLStunReply(Rest, 0, 0, Key bsr 3, TrUserData); + 2 -> skip_length_delimited_SDLStunReply(Rest, 0, 0, Key bsr 3, TrUserData); + 3 -> skip_group_SDLStunReply(Rest, 0, 0, Key bsr 3, TrUserData); + 5 -> skip_32_SDLStunReply(Rest, 0, 0, Key bsr 3, TrUserData) + end; +dg_read_field_def_SDLStunReply(<<>>, 0, 0, _, _) -> #'SDLStunReply'{}. + +skip_varint_SDLStunReply(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, TrUserData) -> skip_varint_SDLStunReply(Rest, Z1, Z2, F, TrUserData); +skip_varint_SDLStunReply(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_SDLStunReply(Rest, Z1, Z2, F, TrUserData). + +skip_length_delimited_SDLStunReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, TrUserData) when N < 57 -> skip_length_delimited_SDLStunReply(Rest, N + 7, X bsl N + Acc, F, TrUserData); +skip_length_delimited_SDLStunReply(<<0:1, X:7, Rest/binary>>, N, Acc, F, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLStunReply(Rest2, 0, 0, F, TrUserData). + +skip_group_SDLStunReply(Bin, _, Z2, FNum, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLStunReply(Rest, 0, Z2, FNum, TrUserData). + +skip_32_SDLStunReply(<<_:32, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_SDLStunReply(Rest, Z1, Z2, F, TrUserData). + +skip_64_SDLStunReply(<<_:64, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_SDLStunReply(Rest, Z1, Z2, F, TrUserData). + +decode_msg_SDLData(Bin, TrUserData) -> + dfp_read_field_def_SDLData(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(false, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), TrUserData). + +dfp_read_field_def_SDLData(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_src_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_is_p2p(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<40, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_ttl(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<50, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_data(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<58, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_session_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_SDLData_identity_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_SDLData(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> #'SDLData'{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3, is_p2p = F@_4, ttl = F@_5, data = F@_6, session_token = F@_7, identity_id = F@_8}; +dfp_read_field_def_SDLData(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dg_read_field_def_SDLData(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +dg_read_field_def_SDLData(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 32 - 7 -> + dg_read_field_def_SDLData(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dg_read_field_def_SDLData(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLData_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 18 -> d_field_SDLData_src_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 26 -> d_field_SDLData_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 32 -> d_field_SDLData_is_p2p(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 40 -> d_field_SDLData_ttl(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 50 -> d_field_SDLData_data(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 58 -> d_field_SDLData_session_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 64 -> d_field_SDLData_identity_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLData(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 1 -> skip_64_SDLData(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 2 -> skip_length_delimited_SDLData(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 3 -> skip_group_SDLData(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 5 -> skip_32_SDLData(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) + end + end; +dg_read_field_def_SDLData(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> #'SDLData'{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3, is_p2p = F@_4, ttl = F@_5, data = F@_6, session_token = F@_7, identity_id = F@_8}. + +d_field_SDLData_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLData_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLData(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLData_src_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLData_src_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_src_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLData_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLData_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLData_is_p2p(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> d_field_SDLData_is_p2p(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_is_p2p(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = {id(X bsl N + Acc =/= 0, TrUserData), Rest}, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLData_ttl(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> d_field_SDLData_ttl(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_ttl(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, F@_7, F@_8, TrUserData). + +d_field_SDLData_data(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> d_field_SDLData_data(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_data(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, F@_7, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, NewFValue, F@_7, F@_8, TrUserData). + +d_field_SDLData_session_token(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLData_session_token(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_session_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _, F@_8, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, NewFValue, F@_8, TrUserData). + +d_field_SDLData_identity_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_SDLData_identity_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_SDLData_identity_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLData(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, NewFValue, TrUserData). + +skip_varint_SDLData(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> skip_varint_SDLData(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +skip_varint_SDLData(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_SDLData(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_length_delimited_SDLData(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + skip_length_delimited_SDLData(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +skip_length_delimited_SDLData(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLData(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_group_SDLData(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLData(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_32_SDLData(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_SDLData(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +skip_64_SDLData(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dfp_read_field_def_SDLData(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). + +decode_msg_SDLStunProbe(Bin, TrUserData) -> dfp_read_field_def_SDLStunProbe(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), TrUserData). + +dfp_read_field_def_SDLStunProbe(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLStunProbe_cookie(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLStunProbe(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLStunProbe_attr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLStunProbe(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLStunProbe_step(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLStunProbe(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLStunProbe'{cookie = F@_1, attr = F@_2, step = F@_3}; +dfp_read_field_def_SDLStunProbe(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLStunProbe(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLStunProbe(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLStunProbe(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLStunProbe(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLStunProbe_cookie(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 16 -> d_field_SDLStunProbe_attr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 24 -> d_field_SDLStunProbe_step(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLStunProbe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLStunProbe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLStunProbe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLStunProbe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLStunProbe(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLStunProbe(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLStunProbe'{cookie = F@_1, attr = F@_2, step = F@_3}. + +d_field_SDLStunProbe_cookie(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLStunProbe_cookie(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLStunProbe_cookie(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbe(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLStunProbe_attr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLStunProbe_attr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLStunProbe_attr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbe(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). + +d_field_SDLStunProbe_step(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLStunProbe_step(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLStunProbe_step(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbe(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). + +skip_varint_SDLStunProbe(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLStunProbe(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLStunProbe(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLStunProbe(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLStunProbe(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLStunProbe(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLStunProbe(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLStunProbe(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLStunProbe(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLStunProbe(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLStunProbe(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLStunProbe(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLStunProbe(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLStunProbe(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +decode_msg_SDLStunProbeReply(Bin, TrUserData) -> dfp_read_field_def_SDLStunProbeReply(Bin, 0, 0, 0, id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), id(0, TrUserData), TrUserData). + +dfp_read_field_def_SDLStunProbeReply(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLStunProbeReply_cookie(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLStunProbeReply(<<16, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLStunProbeReply_step(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLStunProbeReply(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLStunProbeReply_port(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLStunProbeReply(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_SDLStunProbeReply_ip(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dfp_read_field_def_SDLStunProbeReply(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLStunProbeReply'{cookie = F@_1, step = F@_2, port = F@_3, ip = F@_4}; +dfp_read_field_def_SDLStunProbeReply(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dg_read_field_def_SDLStunProbeReply(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +dg_read_field_def_SDLStunProbeReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLStunProbeReply(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +dg_read_field_def_SDLStunProbeReply(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLStunProbeReply_cookie(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 16 -> d_field_SDLStunProbeReply_step(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 24 -> d_field_SDLStunProbeReply_port(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + 32 -> d_field_SDLStunProbeReply_ip(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLStunProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 1 -> skip_64_SDLStunProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 2 -> skip_length_delimited_SDLStunProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 3 -> skip_group_SDLStunProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData); + 5 -> skip_32_SDLStunProbeReply(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData) + end + end; +dg_read_field_def_SDLStunProbeReply(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #'SDLStunProbeReply'{cookie = F@_1, step = F@_2, port = F@_3, ip = F@_4}. + +d_field_SDLStunProbeReply_cookie(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLStunProbeReply_cookie(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLStunProbeReply_cookie(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbeReply(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, TrUserData). + +d_field_SDLStunProbeReply_step(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLStunProbeReply_step(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLStunProbeReply_step(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbeReply(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, TrUserData). + +d_field_SDLStunProbeReply_port(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLStunProbeReply_port(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLStunProbeReply_port(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbeReply(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, TrUserData). + +d_field_SDLStunProbeReply_ip(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_SDLStunProbeReply_ip(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +d_field_SDLStunProbeReply_ip(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLStunProbeReply(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, TrUserData). + +skip_varint_SDLStunProbeReply(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> skip_varint_SDLStunProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_varint_SDLStunProbeReply(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLStunProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_length_delimited_SDLStunProbeReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> skip_length_delimited_SDLStunProbeReply(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData); +skip_length_delimited_SDLStunProbeReply(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLStunProbeReply(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_group_SDLStunProbeReply(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLStunProbeReply(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_32_SDLStunProbeReply(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLStunProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +skip_64_SDLStunProbeReply(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_SDLStunProbeReply(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData). + +decode_msg_SDLRegister(Bin, TrUserData) -> dfp_read_field_def_SDLRegister(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLRegister(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLRegister_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLRegister(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLRegister_src_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLRegister(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLRegister_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLRegister(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLRegister'{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}; +dfp_read_field_def_SDLRegister(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLRegister(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLRegister(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLRegister(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLRegister(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLRegister_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 18 -> d_field_SDLRegister_src_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 26 -> d_field_SDLRegister_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLRegister(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLRegister(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLRegister(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLRegister(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLRegister(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLRegister(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLRegister'{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}. + +d_field_SDLRegister_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLRegister_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLRegister_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegister(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLRegister_src_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLRegister_src_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLRegister_src_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegister(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). + +d_field_SDLRegister_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLRegister_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLRegister_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegister(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). + +skip_varint_SDLRegister(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLRegister(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLRegister(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLRegister(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLRegister(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLRegister(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLRegister(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLRegister(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLRegister(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLRegister(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLRegister(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLRegister(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLRegister(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLRegister(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +decode_msg_SDLRegisterAck(Bin, TrUserData) -> dfp_read_field_def_SDLRegisterAck(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData). + +dfp_read_field_def_SDLRegisterAck(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLRegisterAck_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLRegisterAck(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLRegisterAck_src_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLRegisterAck(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> d_field_SDLRegisterAck_dst_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +dfp_read_field_def_SDLRegisterAck(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLRegisterAck'{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}; +dfp_read_field_def_SDLRegisterAck(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dg_read_field_def_SDLRegisterAck(Other, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +dg_read_field_def_SDLRegisterAck(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 32 - 7 -> dg_read_field_def_SDLRegisterAck(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +dg_read_field_def_SDLRegisterAck(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> d_field_SDLRegisterAck_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 18 -> d_field_SDLRegisterAck_src_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + 26 -> d_field_SDLRegisterAck_dst_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, TrUserData); + _ -> + case Key band 7 of + 0 -> skip_varint_SDLRegisterAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 1 -> skip_64_SDLRegisterAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 2 -> skip_length_delimited_SDLRegisterAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 3 -> skip_group_SDLRegisterAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData); + 5 -> skip_32_SDLRegisterAck(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, TrUserData) + end + end; +dg_read_field_def_SDLRegisterAck(<<>>, 0, 0, _, F@_1, F@_2, F@_3, _) -> #'SDLRegisterAck'{network_id = F@_1, src_mac = F@_2, dst_mac = F@_3}. + +d_field_SDLRegisterAck_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLRegisterAck_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLRegisterAck_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, TrUserData) -> + {NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest}, + dfp_read_field_def_SDLRegisterAck(RestF, 0, 0, F, NewFValue, F@_2, F@_3, TrUserData). + +d_field_SDLRegisterAck_src_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLRegisterAck_src_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLRegisterAck_src_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterAck(RestF, 0, 0, F, F@_1, NewFValue, F@_3, TrUserData). + +d_field_SDLRegisterAck_dst_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> d_field_SDLRegisterAck_dst_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +d_field_SDLRegisterAck_dst_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + dfp_read_field_def_SDLRegisterAck(RestF, 0, 0, F, F@_1, F@_2, NewFValue, TrUserData). + +skip_varint_SDLRegisterAck(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> skip_varint_SDLRegisterAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData); +skip_varint_SDLRegisterAck(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLRegisterAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_length_delimited_SDLRegisterAck(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) when N < 57 -> skip_length_delimited_SDLRegisterAck(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, TrUserData); +skip_length_delimited_SDLRegisterAck(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + dfp_read_field_def_SDLRegisterAck(Rest2, 0, 0, F, F@_1, F@_2, F@_3, TrUserData). + +skip_group_SDLRegisterAck(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + dfp_read_field_def_SDLRegisterAck(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, TrUserData). + +skip_32_SDLRegisterAck(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLRegisterAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +skip_64_SDLRegisterAck(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData) -> dfp_read_field_def_SDLRegisterAck(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, TrUserData). + +read_group(Bin, FieldNum) -> + {NumBytes, EndTagLen} = read_gr_b(Bin, 0, 0, 0, 0, FieldNum), + <> = Bin, + {Group, Rest}. + +%% Like skipping over fields, but record the total length, +%% Each field is <(FieldNum bsl 3) bor FieldType> ++ +%% Record the length because varints may be non-optimally encoded. +%% +%% Groups can be nested, but assume the same FieldNum cannot be nested +%% because group field numbers are shared with the rest of the fields +%% numbers. Thus we can search just for an group-end with the same +%% field number. +%% +%% (The only time the same group field number could occur would +%% be in a nested sub message, but then it would be inside a +%% length-delimited entry, which we skip-read by length.) +read_gr_b(<<1:1, X:7, Tl/binary>>, N, Acc, NumBytes, TagLen, FieldNum) + when N < (32-7) -> + read_gr_b(Tl, N+7, X bsl N + Acc, NumBytes, TagLen+1, FieldNum); +read_gr_b(<<0:1, X:7, Tl/binary>>, N, Acc, NumBytes, TagLen, + FieldNum) -> + Key = X bsl N + Acc, + TagLen1 = TagLen + 1, + case {Key bsr 3, Key band 7} of + {FieldNum, 4} -> % 4 = group_end + {NumBytes, TagLen1}; + {_, 0} -> % 0 = varint + read_gr_vi(Tl, 0, NumBytes + TagLen1, FieldNum); + {_, 1} -> % 1 = bits64 + <<_:64, Tl2/binary>> = Tl, + read_gr_b(Tl2, 0, 0, NumBytes + TagLen1 + 8, 0, FieldNum); + {_, 2} -> % 2 = length_delimited + read_gr_ld(Tl, 0, 0, NumBytes + TagLen1, FieldNum); + {_, 3} -> % 3 = group_start + read_gr_b(Tl, 0, 0, NumBytes + TagLen1, 0, FieldNum); + {_, 4} -> % 4 = group_end + read_gr_b(Tl, 0, 0, NumBytes + TagLen1, 0, FieldNum); + {_, 5} -> % 5 = bits32 + <<_:32, Tl2/binary>> = Tl, + read_gr_b(Tl2, 0, 0, NumBytes + TagLen1 + 4, 0, FieldNum) + end. + +read_gr_vi(<<1:1, _:7, Tl/binary>>, N, NumBytes, FieldNum) + when N < (64-7) -> + read_gr_vi(Tl, N+7, NumBytes+1, FieldNum); +read_gr_vi(<<0:1, _:7, Tl/binary>>, _, NumBytes, FieldNum) -> + read_gr_b(Tl, 0, 0, NumBytes+1, 0, FieldNum). + +read_gr_ld(<<1:1, X:7, Tl/binary>>, N, Acc, NumBytes, FieldNum) + when N < (64-7) -> + read_gr_ld(Tl, N+7, X bsl N + Acc, NumBytes+1, FieldNum); +read_gr_ld(<<0:1, X:7, Tl/binary>>, N, Acc, NumBytes, FieldNum) -> + Len = X bsl N + Acc, + NumBytes1 = NumBytes + 1, + <<_:Len/binary, Tl2/binary>> = Tl, + read_gr_b(Tl2, 0, 0, NumBytes1 + Len, 0, FieldNum). + +merge_msgs(Prev, New) when element(1, Prev) =:= element(1, New) -> merge_msgs(Prev, New, element(1, Prev), []). + +merge_msgs(Prev, New, MsgName) when is_atom(MsgName) -> merge_msgs(Prev, New, MsgName, []); +merge_msgs(Prev, New, Opts) when element(1, Prev) =:= element(1, New), is_list(Opts) -> merge_msgs(Prev, New, element(1, Prev), Opts). + +merge_msgs(Prev, New, MsgName, Opts) -> + TrUserData = proplists:get_value(user_data, Opts), + case MsgName of + 'SDLV4Info' -> merge_msg_SDLV4Info(Prev, New, TrUserData); + 'SDLV6Info' -> merge_msg_SDLV6Info(Prev, New, TrUserData); + 'SDLV6AssistProbe' -> merge_msg_SDLV6AssistProbe(Prev, New, TrUserData); + 'SDLV6AssistProbeReply' -> merge_msg_SDLV6AssistProbeReply(Prev, New, TrUserData); + 'SDLWelcome' -> merge_msg_SDLWelcome(Prev, New, TrUserData); + 'SDLRegisterSuper' -> merge_msg_SDLRegisterSuper(Prev, New, TrUserData); + 'SDLRegisterSuperAck' -> merge_msg_SDLRegisterSuperAck(Prev, New, TrUserData); + 'SDLRegisterSuperNak' -> merge_msg_SDLRegisterSuperNak(Prev, New, TrUserData); + 'SDLQueryInfo' -> merge_msg_SDLQueryInfo(Prev, New, TrUserData); + 'SDLPeerInfo' -> merge_msg_SDLPeerInfo(Prev, New, TrUserData); + 'SDLArpRequest' -> merge_msg_SDLArpRequest(Prev, New, TrUserData); + 'SDLArpResponse' -> merge_msg_SDLArpResponse(Prev, New, TrUserData); + 'SDLPolicyRequest' -> merge_msg_SDLPolicyRequest(Prev, New, TrUserData); + 'SDLPolicyResponse' -> merge_msg_SDLPolicyResponse(Prev, New, TrUserData); + 'SDLEvent.NatChanged' -> 'merge_msg_SDLEvent.NatChanged'(Prev, New, TrUserData); + 'SDLEvent.SendRegister' -> 'merge_msg_SDLEvent.SendRegister'(Prev, New, TrUserData); + 'SDLEvent.NetworkShutdown' -> 'merge_msg_SDLEvent.NetworkShutdown'(Prev, New, TrUserData); + 'SDLEvent' -> merge_msg_SDLEvent(Prev, New, TrUserData); + 'SDLCommand.ExitNodeControl' -> 'merge_msg_SDLCommand.ExitNodeControl'(Prev, New, TrUserData); + 'SDLCommand' -> merge_msg_SDLCommand(Prev, New, TrUserData); + 'SDLCommandAck' -> merge_msg_SDLCommandAck(Prev, New, TrUserData); + 'SDLStunRequest' -> merge_msg_SDLStunRequest(Prev, New, TrUserData); + 'SDLStunReply' -> merge_msg_SDLStunReply(Prev, New, TrUserData); + 'SDLData' -> merge_msg_SDLData(Prev, New, TrUserData); + 'SDLStunProbe' -> merge_msg_SDLStunProbe(Prev, New, TrUserData); + 'SDLStunProbeReply' -> merge_msg_SDLStunProbeReply(Prev, New, TrUserData); + 'SDLRegister' -> merge_msg_SDLRegister(Prev, New, TrUserData); + 'SDLRegisterAck' -> merge_msg_SDLRegisterAck(Prev, New, TrUserData) + end. + +-compile({nowarn_unused_function,merge_msg_SDLV4Info/3}). +merge_msg_SDLV4Info(#'SDLV4Info'{port = PFport, v4 = PFv4, nat_type = PFnat_type}, #'SDLV4Info'{port = NFport, v4 = NFv4, nat_type = NFnat_type}, _) -> + #'SDLV4Info'{port = + if NFport =:= undefined -> PFport; + true -> NFport + end, + v4 = + if NFv4 =:= undefined -> PFv4; + true -> NFv4 + end, + nat_type = + if NFnat_type =:= undefined -> PFnat_type; + true -> NFnat_type + end}. + +-compile({nowarn_unused_function,merge_msg_SDLV6Info/3}). +merge_msg_SDLV6Info(#'SDLV6Info'{port = PFport, v6 = PFv6}, #'SDLV6Info'{port = NFport, v6 = NFv6}, _) -> + #'SDLV6Info'{port = + if NFport =:= undefined -> PFport; + true -> NFport + end, + v6 = + if NFv6 =:= undefined -> PFv6; + true -> NFv6 + end}. + +-compile({nowarn_unused_function,merge_msg_SDLV6AssistProbe/3}). +merge_msg_SDLV6AssistProbe(#'SDLV6AssistProbe'{pkt_id = PFpkt_id}, #'SDLV6AssistProbe'{pkt_id = NFpkt_id}, _) -> + #'SDLV6AssistProbe'{pkt_id = + if NFpkt_id =:= undefined -> PFpkt_id; + true -> NFpkt_id + end}. + +-compile({nowarn_unused_function,merge_msg_SDLV6AssistProbeReply/3}). +merge_msg_SDLV6AssistProbeReply(#'SDLV6AssistProbeReply'{pkt_id = PFpkt_id, v6_info = PFv6_info}, #'SDLV6AssistProbeReply'{pkt_id = NFpkt_id, v6_info = NFv6_info}, TrUserData) -> + #'SDLV6AssistProbeReply'{pkt_id = + if NFpkt_id =:= undefined -> PFpkt_id; + true -> NFpkt_id + end, + v6_info = + if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_SDLV6Info(PFv6_info, NFv6_info, TrUserData); + PFv6_info == undefined -> NFv6_info; + NFv6_info == undefined -> PFv6_info + end}. + +-compile({nowarn_unused_function,merge_msg_SDLWelcome/3}). +merge_msg_SDLWelcome(#'SDLWelcome'{version = PFversion, max_bidi_streams = PFmax_bidi_streams, max_packet_size = PFmax_packet_size, heartbeat_sec = PFheartbeat_sec, ipv6_assist = PFipv6_assist}, + #'SDLWelcome'{version = NFversion, max_bidi_streams = NFmax_bidi_streams, max_packet_size = NFmax_packet_size, heartbeat_sec = NFheartbeat_sec, ipv6_assist = NFipv6_assist}, TrUserData) -> + #'SDLWelcome'{version = + if NFversion =:= undefined -> PFversion; + true -> NFversion + end, + max_bidi_streams = + if NFmax_bidi_streams =:= undefined -> PFmax_bidi_streams; + true -> NFmax_bidi_streams + end, + max_packet_size = + if NFmax_packet_size =:= undefined -> PFmax_packet_size; + true -> NFmax_packet_size + end, + heartbeat_sec = + if NFheartbeat_sec =:= undefined -> PFheartbeat_sec; + true -> NFheartbeat_sec + end, + ipv6_assist = + if PFipv6_assist /= undefined, NFipv6_assist /= undefined -> merge_msg_SDLV6Info(PFipv6_assist, NFipv6_assist, TrUserData); + PFipv6_assist == undefined -> NFipv6_assist; + NFipv6_assist == undefined -> PFipv6_assist + end}. + +-compile({nowarn_unused_function,merge_msg_SDLRegisterSuper/3}). +merge_msg_SDLRegisterSuper(#'SDLRegisterSuper'{client_id = PFclient_id, network_id = PFnetwork_id, mac = PFmac, ip = PFip, mask_len = PFmask_len, hostname = PFhostname, pub_key = PFpub_key, access_token = PFaccess_token}, + #'SDLRegisterSuper'{client_id = NFclient_id, network_id = NFnetwork_id, mac = NFmac, ip = NFip, mask_len = NFmask_len, hostname = NFhostname, pub_key = NFpub_key, access_token = NFaccess_token}, _) -> + #'SDLRegisterSuper'{client_id = + if NFclient_id =:= undefined -> PFclient_id; + true -> NFclient_id + end, + network_id = + if NFnetwork_id =:= undefined -> PFnetwork_id; + true -> NFnetwork_id + end, + mac = + if NFmac =:= undefined -> PFmac; + true -> NFmac + end, + ip = + if NFip =:= undefined -> PFip; + true -> NFip + end, + mask_len = + if NFmask_len =:= undefined -> PFmask_len; + true -> NFmask_len + end, + hostname = + if NFhostname =:= undefined -> PFhostname; + true -> NFhostname + end, + pub_key = + if NFpub_key =:= undefined -> PFpub_key; + true -> NFpub_key + end, + access_token = + if NFaccess_token =:= undefined -> PFaccess_token; + true -> NFaccess_token + end}. + +-compile({nowarn_unused_function,merge_msg_SDLRegisterSuperAck/3}). +merge_msg_SDLRegisterSuperAck(#'SDLRegisterSuperAck'{algorithm = PFalgorithm, key = PFkey, region_id = PFregion_id, session_token = PFsession_token}, + #'SDLRegisterSuperAck'{algorithm = NFalgorithm, key = NFkey, region_id = NFregion_id, session_token = NFsession_token}, _) -> + #'SDLRegisterSuperAck'{algorithm = + if NFalgorithm =:= undefined -> PFalgorithm; + true -> NFalgorithm + end, + key = + if NFkey =:= undefined -> PFkey; + true -> NFkey + end, + region_id = + if NFregion_id =:= undefined -> PFregion_id; + true -> NFregion_id + end, + session_token = + if NFsession_token =:= undefined -> PFsession_token; + true -> NFsession_token + end}. + +-compile({nowarn_unused_function,merge_msg_SDLRegisterSuperNak/3}). +merge_msg_SDLRegisterSuperNak(#'SDLRegisterSuperNak'{error_code = PFerror_code, error_message = PFerror_message}, #'SDLRegisterSuperNak'{error_code = NFerror_code, error_message = NFerror_message}, _) -> + #'SDLRegisterSuperNak'{error_code = + if NFerror_code =:= undefined -> PFerror_code; + true -> NFerror_code + end, + error_message = + if NFerror_message =:= undefined -> PFerror_message; + true -> NFerror_message + end}. + +-compile({nowarn_unused_function,merge_msg_SDLQueryInfo/3}). +merge_msg_SDLQueryInfo(#'SDLQueryInfo'{dst_mac = PFdst_mac}, #'SDLQueryInfo'{dst_mac = NFdst_mac}, _) -> + #'SDLQueryInfo'{dst_mac = + if NFdst_mac =:= undefined -> PFdst_mac; + true -> NFdst_mac + end}. + +-compile({nowarn_unused_function,merge_msg_SDLPeerInfo/3}). +merge_msg_SDLPeerInfo(#'SDLPeerInfo'{dst_mac = PFdst_mac, v4_info = PFv4_info, v6_info = PFv6_info}, #'SDLPeerInfo'{dst_mac = NFdst_mac, v4_info = NFv4_info, v6_info = NFv6_info}, TrUserData) -> + #'SDLPeerInfo'{dst_mac = + if NFdst_mac =:= undefined -> PFdst_mac; + true -> NFdst_mac + end, + v4_info = + if PFv4_info /= undefined, NFv4_info /= undefined -> merge_msg_SDLV4Info(PFv4_info, NFv4_info, TrUserData); + PFv4_info == undefined -> NFv4_info; + NFv4_info == undefined -> PFv4_info + end, + v6_info = + if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_SDLV6Info(PFv6_info, NFv6_info, TrUserData); + PFv6_info == undefined -> NFv6_info; + NFv6_info == undefined -> PFv6_info + end}. + +-compile({nowarn_unused_function,merge_msg_SDLArpRequest/3}). +merge_msg_SDLArpRequest(#'SDLArpRequest'{target_ip = PFtarget_ip, origin_ip = PForigin_ip, context = PFcontext}, #'SDLArpRequest'{target_ip = NFtarget_ip, origin_ip = NForigin_ip, context = NFcontext}, _) -> + #'SDLArpRequest'{target_ip = + if NFtarget_ip =:= undefined -> PFtarget_ip; + true -> NFtarget_ip + end, + origin_ip = + if NForigin_ip =:= undefined -> PForigin_ip; + true -> NForigin_ip + end, + context = + if NFcontext =:= undefined -> PFcontext; + true -> NFcontext + end}. + +-compile({nowarn_unused_function,merge_msg_SDLArpResponse/3}). +merge_msg_SDLArpResponse(#'SDLArpResponse'{target_ip = PFtarget_ip, target_mac = PFtarget_mac, origin_ip = PForigin_ip, context = PFcontext}, + #'SDLArpResponse'{target_ip = NFtarget_ip, target_mac = NFtarget_mac, origin_ip = NForigin_ip, context = NFcontext}, _) -> + #'SDLArpResponse'{target_ip = + if NFtarget_ip =:= undefined -> PFtarget_ip; + true -> NFtarget_ip + end, + target_mac = + if NFtarget_mac =:= undefined -> PFtarget_mac; + true -> NFtarget_mac + end, + origin_ip = + if NForigin_ip =:= undefined -> PForigin_ip; + true -> NForigin_ip + end, + context = + if NFcontext =:= undefined -> PFcontext; + true -> NFcontext + end}. + +-compile({nowarn_unused_function,merge_msg_SDLPolicyRequest/3}). +merge_msg_SDLPolicyRequest(#'SDLPolicyRequest'{src_identity_id = PFsrc_identity_id, dst_identity_id = PFdst_identity_id, version = PFversion}, + #'SDLPolicyRequest'{src_identity_id = NFsrc_identity_id, dst_identity_id = NFdst_identity_id, version = NFversion}, _) -> + #'SDLPolicyRequest'{src_identity_id = + if NFsrc_identity_id =:= undefined -> PFsrc_identity_id; + true -> NFsrc_identity_id + end, + dst_identity_id = + if NFdst_identity_id =:= undefined -> PFdst_identity_id; + true -> NFdst_identity_id + end, + version = + if NFversion =:= undefined -> PFversion; + true -> NFversion + end}. + +-compile({nowarn_unused_function,merge_msg_SDLPolicyResponse/3}). +merge_msg_SDLPolicyResponse(#'SDLPolicyResponse'{src_identity_id = PFsrc_identity_id, dst_identity_id = PFdst_identity_id, version = PFversion, rules = PFrules}, + #'SDLPolicyResponse'{src_identity_id = NFsrc_identity_id, dst_identity_id = NFdst_identity_id, version = NFversion, rules = NFrules}, _) -> + #'SDLPolicyResponse'{src_identity_id = + if NFsrc_identity_id =:= undefined -> PFsrc_identity_id; + true -> NFsrc_identity_id + end, + dst_identity_id = + if NFdst_identity_id =:= undefined -> PFdst_identity_id; + true -> NFdst_identity_id + end, + version = + if NFversion =:= undefined -> PFversion; + true -> NFversion + end, + rules = + if NFrules =:= undefined -> PFrules; + true -> NFrules + end}. + +-compile({nowarn_unused_function,'merge_msg_SDLEvent.NatChanged'/3}). +'merge_msg_SDLEvent.NatChanged'(#'SDLEvent.NatChanged'{mac = PFmac, ip = PFip}, #'SDLEvent.NatChanged'{mac = NFmac, ip = NFip}, _) -> + #'SDLEvent.NatChanged'{mac = + if NFmac =:= undefined -> PFmac; + true -> NFmac + end, + ip = + if NFip =:= undefined -> PFip; + true -> NFip + end}. + +-compile({nowarn_unused_function,'merge_msg_SDLEvent.SendRegister'/3}). +'merge_msg_SDLEvent.SendRegister'(#'SDLEvent.SendRegister'{dst_mac = PFdst_mac, nat_ip = PFnat_ip, nat_port = PFnat_port, nat_type = PFnat_type, v6_info = PFv6_info}, + #'SDLEvent.SendRegister'{dst_mac = NFdst_mac, nat_ip = NFnat_ip, nat_port = NFnat_port, nat_type = NFnat_type, v6_info = NFv6_info}, TrUserData) -> + #'SDLEvent.SendRegister'{dst_mac = + if NFdst_mac =:= undefined -> PFdst_mac; + true -> NFdst_mac + end, + nat_ip = + if NFnat_ip =:= undefined -> PFnat_ip; + true -> NFnat_ip + end, + nat_port = + if NFnat_port =:= undefined -> PFnat_port; + true -> NFnat_port + end, + nat_type = + if NFnat_type =:= undefined -> PFnat_type; + true -> NFnat_type + end, + v6_info = + if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_SDLV6Info(PFv6_info, NFv6_info, TrUserData); + PFv6_info == undefined -> NFv6_info; + NFv6_info == undefined -> PFv6_info + end}. + +-compile({nowarn_unused_function,'merge_msg_SDLEvent.NetworkShutdown'/3}). +'merge_msg_SDLEvent.NetworkShutdown'(#'SDLEvent.NetworkShutdown'{message = PFmessage}, #'SDLEvent.NetworkShutdown'{message = NFmessage}, _) -> + #'SDLEvent.NetworkShutdown'{message = + if NFmessage =:= undefined -> PFmessage; + true -> NFmessage + end}. + +-compile({nowarn_unused_function,merge_msg_SDLEvent/3}). +merge_msg_SDLEvent(#'SDLEvent'{event = PFevent}, #'SDLEvent'{event = NFevent}, TrUserData) -> + #'SDLEvent'{event = + case {PFevent, NFevent} of + {{nat_changed, OPFevent}, {nat_changed, ONFevent}} -> {nat_changed, 'merge_msg_SDLEvent.NatChanged'(OPFevent, ONFevent, TrUserData)}; + {{send_register, OPFevent}, {send_register, ONFevent}} -> {send_register, 'merge_msg_SDLEvent.SendRegister'(OPFevent, ONFevent, TrUserData)}; + {{shutdown, OPFevent}, {shutdown, ONFevent}} -> {shutdown, 'merge_msg_SDLEvent.NetworkShutdown'(OPFevent, ONFevent, TrUserData)}; + {_, undefined} -> PFevent; + _ -> NFevent + end}. + +-compile({nowarn_unused_function,'merge_msg_SDLCommand.ExitNodeControl'/3}). +'merge_msg_SDLCommand.ExitNodeControl'(#'SDLCommand.ExitNodeControl'{action = PFaction, remark = PFremark}, #'SDLCommand.ExitNodeControl'{action = NFaction, remark = NFremark}, _) -> + #'SDLCommand.ExitNodeControl'{action = + if NFaction =:= undefined -> PFaction; + true -> NFaction + end, + remark = + if NFremark =:= undefined -> PFremark; + true -> NFremark + end}. + +-compile({nowarn_unused_function,merge_msg_SDLCommand/3}). +merge_msg_SDLCommand(#'SDLCommand'{pkt_id = PFpkt_id, command = PFcommand}, #'SDLCommand'{pkt_id = NFpkt_id, command = NFcommand}, TrUserData) -> + #'SDLCommand'{pkt_id = + if NFpkt_id =:= undefined -> PFpkt_id; + true -> NFpkt_id + end, + command = + case {PFcommand, NFcommand} of + {{exit_node, OPFcommand}, {exit_node, ONFcommand}} -> {exit_node, 'merge_msg_SDLCommand.ExitNodeControl'(OPFcommand, ONFcommand, TrUserData)}; + {_, undefined} -> PFcommand; + _ -> NFcommand + end}. + +-compile({nowarn_unused_function,merge_msg_SDLCommandAck/3}). +merge_msg_SDLCommandAck(#'SDLCommandAck'{pkt_id = PFpkt_id, code = PFcode, message = PFmessage, data = PFdata}, #'SDLCommandAck'{pkt_id = NFpkt_id, code = NFcode, message = NFmessage, data = NFdata}, _) -> + #'SDLCommandAck'{pkt_id = + if NFpkt_id =:= undefined -> PFpkt_id; + true -> NFpkt_id + end, + code = + if NFcode =:= undefined -> PFcode; + true -> NFcode + end, + message = + if NFmessage =:= undefined -> PFmessage; + true -> NFmessage + end, + data = + if NFdata =:= undefined -> PFdata; + true -> NFdata + end}. + +-compile({nowarn_unused_function,merge_msg_SDLStunRequest/3}). +merge_msg_SDLStunRequest(#'SDLStunRequest'{client_id = PFclient_id, network_id = PFnetwork_id, mac = PFmac, ip = PFip, nat_type = PFnat_type, v6_info = PFv6_info, session_token = PFsession_token}, + #'SDLStunRequest'{client_id = NFclient_id, network_id = NFnetwork_id, mac = NFmac, ip = NFip, nat_type = NFnat_type, v6_info = NFv6_info, session_token = NFsession_token}, TrUserData) -> + #'SDLStunRequest'{client_id = + if NFclient_id =:= undefined -> PFclient_id; + true -> NFclient_id + end, + network_id = + if NFnetwork_id =:= undefined -> PFnetwork_id; + true -> NFnetwork_id + end, + mac = + if NFmac =:= undefined -> PFmac; + true -> NFmac + end, + ip = + if NFip =:= undefined -> PFip; + true -> NFip + end, + nat_type = + if NFnat_type =:= undefined -> PFnat_type; + true -> NFnat_type + end, + v6_info = + if PFv6_info /= undefined, NFv6_info /= undefined -> merge_msg_SDLV6Info(PFv6_info, NFv6_info, TrUserData); + PFv6_info == undefined -> NFv6_info; + NFv6_info == undefined -> PFv6_info + end, + session_token = + if NFsession_token =:= undefined -> PFsession_token; + true -> NFsession_token + end}. + +-compile({nowarn_unused_function,merge_msg_SDLStunReply/3}). +merge_msg_SDLStunReply(_Prev, New, _TrUserData) -> New. + +-compile({nowarn_unused_function,merge_msg_SDLData/3}). +merge_msg_SDLData(#'SDLData'{network_id = PFnetwork_id, src_mac = PFsrc_mac, dst_mac = PFdst_mac, is_p2p = PFis_p2p, ttl = PFttl, data = PFdata, session_token = PFsession_token, identity_id = PFidentity_id}, + #'SDLData'{network_id = NFnetwork_id, src_mac = NFsrc_mac, dst_mac = NFdst_mac, is_p2p = NFis_p2p, ttl = NFttl, data = NFdata, session_token = NFsession_token, identity_id = NFidentity_id}, _) -> + #'SDLData'{network_id = + if NFnetwork_id =:= undefined -> PFnetwork_id; + true -> NFnetwork_id + end, + src_mac = + if NFsrc_mac =:= undefined -> PFsrc_mac; + true -> NFsrc_mac + end, + dst_mac = + if NFdst_mac =:= undefined -> PFdst_mac; + true -> NFdst_mac + end, + is_p2p = + if NFis_p2p =:= undefined -> PFis_p2p; + true -> NFis_p2p + end, + ttl = + if NFttl =:= undefined -> PFttl; + true -> NFttl + end, + data = + if NFdata =:= undefined -> PFdata; + true -> NFdata + end, + session_token = + if NFsession_token =:= undefined -> PFsession_token; + true -> NFsession_token + end, + identity_id = + if NFidentity_id =:= undefined -> PFidentity_id; + true -> NFidentity_id + end}. + +-compile({nowarn_unused_function,merge_msg_SDLStunProbe/3}). +merge_msg_SDLStunProbe(#'SDLStunProbe'{cookie = PFcookie, attr = PFattr, step = PFstep}, #'SDLStunProbe'{cookie = NFcookie, attr = NFattr, step = NFstep}, _) -> + #'SDLStunProbe'{cookie = + if NFcookie =:= undefined -> PFcookie; + true -> NFcookie + end, + attr = + if NFattr =:= undefined -> PFattr; + true -> NFattr + end, + step = + if NFstep =:= undefined -> PFstep; + true -> NFstep + end}. + +-compile({nowarn_unused_function,merge_msg_SDLStunProbeReply/3}). +merge_msg_SDLStunProbeReply(#'SDLStunProbeReply'{cookie = PFcookie, step = PFstep, port = PFport, ip = PFip}, #'SDLStunProbeReply'{cookie = NFcookie, step = NFstep, port = NFport, ip = NFip}, _) -> + #'SDLStunProbeReply'{cookie = + if NFcookie =:= undefined -> PFcookie; + true -> NFcookie + end, + step = + if NFstep =:= undefined -> PFstep; + true -> NFstep + end, + port = + if NFport =:= undefined -> PFport; + true -> NFport + end, + ip = + if NFip =:= undefined -> PFip; + true -> NFip + end}. + +-compile({nowarn_unused_function,merge_msg_SDLRegister/3}). +merge_msg_SDLRegister(#'SDLRegister'{network_id = PFnetwork_id, src_mac = PFsrc_mac, dst_mac = PFdst_mac}, #'SDLRegister'{network_id = NFnetwork_id, src_mac = NFsrc_mac, dst_mac = NFdst_mac}, _) -> + #'SDLRegister'{network_id = + if NFnetwork_id =:= undefined -> PFnetwork_id; + true -> NFnetwork_id + end, + src_mac = + if NFsrc_mac =:= undefined -> PFsrc_mac; + true -> NFsrc_mac + end, + dst_mac = + if NFdst_mac =:= undefined -> PFdst_mac; + true -> NFdst_mac + end}. + +-compile({nowarn_unused_function,merge_msg_SDLRegisterAck/3}). +merge_msg_SDLRegisterAck(#'SDLRegisterAck'{network_id = PFnetwork_id, src_mac = PFsrc_mac, dst_mac = PFdst_mac}, #'SDLRegisterAck'{network_id = NFnetwork_id, src_mac = NFsrc_mac, dst_mac = NFdst_mac}, _) -> + #'SDLRegisterAck'{network_id = + if NFnetwork_id =:= undefined -> PFnetwork_id; + true -> NFnetwork_id + end, + src_mac = + if NFsrc_mac =:= undefined -> PFsrc_mac; + true -> NFsrc_mac + end, + dst_mac = + if NFdst_mac =:= undefined -> PFdst_mac; + true -> NFdst_mac + end}. + + +verify_msg(Msg) when tuple_size(Msg) >= 1 -> verify_msg(Msg, element(1, Msg), []); +verify_msg(X) -> mk_type_error(not_a_known_message, X, []). + +verify_msg(Msg, MsgName) when is_atom(MsgName) -> verify_msg(Msg, MsgName, []); +verify_msg(Msg, Opts) when tuple_size(Msg) >= 1 -> verify_msg(Msg, element(1, Msg), Opts); +verify_msg(X, _Opts) -> mk_type_error(not_a_known_message, X, []). + +verify_msg(Msg, MsgName, Opts) -> + TrUserData = proplists:get_value(user_data, Opts), + case MsgName of + 'SDLV4Info' -> v_msg_SDLV4Info(Msg, [MsgName], TrUserData); + 'SDLV6Info' -> v_msg_SDLV6Info(Msg, [MsgName], TrUserData); + 'SDLV6AssistProbe' -> v_msg_SDLV6AssistProbe(Msg, [MsgName], TrUserData); + 'SDLV6AssistProbeReply' -> v_msg_SDLV6AssistProbeReply(Msg, [MsgName], TrUserData); + 'SDLWelcome' -> v_msg_SDLWelcome(Msg, [MsgName], TrUserData); + 'SDLRegisterSuper' -> v_msg_SDLRegisterSuper(Msg, [MsgName], TrUserData); + 'SDLRegisterSuperAck' -> v_msg_SDLRegisterSuperAck(Msg, [MsgName], TrUserData); + 'SDLRegisterSuperNak' -> v_msg_SDLRegisterSuperNak(Msg, [MsgName], TrUserData); + 'SDLQueryInfo' -> v_msg_SDLQueryInfo(Msg, [MsgName], TrUserData); + 'SDLPeerInfo' -> v_msg_SDLPeerInfo(Msg, [MsgName], TrUserData); + 'SDLArpRequest' -> v_msg_SDLArpRequest(Msg, [MsgName], TrUserData); + 'SDLArpResponse' -> v_msg_SDLArpResponse(Msg, [MsgName], TrUserData); + 'SDLPolicyRequest' -> v_msg_SDLPolicyRequest(Msg, [MsgName], TrUserData); + 'SDLPolicyResponse' -> v_msg_SDLPolicyResponse(Msg, [MsgName], TrUserData); + 'SDLEvent.NatChanged' -> 'v_msg_SDLEvent.NatChanged'(Msg, [MsgName], TrUserData); + 'SDLEvent.SendRegister' -> 'v_msg_SDLEvent.SendRegister'(Msg, [MsgName], TrUserData); + 'SDLEvent.NetworkShutdown' -> 'v_msg_SDLEvent.NetworkShutdown'(Msg, [MsgName], TrUserData); + 'SDLEvent' -> v_msg_SDLEvent(Msg, [MsgName], TrUserData); + 'SDLCommand.ExitNodeControl' -> 'v_msg_SDLCommand.ExitNodeControl'(Msg, [MsgName], TrUserData); + 'SDLCommand' -> v_msg_SDLCommand(Msg, [MsgName], TrUserData); + 'SDLCommandAck' -> v_msg_SDLCommandAck(Msg, [MsgName], TrUserData); + 'SDLStunRequest' -> v_msg_SDLStunRequest(Msg, [MsgName], TrUserData); + 'SDLStunReply' -> v_msg_SDLStunReply(Msg, [MsgName], TrUserData); + 'SDLData' -> v_msg_SDLData(Msg, [MsgName], TrUserData); + 'SDLStunProbe' -> v_msg_SDLStunProbe(Msg, [MsgName], TrUserData); + 'SDLStunProbeReply' -> v_msg_SDLStunProbeReply(Msg, [MsgName], TrUserData); + 'SDLRegister' -> v_msg_SDLRegister(Msg, [MsgName], TrUserData); + 'SDLRegisterAck' -> v_msg_SDLRegisterAck(Msg, [MsgName], TrUserData); + _ -> mk_type_error(not_a_known_message, Msg, []) + end. + + +-compile({nowarn_unused_function,v_submsg_SDLV4Info/3}). +-dialyzer({nowarn_function,v_submsg_SDLV4Info/3}). +v_submsg_SDLV4Info(Msg, Path, TrUserData) -> v_msg_SDLV4Info(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,v_msg_SDLV4Info/3}). +-dialyzer({nowarn_function,v_msg_SDLV4Info/3}). +v_msg_SDLV4Info(#'SDLV4Info'{port = F1, v4 = F2, nat_type = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [port | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [v4 | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [nat_type | Path], TrUserData) + end, + ok; +v_msg_SDLV4Info(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLV4Info'}, X, Path). + +-compile({nowarn_unused_function,v_submsg_SDLV6Info/3}). +-dialyzer({nowarn_function,v_submsg_SDLV6Info/3}). +v_submsg_SDLV6Info(Msg, Path, TrUserData) -> v_msg_SDLV6Info(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,v_msg_SDLV6Info/3}). +-dialyzer({nowarn_function,v_msg_SDLV6Info/3}). +v_msg_SDLV6Info(#'SDLV6Info'{port = F1, v6 = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [port | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [v6 | Path], TrUserData) + end, + ok; +v_msg_SDLV6Info(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLV6Info'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLV6AssistProbe/3}). +-dialyzer({nowarn_function,v_msg_SDLV6AssistProbe/3}). +v_msg_SDLV6AssistProbe(#'SDLV6AssistProbe'{pkt_id = F1}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [pkt_id | Path], TrUserData) + end, + ok; +v_msg_SDLV6AssistProbe(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLV6AssistProbe'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLV6AssistProbeReply/3}). +-dialyzer({nowarn_function,v_msg_SDLV6AssistProbeReply/3}). +v_msg_SDLV6AssistProbeReply(#'SDLV6AssistProbeReply'{pkt_id = F1, v6_info = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [pkt_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_submsg_SDLV6Info(F2, [v6_info | Path], TrUserData) + end, + ok; +v_msg_SDLV6AssistProbeReply(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLV6AssistProbeReply'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLWelcome/3}). +-dialyzer({nowarn_function,v_msg_SDLWelcome/3}). +v_msg_SDLWelcome(#'SDLWelcome'{version = F1, max_bidi_streams = F2, max_packet_size = F3, heartbeat_sec = F4, ipv6_assist = F5}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [version | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [max_bidi_streams | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [max_packet_size | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_uint32(F4, [heartbeat_sec | Path], TrUserData) + end, + if F5 == undefined -> ok; + true -> v_submsg_SDLV6Info(F5, [ipv6_assist | Path], TrUserData) + end, + ok; +v_msg_SDLWelcome(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLWelcome'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLRegisterSuper/3}). +-dialyzer({nowarn_function,v_msg_SDLRegisterSuper/3}). +v_msg_SDLRegisterSuper(#'SDLRegisterSuper'{client_id = F1, network_id = F2, mac = F3, ip = F4, mask_len = F5, hostname = F6, pub_key = F7, access_token = F8}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_string(F1, [client_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [network_id | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_bytes(F3, [mac | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_uint32(F4, [ip | Path], TrUserData) + end, + if F5 == undefined -> ok; + true -> v_type_uint32(F5, [mask_len | Path], TrUserData) + end, + if F6 == undefined -> ok; + true -> v_type_string(F6, [hostname | Path], TrUserData) + end, + if F7 == undefined -> ok; + true -> v_type_string(F7, [pub_key | Path], TrUserData) + end, + if F8 == undefined -> ok; + true -> v_type_string(F8, [access_token | Path], TrUserData) + end, + ok; +v_msg_SDLRegisterSuper(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLRegisterSuper'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLRegisterSuperAck/3}). +-dialyzer({nowarn_function,v_msg_SDLRegisterSuperAck/3}). +v_msg_SDLRegisterSuperAck(#'SDLRegisterSuperAck'{algorithm = F1, key = F2, region_id = F3, session_token = F4}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_string(F1, [algorithm | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [key | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [region_id | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_bytes(F4, [session_token | Path], TrUserData) + end, + ok; +v_msg_SDLRegisterSuperAck(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLRegisterSuperAck'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLRegisterSuperNak/3}). +-dialyzer({nowarn_function,v_msg_SDLRegisterSuperNak/3}). +v_msg_SDLRegisterSuperNak(#'SDLRegisterSuperNak'{error_code = F1, error_message = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [error_code | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_string(F2, [error_message | Path], TrUserData) + end, + ok; +v_msg_SDLRegisterSuperNak(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLRegisterSuperNak'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLQueryInfo/3}). +-dialyzer({nowarn_function,v_msg_SDLQueryInfo/3}). +v_msg_SDLQueryInfo(#'SDLQueryInfo'{dst_mac = F1}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_bytes(F1, [dst_mac | Path], TrUserData) + end, + ok; +v_msg_SDLQueryInfo(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLQueryInfo'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLPeerInfo/3}). +-dialyzer({nowarn_function,v_msg_SDLPeerInfo/3}). +v_msg_SDLPeerInfo(#'SDLPeerInfo'{dst_mac = F1, v4_info = F2, v6_info = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_bytes(F1, [dst_mac | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_submsg_SDLV4Info(F2, [v4_info | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_submsg_SDLV6Info(F3, [v6_info | Path], TrUserData) + end, + ok; +v_msg_SDLPeerInfo(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLPeerInfo'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLArpRequest/3}). +-dialyzer({nowarn_function,v_msg_SDLArpRequest/3}). +v_msg_SDLArpRequest(#'SDLArpRequest'{target_ip = F1, origin_ip = F2, context = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [target_ip | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [origin_ip | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_bytes(F3, [context | Path], TrUserData) + end, + ok; +v_msg_SDLArpRequest(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLArpRequest'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLArpResponse/3}). +-dialyzer({nowarn_function,v_msg_SDLArpResponse/3}). +v_msg_SDLArpResponse(#'SDLArpResponse'{target_ip = F1, target_mac = F2, origin_ip = F3, context = F4}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [target_ip | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [target_mac | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [origin_ip | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_bytes(F4, [context | Path], TrUserData) + end, + ok; +v_msg_SDLArpResponse(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLArpResponse'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLPolicyRequest/3}). +-dialyzer({nowarn_function,v_msg_SDLPolicyRequest/3}). +v_msg_SDLPolicyRequest(#'SDLPolicyRequest'{src_identity_id = F1, dst_identity_id = F2, version = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [src_identity_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [dst_identity_id | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [version | Path], TrUserData) + end, + ok; +v_msg_SDLPolicyRequest(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLPolicyRequest'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLPolicyResponse/3}). +-dialyzer({nowarn_function,v_msg_SDLPolicyResponse/3}). +v_msg_SDLPolicyResponse(#'SDLPolicyResponse'{src_identity_id = F1, dst_identity_id = F2, version = F3, rules = F4}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [src_identity_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [dst_identity_id | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [version | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_bytes(F4, [rules | Path], TrUserData) + end, + ok; +v_msg_SDLPolicyResponse(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLPolicyResponse'}, X, Path). + +-compile({nowarn_unused_function,'v_submsg_SDLEvent.NatChanged'/3}). +-dialyzer({nowarn_function,'v_submsg_SDLEvent.NatChanged'/3}). +'v_submsg_SDLEvent.NatChanged'(Msg, Path, TrUserData) -> 'v_msg_SDLEvent.NatChanged'(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,'v_msg_SDLEvent.NatChanged'/3}). +-dialyzer({nowarn_function,'v_msg_SDLEvent.NatChanged'/3}). +'v_msg_SDLEvent.NatChanged'(#'SDLEvent.NatChanged'{mac = F1, ip = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_bytes(F1, [mac | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [ip | Path], TrUserData) + end, + ok; +'v_msg_SDLEvent.NatChanged'(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLEvent.NatChanged'}, X, Path). + +-compile({nowarn_unused_function,'v_submsg_SDLEvent.SendRegister'/3}). +-dialyzer({nowarn_function,'v_submsg_SDLEvent.SendRegister'/3}). +'v_submsg_SDLEvent.SendRegister'(Msg, Path, TrUserData) -> 'v_msg_SDLEvent.SendRegister'(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,'v_msg_SDLEvent.SendRegister'/3}). +-dialyzer({nowarn_function,'v_msg_SDLEvent.SendRegister'/3}). +'v_msg_SDLEvent.SendRegister'(#'SDLEvent.SendRegister'{dst_mac = F1, nat_ip = F2, nat_port = F3, nat_type = F4, v6_info = F5}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_bytes(F1, [dst_mac | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [nat_ip | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [nat_port | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_uint32(F4, [nat_type | Path], TrUserData) + end, + if F5 == undefined -> ok; + true -> v_submsg_SDLV6Info(F5, [v6_info | Path], TrUserData) + end, + ok; +'v_msg_SDLEvent.SendRegister'(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLEvent.SendRegister'}, X, Path). + +-compile({nowarn_unused_function,'v_submsg_SDLEvent.NetworkShutdown'/3}). +-dialyzer({nowarn_function,'v_submsg_SDLEvent.NetworkShutdown'/3}). +'v_submsg_SDLEvent.NetworkShutdown'(Msg, Path, TrUserData) -> 'v_msg_SDLEvent.NetworkShutdown'(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,'v_msg_SDLEvent.NetworkShutdown'/3}). +-dialyzer({nowarn_function,'v_msg_SDLEvent.NetworkShutdown'/3}). +'v_msg_SDLEvent.NetworkShutdown'(#'SDLEvent.NetworkShutdown'{message = F1}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_string(F1, [message | Path], TrUserData) + end, + ok; +'v_msg_SDLEvent.NetworkShutdown'(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLEvent.NetworkShutdown'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLEvent/3}). +-dialyzer({nowarn_function,v_msg_SDLEvent/3}). +v_msg_SDLEvent(#'SDLEvent'{event = F1}, Path, TrUserData) -> + case F1 of + undefined -> ok; + {nat_changed, OF1} -> 'v_submsg_SDLEvent.NatChanged'(OF1, [nat_changed, event | Path], TrUserData); + {send_register, OF1} -> 'v_submsg_SDLEvent.SendRegister'(OF1, [send_register, event | Path], TrUserData); + {shutdown, OF1} -> 'v_submsg_SDLEvent.NetworkShutdown'(OF1, [shutdown, event | Path], TrUserData); + _ -> mk_type_error(invalid_oneof, F1, [event | Path]) + end, + ok; +v_msg_SDLEvent(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLEvent'}, X, Path). + +-compile({nowarn_unused_function,'v_submsg_SDLCommand.ExitNodeControl'/3}). +-dialyzer({nowarn_function,'v_submsg_SDLCommand.ExitNodeControl'/3}). +'v_submsg_SDLCommand.ExitNodeControl'(Msg, Path, TrUserData) -> 'v_msg_SDLCommand.ExitNodeControl'(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,'v_msg_SDLCommand.ExitNodeControl'/3}). +-dialyzer({nowarn_function,'v_msg_SDLCommand.ExitNodeControl'/3}). +'v_msg_SDLCommand.ExitNodeControl'(#'SDLCommand.ExitNodeControl'{action = F1, remark = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_int32(F1, [action | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_string(F2, [remark | Path], TrUserData) + end, + ok; +'v_msg_SDLCommand.ExitNodeControl'(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLCommand.ExitNodeControl'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLCommand/3}). +-dialyzer({nowarn_function,v_msg_SDLCommand/3}). +v_msg_SDLCommand(#'SDLCommand'{pkt_id = F1, command = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [pkt_id | Path], TrUserData) + end, + case F2 of + undefined -> ok; + {exit_node, OF2} -> 'v_submsg_SDLCommand.ExitNodeControl'(OF2, [exit_node, command | Path], TrUserData); + _ -> mk_type_error(invalid_oneof, F2, [command | Path]) + end, + ok; +v_msg_SDLCommand(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLCommand'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLCommandAck/3}). +-dialyzer({nowarn_function,v_msg_SDLCommandAck/3}). +v_msg_SDLCommandAck(#'SDLCommandAck'{pkt_id = F1, code = F2, message = F3, data = F4}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [pkt_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_int32(F2, [code | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_string(F3, [message | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_bytes(F4, [data | Path], TrUserData) + end, + ok; +v_msg_SDLCommandAck(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLCommandAck'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLStunRequest/3}). +-dialyzer({nowarn_function,v_msg_SDLStunRequest/3}). +v_msg_SDLStunRequest(#'SDLStunRequest'{client_id = F1, network_id = F2, mac = F3, ip = F4, nat_type = F5, v6_info = F6, session_token = F7}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_string(F1, [client_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [network_id | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_bytes(F3, [mac | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_uint32(F4, [ip | Path], TrUserData) + end, + if F5 == undefined -> ok; + true -> v_type_uint32(F5, [nat_type | Path], TrUserData) + end, + if F6 == undefined -> ok; + true -> v_submsg_SDLV6Info(F6, [v6_info | Path], TrUserData) + end, + if F7 == undefined -> ok; + true -> v_type_bytes(F7, [session_token | Path], TrUserData) + end, + ok; +v_msg_SDLStunRequest(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLStunRequest'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLStunReply/3}). +-dialyzer({nowarn_function,v_msg_SDLStunReply/3}). +v_msg_SDLStunReply(#'SDLStunReply'{}, _Path, _) -> ok; +v_msg_SDLStunReply(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLStunReply'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLData/3}). +-dialyzer({nowarn_function,v_msg_SDLData/3}). +v_msg_SDLData(#'SDLData'{network_id = F1, src_mac = F2, dst_mac = F3, is_p2p = F4, ttl = F5, data = F6, session_token = F7, identity_id = F8}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [network_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [src_mac | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_bytes(F3, [dst_mac | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_bool(F4, [is_p2p | Path], TrUserData) + end, + if F5 == undefined -> ok; + true -> v_type_uint32(F5, [ttl | Path], TrUserData) + end, + if F6 == undefined -> ok; + true -> v_type_bytes(F6, [data | Path], TrUserData) + end, + if F7 == undefined -> ok; + true -> v_type_bytes(F7, [session_token | Path], TrUserData) + end, + if F8 == undefined -> ok; + true -> v_type_uint32(F8, [identity_id | Path], TrUserData) + end, + ok; +v_msg_SDLData(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLData'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLStunProbe/3}). +-dialyzer({nowarn_function,v_msg_SDLStunProbe/3}). +v_msg_SDLStunProbe(#'SDLStunProbe'{cookie = F1, attr = F2, step = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [cookie | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [attr | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [step | Path], TrUserData) + end, + ok; +v_msg_SDLStunProbe(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLStunProbe'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLStunProbeReply/3}). +-dialyzer({nowarn_function,v_msg_SDLStunProbeReply/3}). +v_msg_SDLStunProbeReply(#'SDLStunProbeReply'{cookie = F1, step = F2, port = F3, ip = F4}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [cookie | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_uint32(F2, [step | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_uint32(F3, [port | Path], TrUserData) + end, + if F4 == undefined -> ok; + true -> v_type_uint32(F4, [ip | Path], TrUserData) + end, + ok; +v_msg_SDLStunProbeReply(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLStunProbeReply'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLRegister/3}). +-dialyzer({nowarn_function,v_msg_SDLRegister/3}). +v_msg_SDLRegister(#'SDLRegister'{network_id = F1, src_mac = F2, dst_mac = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [network_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [src_mac | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_bytes(F3, [dst_mac | Path], TrUserData) + end, + ok; +v_msg_SDLRegister(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLRegister'}, X, Path). + +-compile({nowarn_unused_function,v_msg_SDLRegisterAck/3}). +-dialyzer({nowarn_function,v_msg_SDLRegisterAck/3}). +v_msg_SDLRegisterAck(#'SDLRegisterAck'{network_id = F1, src_mac = F2, dst_mac = F3}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_uint32(F1, [network_id | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_bytes(F2, [src_mac | Path], TrUserData) + end, + if F3 == undefined -> ok; + true -> v_type_bytes(F3, [dst_mac | Path], TrUserData) + end, + ok; +v_msg_SDLRegisterAck(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'SDLRegisterAck'}, X, Path). + +-compile({nowarn_unused_function,v_type_int32/3}). +-dialyzer({nowarn_function,v_type_int32/3}). +v_type_int32(N, _Path, _TrUserData) when is_integer(N), -2147483648 =< N, N =< 2147483647 -> ok; +v_type_int32(N, Path, _TrUserData) when is_integer(N) -> mk_type_error({value_out_of_range, int32, signed, 32}, N, Path); +v_type_int32(X, Path, _TrUserData) -> mk_type_error({bad_integer, int32, signed, 32}, X, Path). + +-compile({nowarn_unused_function,v_type_uint32/3}). +-dialyzer({nowarn_function,v_type_uint32/3}). +v_type_uint32(N, _Path, _TrUserData) when is_integer(N), 0 =< N, N =< 4294967295 -> ok; +v_type_uint32(N, Path, _TrUserData) when is_integer(N) -> mk_type_error({value_out_of_range, uint32, unsigned, 32}, N, Path); +v_type_uint32(X, Path, _TrUserData) -> mk_type_error({bad_integer, uint32, unsigned, 32}, X, Path). + +-compile({nowarn_unused_function,v_type_bool/3}). +-dialyzer({nowarn_function,v_type_bool/3}). +v_type_bool(false, _Path, _TrUserData) -> ok; +v_type_bool(true, _Path, _TrUserData) -> ok; +v_type_bool(0, _Path, _TrUserData) -> ok; +v_type_bool(1, _Path, _TrUserData) -> ok; +v_type_bool(X, Path, _TrUserData) -> mk_type_error(bad_boolean_value, X, Path). + +-compile({nowarn_unused_function,v_type_string/3}). +-dialyzer({nowarn_function,v_type_string/3}). +v_type_string(S, Path, _TrUserData) when is_list(S); is_binary(S) -> + try unicode:characters_to_binary(S) of + B when is_binary(B) -> ok; + {error, _, _} -> mk_type_error(bad_unicode_string, S, Path) + catch + error:badarg -> mk_type_error(bad_unicode_string, S, Path) + end; +v_type_string(X, Path, _TrUserData) -> mk_type_error(bad_unicode_string, X, Path). + +-compile({nowarn_unused_function,v_type_bytes/3}). +-dialyzer({nowarn_function,v_type_bytes/3}). +v_type_bytes(B, _Path, _TrUserData) when is_binary(B) -> ok; +v_type_bytes(B, _Path, _TrUserData) when is_list(B) -> ok; +v_type_bytes(X, Path, _TrUserData) -> mk_type_error(bad_binary_value, X, Path). + +-compile({nowarn_unused_function,mk_type_error/3}). +-spec mk_type_error(_, _, list()) -> no_return(). +mk_type_error(Error, ValueSeen, Path) -> + Path2 = prettify_path(Path), + erlang:error({gpb_type_error, {Error, [{value, ValueSeen}, {path, Path2}]}}). + + +-compile({nowarn_unused_function,prettify_path/1}). +-dialyzer({nowarn_function,prettify_path/1}). +prettify_path([]) -> top_level; +prettify_path(PathR) -> lists:append(lists:join(".", lists:map(fun atom_to_list/1, lists:reverse(PathR)))). + + +-compile({nowarn_unused_function,id/2}). +-compile({inline,id/2}). +id(X, _TrUserData) -> X. + +-compile({nowarn_unused_function,v_ok/3}). +-compile({inline,v_ok/3}). +v_ok(_Value, _Path, _TrUserData) -> ok. + +-compile({nowarn_unused_function,m_overwrite/3}). +-compile({inline,m_overwrite/3}). +m_overwrite(_Prev, New, _TrUserData) -> New. + +-compile({nowarn_unused_function,cons/3}). +-compile({inline,cons/3}). +cons(Elem, Acc, _TrUserData) -> [Elem | Acc]. + +-compile({nowarn_unused_function,lists_reverse/2}). +-compile({inline,lists_reverse/2}). +'lists_reverse'(L, _TrUserData) -> lists:reverse(L). +-compile({nowarn_unused_function,'erlang_++'/3}). +-compile({inline,'erlang_++'/3}). +'erlang_++'(A, B, _TrUserData) -> A ++ B. + + +get_msg_defs() -> + [{{msg, 'SDLV4Info'}, + [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = v4, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = nat_type, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLV6Info'}, [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = v6, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLV6AssistProbe'}, [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLV6AssistProbeReply'}, [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = v6_info, fnum = 2, rnum = 3, type = {msg, 'SDLV6Info'}, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLWelcome'}, + [#field{name = version, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = max_bidi_streams, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = max_packet_size, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = heartbeat_sec, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = ipv6_assist, fnum = 5, rnum = 6, type = {msg, 'SDLV6Info'}, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLRegisterSuper'}, + [#field{name = client_id, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}, + #field{name = network_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, + #field{name = ip, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = mask_len, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, + #field{name = hostname, fnum = 6, rnum = 7, type = string, occurrence = defaulty, opts = []}, + #field{name = pub_key, fnum = 7, rnum = 8, type = string, occurrence = defaulty, opts = []}, + #field{name = access_token, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLRegisterSuperAck'}, + [#field{name = algorithm, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}, + #field{name = key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = region_id, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = session_token, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLRegisterSuperNak'}, [#field{name = error_code, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = error_message, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLQueryInfo'}, [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLPeerInfo'}, + [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, + #field{name = v4_info, fnum = 2, rnum = 3, type = {msg, 'SDLV4Info'}, occurrence = optional, opts = []}, + #field{name = v6_info, fnum = 3, rnum = 4, type = {msg, 'SDLV6Info'}, occurrence = optional, opts = []}]}, + {{msg, 'SDLArpRequest'}, + [#field{name = target_ip, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = origin_ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = context, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLArpResponse'}, + [#field{name = target_ip, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = target_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = origin_ip, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = context, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLPolicyRequest'}, + [#field{name = src_identity_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = dst_identity_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = version, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLPolicyResponse'}, + [#field{name = src_identity_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = dst_identity_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = version, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = rules, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLEvent.NatChanged'}, [#field{name = mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, #field{name = ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLEvent.SendRegister'}, + [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, + #field{name = nat_ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = nat_port, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = nat_type, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = v6_info, fnum = 5, rnum = 6, type = {msg, 'SDLV6Info'}, occurrence = optional, opts = []}]}, + {{msg, 'SDLEvent.NetworkShutdown'}, [#field{name = message, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLEvent'}, + [#gpb_oneof{name = event, rnum = 2, + fields = + [#field{name = nat_changed, fnum = 1, rnum = 2, type = {msg, 'SDLEvent.NatChanged'}, occurrence = optional, opts = []}, + #field{name = send_register, fnum = 2, rnum = 2, type = {msg, 'SDLEvent.SendRegister'}, occurrence = optional, opts = []}, + #field{name = shutdown, fnum = 3, rnum = 2, type = {msg, 'SDLEvent.NetworkShutdown'}, occurrence = optional, opts = []}], + opts = []}]}, + {{msg, 'SDLCommand.ExitNodeControl'}, [#field{name = action, fnum = 1, rnum = 2, type = int32, occurrence = defaulty, opts = []}, #field{name = remark, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLCommand'}, + [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #gpb_oneof{name = command, rnum = 3, fields = [#field{name = exit_node, fnum = 2, rnum = 3, type = {msg, 'SDLCommand.ExitNodeControl'}, occurrence = optional, opts = []}], opts = []}]}, + {{msg, 'SDLCommandAck'}, + [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = code, fnum = 2, rnum = 3, type = int32, occurrence = defaulty, opts = []}, + #field{name = message, fnum = 3, rnum = 4, type = string, occurrence = defaulty, opts = []}, + #field{name = data, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLStunRequest'}, + [#field{name = client_id, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}, + #field{name = network_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, + #field{name = ip, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = nat_type, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, + #field{name = v6_info, fnum = 6, rnum = 7, type = {msg, 'SDLV6Info'}, occurrence = optional, opts = []}, + #field{name = session_token, fnum = 7, rnum = 8, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLStunReply'}, []}, + {{msg, 'SDLData'}, + [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, + #field{name = is_p2p, fnum = 4, rnum = 5, type = bool, occurrence = defaulty, opts = []}, + #field{name = ttl, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, + #field{name = data, fnum = 6, rnum = 7, type = bytes, occurrence = defaulty, opts = []}, + #field{name = session_token, fnum = 7, rnum = 8, type = bytes, occurrence = defaulty, opts = []}, + #field{name = identity_id, fnum = 8, rnum = 9, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLStunProbe'}, + [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = attr, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = step, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLStunProbeReply'}, + [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = step, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = port, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = ip, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLRegister'}, + [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]}, + {{msg, 'SDLRegisterAck'}, + [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]}]. + + +get_msg_names() -> + ['SDLV4Info', + 'SDLV6Info', + 'SDLV6AssistProbe', + 'SDLV6AssistProbeReply', + 'SDLWelcome', + 'SDLRegisterSuper', + 'SDLRegisterSuperAck', + 'SDLRegisterSuperNak', + 'SDLQueryInfo', + 'SDLPeerInfo', + 'SDLArpRequest', + 'SDLArpResponse', + 'SDLPolicyRequest', + 'SDLPolicyResponse', + 'SDLEvent.NatChanged', + 'SDLEvent.SendRegister', + 'SDLEvent.NetworkShutdown', + 'SDLEvent', + 'SDLCommand.ExitNodeControl', + 'SDLCommand', + 'SDLCommandAck', + 'SDLStunRequest', + 'SDLStunReply', + 'SDLData', + 'SDLStunProbe', + 'SDLStunProbeReply', + 'SDLRegister', + 'SDLRegisterAck']. + + +get_group_names() -> []. + + +get_msg_or_group_names() -> + ['SDLV4Info', + 'SDLV6Info', + 'SDLV6AssistProbe', + 'SDLV6AssistProbeReply', + 'SDLWelcome', + 'SDLRegisterSuper', + 'SDLRegisterSuperAck', + 'SDLRegisterSuperNak', + 'SDLQueryInfo', + 'SDLPeerInfo', + 'SDLArpRequest', + 'SDLArpResponse', + 'SDLPolicyRequest', + 'SDLPolicyResponse', + 'SDLEvent.NatChanged', + 'SDLEvent.SendRegister', + 'SDLEvent.NetworkShutdown', + 'SDLEvent', + 'SDLCommand.ExitNodeControl', + 'SDLCommand', + 'SDLCommandAck', + 'SDLStunRequest', + 'SDLStunReply', + 'SDLData', + 'SDLStunProbe', + 'SDLStunProbeReply', + 'SDLRegister', + 'SDLRegisterAck']. + + +get_enum_names() -> []. + + +fetch_msg_def(MsgName) -> + case find_msg_def(MsgName) of + Fs when is_list(Fs) -> Fs; + error -> erlang:error({no_such_msg, MsgName}) + end. + + +-spec fetch_enum_def(_) -> no_return(). +fetch_enum_def(EnumName) -> erlang:error({no_such_enum, EnumName}). + + +find_msg_def('SDLV4Info') -> + [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = v4, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = nat_type, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLV6Info') -> [#field{name = port, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = v6, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLV6AssistProbe') -> [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLV6AssistProbeReply') -> [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = v6_info, fnum = 2, rnum = 3, type = {msg, 'SDLV6Info'}, occurrence = defaulty, opts = []}]; +find_msg_def('SDLWelcome') -> + [#field{name = version, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = max_bidi_streams, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = max_packet_size, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = heartbeat_sec, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = ipv6_assist, fnum = 5, rnum = 6, type = {msg, 'SDLV6Info'}, occurrence = defaulty, opts = []}]; +find_msg_def('SDLRegisterSuper') -> + [#field{name = client_id, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}, + #field{name = network_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, + #field{name = ip, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = mask_len, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, + #field{name = hostname, fnum = 6, rnum = 7, type = string, occurrence = defaulty, opts = []}, + #field{name = pub_key, fnum = 7, rnum = 8, type = string, occurrence = defaulty, opts = []}, + #field{name = access_token, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]; +find_msg_def('SDLRegisterSuperAck') -> + [#field{name = algorithm, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}, + #field{name = key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = region_id, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = session_token, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLRegisterSuperNak') -> [#field{name = error_code, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, #field{name = error_message, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}]; +find_msg_def('SDLQueryInfo') -> [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLPeerInfo') -> + [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, + #field{name = v4_info, fnum = 2, rnum = 3, type = {msg, 'SDLV4Info'}, occurrence = optional, opts = []}, + #field{name = v6_info, fnum = 3, rnum = 4, type = {msg, 'SDLV6Info'}, occurrence = optional, opts = []}]; +find_msg_def('SDLArpRequest') -> + [#field{name = target_ip, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = origin_ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = context, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLArpResponse') -> + [#field{name = target_ip, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = target_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = origin_ip, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = context, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLPolicyRequest') -> + [#field{name = src_identity_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = dst_identity_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = version, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLPolicyResponse') -> + [#field{name = src_identity_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = dst_identity_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = version, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = rules, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLEvent.NatChanged') -> [#field{name = mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, #field{name = ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLEvent.SendRegister') -> + [#field{name = dst_mac, fnum = 1, rnum = 2, type = bytes, occurrence = defaulty, opts = []}, + #field{name = nat_ip, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = nat_port, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = nat_type, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = v6_info, fnum = 5, rnum = 6, type = {msg, 'SDLV6Info'}, occurrence = optional, opts = []}]; +find_msg_def('SDLEvent.NetworkShutdown') -> [#field{name = message, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}]; +find_msg_def('SDLEvent') -> + [#gpb_oneof{name = event, rnum = 2, + fields = + [#field{name = nat_changed, fnum = 1, rnum = 2, type = {msg, 'SDLEvent.NatChanged'}, occurrence = optional, opts = []}, + #field{name = send_register, fnum = 2, rnum = 2, type = {msg, 'SDLEvent.SendRegister'}, occurrence = optional, opts = []}, + #field{name = shutdown, fnum = 3, rnum = 2, type = {msg, 'SDLEvent.NetworkShutdown'}, occurrence = optional, opts = []}], + opts = []}]; +find_msg_def('SDLCommand.ExitNodeControl') -> [#field{name = action, fnum = 1, rnum = 2, type = int32, occurrence = defaulty, opts = []}, #field{name = remark, fnum = 2, rnum = 3, type = string, occurrence = defaulty, opts = []}]; +find_msg_def('SDLCommand') -> + [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #gpb_oneof{name = command, rnum = 3, fields = [#field{name = exit_node, fnum = 2, rnum = 3, type = {msg, 'SDLCommand.ExitNodeControl'}, occurrence = optional, opts = []}], opts = []}]; +find_msg_def('SDLCommandAck') -> + [#field{name = pkt_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = code, fnum = 2, rnum = 3, type = int32, occurrence = defaulty, opts = []}, + #field{name = message, fnum = 3, rnum = 4, type = string, occurrence = defaulty, opts = []}, + #field{name = data, fnum = 4, rnum = 5, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLStunRequest') -> + [#field{name = client_id, fnum = 1, rnum = 2, type = string, occurrence = defaulty, opts = []}, + #field{name = network_id, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, + #field{name = ip, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}, + #field{name = nat_type, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, + #field{name = v6_info, fnum = 6, rnum = 7, type = {msg, 'SDLV6Info'}, occurrence = optional, opts = []}, + #field{name = session_token, fnum = 7, rnum = 8, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLStunReply') -> []; +find_msg_def('SDLData') -> + [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}, + #field{name = is_p2p, fnum = 4, rnum = 5, type = bool, occurrence = defaulty, opts = []}, + #field{name = ttl, fnum = 5, rnum = 6, type = uint32, occurrence = defaulty, opts = []}, + #field{name = data, fnum = 6, rnum = 7, type = bytes, occurrence = defaulty, opts = []}, + #field{name = session_token, fnum = 7, rnum = 8, type = bytes, occurrence = defaulty, opts = []}, + #field{name = identity_id, fnum = 8, rnum = 9, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLStunProbe') -> + [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = attr, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = step, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLStunProbeReply') -> + [#field{name = cookie, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = step, fnum = 2, rnum = 3, type = uint32, occurrence = defaulty, opts = []}, + #field{name = port, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []}, + #field{name = ip, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}]; +find_msg_def('SDLRegister') -> + [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def('SDLRegisterAck') -> + [#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []}, + #field{name = src_mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, + #field{name = dst_mac, fnum = 3, rnum = 4, type = bytes, occurrence = defaulty, opts = []}]; +find_msg_def(_) -> error. + + +find_enum_def(_) -> error. + + +-spec enum_symbol_by_value(_, _) -> no_return(). +enum_symbol_by_value(E, V) -> erlang:error({no_enum_defs, E, V}). + + +-spec enum_value_by_symbol(_, _) -> no_return(). +enum_value_by_symbol(E, V) -> erlang:error({no_enum_defs, E, V}). + + + +get_service_names() -> []. + + +get_service_def(_) -> error. + + +get_rpc_names(_) -> error. + + +find_rpc_def(_, _) -> error. + + + +-spec fetch_rpc_def(_, _) -> no_return(). +fetch_rpc_def(ServiceName, RpcName) -> erlang:error({no_such_rpc, ServiceName, RpcName}). + + +%% Convert a a fully qualified (ie with package name) service name +%% as a binary to a service name as an atom. +-spec fqbin_to_service_name(_) -> no_return(). +fqbin_to_service_name(X) -> error({gpb_error, {badservice, X}}). + + +%% Convert a service name as an atom to a fully qualified +%% (ie with package name) name as a binary. +-spec service_name_to_fqbin(_) -> no_return(). +service_name_to_fqbin(X) -> error({gpb_error, {badservice, X}}). + + +%% Convert a a fully qualified (ie with package name) service name +%% and an rpc name, both as binaries to a service name and an rpc +%% name, as atoms. +-spec fqbins_to_service_and_rpc_name(_, _) -> no_return(). +fqbins_to_service_and_rpc_name(S, R) -> error({gpb_error, {badservice_or_rpc, {S, R}}}). + + +%% Convert a service name and an rpc name, both as atoms, +%% to a fully qualified (ie with package name) service name and +%% an rpc name as binaries. +-spec service_and_rpc_name_to_fqbins(_, _) -> no_return(). +service_and_rpc_name_to_fqbins(S, R) -> error({gpb_error, {badservice_or_rpc, {S, R}}}). + + +fqbin_to_msg_name(<<"SDLV4Info">>) -> 'SDLV4Info'; +fqbin_to_msg_name(<<"SDLV6Info">>) -> 'SDLV6Info'; +fqbin_to_msg_name(<<"SDLV6AssistProbe">>) -> 'SDLV6AssistProbe'; +fqbin_to_msg_name(<<"SDLV6AssistProbeReply">>) -> 'SDLV6AssistProbeReply'; +fqbin_to_msg_name(<<"SDLWelcome">>) -> 'SDLWelcome'; +fqbin_to_msg_name(<<"SDLRegisterSuper">>) -> 'SDLRegisterSuper'; +fqbin_to_msg_name(<<"SDLRegisterSuperAck">>) -> 'SDLRegisterSuperAck'; +fqbin_to_msg_name(<<"SDLRegisterSuperNak">>) -> 'SDLRegisterSuperNak'; +fqbin_to_msg_name(<<"SDLQueryInfo">>) -> 'SDLQueryInfo'; +fqbin_to_msg_name(<<"SDLPeerInfo">>) -> 'SDLPeerInfo'; +fqbin_to_msg_name(<<"SDLArpRequest">>) -> 'SDLArpRequest'; +fqbin_to_msg_name(<<"SDLArpResponse">>) -> 'SDLArpResponse'; +fqbin_to_msg_name(<<"SDLPolicyRequest">>) -> 'SDLPolicyRequest'; +fqbin_to_msg_name(<<"SDLPolicyResponse">>) -> 'SDLPolicyResponse'; +fqbin_to_msg_name(<<"SDLEvent.NatChanged">>) -> 'SDLEvent.NatChanged'; +fqbin_to_msg_name(<<"SDLEvent.SendRegister">>) -> 'SDLEvent.SendRegister'; +fqbin_to_msg_name(<<"SDLEvent.NetworkShutdown">>) -> 'SDLEvent.NetworkShutdown'; +fqbin_to_msg_name(<<"SDLEvent">>) -> 'SDLEvent'; +fqbin_to_msg_name(<<"SDLCommand.ExitNodeControl">>) -> 'SDLCommand.ExitNodeControl'; +fqbin_to_msg_name(<<"SDLCommand">>) -> 'SDLCommand'; +fqbin_to_msg_name(<<"SDLCommandAck">>) -> 'SDLCommandAck'; +fqbin_to_msg_name(<<"SDLStunRequest">>) -> 'SDLStunRequest'; +fqbin_to_msg_name(<<"SDLStunReply">>) -> 'SDLStunReply'; +fqbin_to_msg_name(<<"SDLData">>) -> 'SDLData'; +fqbin_to_msg_name(<<"SDLStunProbe">>) -> 'SDLStunProbe'; +fqbin_to_msg_name(<<"SDLStunProbeReply">>) -> 'SDLStunProbeReply'; +fqbin_to_msg_name(<<"SDLRegister">>) -> 'SDLRegister'; +fqbin_to_msg_name(<<"SDLRegisterAck">>) -> 'SDLRegisterAck'; +fqbin_to_msg_name(E) -> error({gpb_error, {badmsg, E}}). + + +msg_name_to_fqbin('SDLV4Info') -> <<"SDLV4Info">>; +msg_name_to_fqbin('SDLV6Info') -> <<"SDLV6Info">>; +msg_name_to_fqbin('SDLV6AssistProbe') -> <<"SDLV6AssistProbe">>; +msg_name_to_fqbin('SDLV6AssistProbeReply') -> <<"SDLV6AssistProbeReply">>; +msg_name_to_fqbin('SDLWelcome') -> <<"SDLWelcome">>; +msg_name_to_fqbin('SDLRegisterSuper') -> <<"SDLRegisterSuper">>; +msg_name_to_fqbin('SDLRegisterSuperAck') -> <<"SDLRegisterSuperAck">>; +msg_name_to_fqbin('SDLRegisterSuperNak') -> <<"SDLRegisterSuperNak">>; +msg_name_to_fqbin('SDLQueryInfo') -> <<"SDLQueryInfo">>; +msg_name_to_fqbin('SDLPeerInfo') -> <<"SDLPeerInfo">>; +msg_name_to_fqbin('SDLArpRequest') -> <<"SDLArpRequest">>; +msg_name_to_fqbin('SDLArpResponse') -> <<"SDLArpResponse">>; +msg_name_to_fqbin('SDLPolicyRequest') -> <<"SDLPolicyRequest">>; +msg_name_to_fqbin('SDLPolicyResponse') -> <<"SDLPolicyResponse">>; +msg_name_to_fqbin('SDLEvent.NatChanged') -> <<"SDLEvent.NatChanged">>; +msg_name_to_fqbin('SDLEvent.SendRegister') -> <<"SDLEvent.SendRegister">>; +msg_name_to_fqbin('SDLEvent.NetworkShutdown') -> <<"SDLEvent.NetworkShutdown">>; +msg_name_to_fqbin('SDLEvent') -> <<"SDLEvent">>; +msg_name_to_fqbin('SDLCommand.ExitNodeControl') -> <<"SDLCommand.ExitNodeControl">>; +msg_name_to_fqbin('SDLCommand') -> <<"SDLCommand">>; +msg_name_to_fqbin('SDLCommandAck') -> <<"SDLCommandAck">>; +msg_name_to_fqbin('SDLStunRequest') -> <<"SDLStunRequest">>; +msg_name_to_fqbin('SDLStunReply') -> <<"SDLStunReply">>; +msg_name_to_fqbin('SDLData') -> <<"SDLData">>; +msg_name_to_fqbin('SDLStunProbe') -> <<"SDLStunProbe">>; +msg_name_to_fqbin('SDLStunProbeReply') -> <<"SDLStunProbeReply">>; +msg_name_to_fqbin('SDLRegister') -> <<"SDLRegister">>; +msg_name_to_fqbin('SDLRegisterAck') -> <<"SDLRegisterAck">>; +msg_name_to_fqbin(E) -> error({gpb_error, {badmsg, E}}). + + +-spec fqbin_to_enum_name(_) -> no_return(). +fqbin_to_enum_name(E) -> error({gpb_error, {badenum, E}}). + + +-spec enum_name_to_fqbin(_) -> no_return(). +enum_name_to_fqbin(E) -> error({gpb_error, {badenum, E}}). + + +get_package_name() -> undefined. + + +%% Whether or not the message names +%% are prepended with package name or not. +uses_packages() -> false. + + +source_basename() -> "sdlan.proto". + + +%% Retrieve all proto file names, also imported ones. +%% The order is top-down. The first element is always the main +%% source file. The files are returned with extension, +%% see get_all_proto_names/0 for a version that returns +%% the basenames sans extension +get_all_source_basenames() -> ["sdlan.proto"]. + + +%% Retrieve all proto file names, also imported ones. +%% The order is top-down. The first element is always the main +%% source file. The files are returned sans .proto extension, +%% to make it easier to use them with the various get_xyz_containment +%% functions. +get_all_proto_names() -> ["sdlan"]. + + +get_msg_containment("sdlan") -> + ['SDLArpRequest', + 'SDLArpResponse', + 'SDLCommand', + 'SDLCommand.ExitNodeControl', + 'SDLCommandAck', + 'SDLData', + 'SDLEvent', + 'SDLEvent.NatChanged', + 'SDLEvent.NetworkShutdown', + 'SDLEvent.SendRegister', + 'SDLPeerInfo', + 'SDLPolicyRequest', + 'SDLPolicyResponse', + 'SDLQueryInfo', + 'SDLRegister', + 'SDLRegisterAck', + 'SDLRegisterSuper', + 'SDLRegisterSuperAck', + 'SDLRegisterSuperNak', + 'SDLStunProbe', + 'SDLStunProbeReply', + 'SDLStunReply', + 'SDLStunRequest', + 'SDLV4Info', + 'SDLV6AssistProbe', + 'SDLV6AssistProbeReply', + 'SDLV6Info', + 'SDLWelcome']; +get_msg_containment(P) -> error({gpb_error, {badproto, P}}). + + +get_pkg_containment("sdlan") -> undefined; +get_pkg_containment(P) -> error({gpb_error, {badproto, P}}). + + +get_service_containment("sdlan") -> []; +get_service_containment(P) -> error({gpb_error, {badproto, P}}). + + +get_rpc_containment("sdlan") -> []; +get_rpc_containment(P) -> error({gpb_error, {badproto, P}}). + + +get_enum_containment("sdlan") -> []; +get_enum_containment(P) -> error({gpb_error, {badproto, P}}). + + +get_proto_by_msg_name_as_fqbin(<<"SDLData">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLRegisterSuper">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLRegister">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLEvent.SendRegister">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLStunRequest">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLPolicyRequest">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLEvent.NatChanged">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLEvent">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLCommand">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLArpRequest">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLWelcome">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLV6AssistProbe">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLStunProbe">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLPolicyResponse">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLArpResponse">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLV6AssistProbeReply">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLStunReply">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLStunProbeReply">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLRegisterSuperNak">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLRegisterSuperAck">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLRegisterAck">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLCommandAck">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLCommand.ExitNodeControl">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLEvent.NetworkShutdown">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLV6Info">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLV4Info">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLQueryInfo">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(<<"SDLPeerInfo">>) -> "sdlan"; +get_proto_by_msg_name_as_fqbin(E) -> error({gpb_error, {badmsg, E}}). + + +-spec get_proto_by_service_name_as_fqbin(_) -> no_return(). +get_proto_by_service_name_as_fqbin(E) -> error({gpb_error, {badservice, E}}). + + +-spec get_proto_by_enum_name_as_fqbin(_) -> no_return(). +get_proto_by_enum_name_as_fqbin(E) -> error({gpb_error, {badenum, E}}). + + +-spec get_protos_by_pkg_name_as_fqbin(_) -> no_return(). +get_protos_by_pkg_name_as_fqbin(E) -> error({gpb_error, {badpkg, E}}). + + + +gpb_version_as_string() -> + "4.21.7". + +gpb_version_as_list() -> + [4,21,7]. + +gpb_version_source() -> + "file". diff --git a/src/sdlan_session.erl b/src/sdlan_session.erl new file mode 100644 index 0000000..fc008ae --- /dev/null +++ b/src/sdlan_session.erl @@ -0,0 +1,379 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% Transport independent sdlan session logic. +%%% @end +%%%------------------------------------------------------------------- +-module(sdlan_session). +-author("anlicheng"). +-include("sdlan.hrl"). +-include("sdlan_pb.hrl"). + +%% API +-export([new/2, handle_frame/2, handle_timeout/2]). +-export([send_event/2, command/4, close/1, debug_info/1]). +-export([welcome_packet/2]). +-export([test_rules/2]). +-export_type([session/0]). + +%% 心跳包监测机制 +-define(PING_TICKER, 15000). + +%% 注册失败的的错误码 + +%% 网络错误 +-define(NAK_NETWORK_FAULT, 4). +%% 内部错误 +-define(NAK_INTERNAL_FAULT, 5). + +-record(session, { + transport :: atom(), + status = initialized :: initialized | registered, + %% 心跳间隔 + heartbeat_sec = 15, + ping_timer :: undefined | reference(), + + client_id :: undefined | binary(), + network_id = 0 :: integer(), + %% 网络相关信息id + network_pid :: undefined | pid(), + %% mac地址 + mac :: undefined | binary(), + ip = 0 :: integer(), + + %% 建立请求和响应的对应关系 + pkt_id = 1, + %% #{pkt_id => {Ref, ReceiverPid}} + pending_commands = #{}, + + ping_counter = 0, + + %% 离线回调函数 + offline_cb :: undefined | fun() +}). + +-type session() :: #session{}. + +%%%=================================================================== +%%% API +%%%=================================================================== + +-spec new(HeartbeatSec :: integer(), Transport :: atom()) -> #session{}. +new(HeartbeatSec, Transport) -> + #session{heartbeat_sec = HeartbeatSec, transport = Transport}. + +%% 测试规则函数 +-spec test_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> binary(). +test_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) -> + {ok, Rules} = get_rules(SrcIdentityId, DstIdentityId), + logger:debug("[sdlan_session] test_rules policy_request src_identity_id: ~p, dst_identity_id: ~p, rules: ~p", [SrcIdentityId, DstIdentityId, Rules]), + iolist_to_binary(lists:map(fun({Proto, Port}) -> <> end, Rules)). + +-spec welcome_packet(MaxPacketSize :: integer(), HeartbeatSec :: integer()) -> binary(). +welcome_packet(MaxPacketSize, HeartbeatSec) -> + Ipv6Assist = case application:get_env(sdlan, ipv6_assist_info) of + {ok, {V6Bytes, Port}} -> + #'SDLV6Info'{v6 = V6Bytes, port = Port}; + _ -> + undefined + end, + WelcomePkt = sdlan_pb:encode_msg(#'SDLWelcome'{ + version = 1, + max_bidi_streams = 1, + max_packet_size = MaxPacketSize, + heartbeat_sec = HeartbeatSec, + ipv6_assist = Ipv6Assist + }), + <>. + +-spec handle_frame(Frame :: binary(), Session :: #session{}) -> + {ok, StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]} | + {stop, Reason :: term(), StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]}. +handle_frame(<>, Session = #session{status = initialized, transport = Transport}) -> + #'SDLRegisterSuper'{ + client_id = ClientId, network_id = NetworkId, mac = Mac, ip = Ip, mask_len = MaskLen, + hostname = HostName, pub_key = PubKey, access_token = AccessToken} = sdlan_pb:decode_msg(Body, 'SDLRegisterSuper'), + + true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>), + %% Mac地址不能是广播地址 + true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)), + + MacBinStr = sdlan_util:format_mac(Mac), + IpAddr = sdlan_util:int_to_ipv4(Ip), + Params = #{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"mac">> => MacBinStr, + <<"ip">> => IpAddr, + <<"mask_len">> => MaskLen, + <<"hostname">> => HostName, + <<"access_token">> => AccessToken + }, + %% 参数检查 + logger:debug("[sdlan_session] transport: ~p, client_id: ~p, ip: ~p, mac: ~p, host_name: ~p, access_token: ~p, network_id: ~p", + [Transport, ClientId, Ip, Mac, HostName, AccessToken, NetworkId]), + + case sdlan_api:auth_access_token(Params) of + {ok, #{<<"result">> := <<"ok">>}} -> + %% 建立到network的对应关系 + case sdlan_network:get_pid(NetworkId) of + NetworkPid when is_pid(NetworkPid) -> + {ok, Algorithm, Key, RegionId, SessionToken} = sdlan_network:attach(NetworkPid, self(), ClientId, Mac, Ip, HostName), + RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), + RegisterSuperAck = sdlan_pb:encode_msg(#'SDLRegisterSuperAck'{ + algorithm = Algorithm, + key = rsa_encode(Key, RsaPubKey), + region_id = RegionId, + session_token = SessionToken + }), + + %% 设置节点的在线状态 + Result = sdlan_api:set_node_status(#{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"access_token">> => AccessToken, + <<"status">> => 1 + }), + logger:debug("[sdlan_session] tranport: ~p, client_id: ~p, set none online result is: ~p", [Transport, ClientId, Result]), + + OfflineCb = fun() -> + sdlan_api:set_node_status(#{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"access_token">> => AccessToken, + <<"status">> => 0 + }) + end, + NSession = schedule_ping(Session#session{ + status = registered, + network_id = NetworkId, + network_pid = NetworkPid, + client_id = ClientId, + mac = Mac, + ip = Ip, + offline_cb = OfflineCb + }), + ok_result(NSession, [<>]); + undefined -> + logger:warning("[sdlan_session] transport: ~p, client_id: ~p, register get error: network not found", [Transport, ClientId]), + stop_result(normal, Session, [register_nak_reply(?NAK_INTERNAL_FAULT, <<"Internal Error">>)]) + end; + {ok, #{<<"error">> := #{<<"code">> := Code, <<"message">> := Message}}} -> + logger:warning("[sdlan_session] transport: ~p, network_id: ~p, client_id: ~p, register get error: ~ts, error_code: ~p", [Transport, NetworkId, ClientId, Message, Code]), + stop_result(normal, Session, [register_nak_reply(Code, Message)]); + {error, Reason} -> + logger:warning("[sdlan_session] transport: ~p, network_id: ~p, client_id: ~p, register get error: ~p", [Transport, NetworkId, ClientId, Reason]), + stop_result(normal, Session, [register_nak_reply(?NAK_NETWORK_FAULT, <<"Network Error">>)]) + end; + +handle_frame(<>, Session = #session{status = registered, network_pid = NetworkPid, mac = SrcMac, transport = Transport}) when is_pid(NetworkPid) -> + #'SDLQueryInfo'{dst_mac = DstMac} = sdlan_pb:decode_msg(Body, 'SDLQueryInfo'), + case sdlan_network:peer_info(NetworkPid, SrcMac, DstMac) of + error -> + logger:debug("[sdlan_session] transport: ~p, query_info src_mac is: ~p, dst_mac: ~p, nat_peer not found", + [Transport, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + + EmptyResponse = sdlan_pb:encode_msg(#'SDLPeerInfo'{ + dst_mac = DstMac, + v4_info = undefined, + v6_info = undefined + }), + ok_result(Session, [<>]); + {ok, {NatPeer = {{Ip0, Ip1, Ip2, Ip3}, NatPort}, NatType}, V6Info} -> + logger:debug("[sdlan_session] transport: ~p, query_info src_mac is: ~p, dst_mac: ~p, nat_peer: ~p", + [Transport, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), NatPeer]), + + PeerInfo = sdlan_pb:encode_msg(#'SDLPeerInfo'{ + dst_mac = DstMac, + v4_info = #'SDLV4Info' { + port = NatPort, + v4 = <>, + nat_type = NatType + }, + v6_info = V6Info + }), + ok_result(Session, [<>]) + end; + +%% arp查询 +handle_frame(<>, + Session = #session{status = registered, network_id = NetworkId, network_pid = NetworkPid, transport = Transport}) when is_pid(NetworkPid) -> + + #'SDLArpRequest'{target_ip = TargetIp, origin_ip = OriginIp, context = Context} = sdlan_pb:decode_msg(Body, 'SDLArpRequest'), + case sdlan_network:arp_request(NetworkPid, TargetIp) of + error -> + logger:debug("[sdlan_session] transport: ~p, network: ~p, arp_request target_ip: ~p, mac not found", + [Transport, NetworkId, sdlan_util:int_to_ipv4(TargetIp)]), + + EmptyArpResponsePkt = sdlan_pb:encode_msg(#'SDLArpResponse'{ + target_ip = TargetIp, + target_mac = <<>>, + origin_ip = OriginIp, + context = Context + }), + ok_result(Session, [<>]); + {ok, Mac} -> + logger:debug("[sdlan_session] transport: ~p, network: ~p, arp_request target_ip: ~p, mac: ~p", + [Transport, NetworkId, sdlan_util:int_to_ipv4(TargetIp), sdlan_util:format_mac(Mac)]), + ArpResponsePkt = sdlan_pb:encode_msg(#'SDLArpResponse'{ + target_ip = TargetIp, + target_mac = Mac, + origin_ip = OriginIp, + context = Context + }), + ok_result(Session, [<>]) + end; + +handle_frame(<>, Session = #session{status = registered, network_pid = NetworkPid, transport = Transport}) when is_pid(NetworkPid) -> + Packets = maybe + #'SDLPolicyRequest'{src_identity_id = SrcIdentityId, dst_identity_id = DstIdentityId, version = Version} ?= sdlan_pb:decode_msg(Body, 'SDLPolicyRequest'), + + {ok, Rules} = get_rules(SrcIdentityId, DstIdentityId), + logger:debug("[sdlan_session] transport: ~p, policy_request src_identity_id: ~p, dst_identity_id: ~p, rules: ~p", + [Transport, SrcIdentityId, DstIdentityId, Rules]), + + RuleBin = iolist_to_binary(lists:map(fun({Proto, Port}) -> <> end, Rules)), + PolicyResponsePkt = sdlan_pb:encode_msg(#'SDLPolicyResponse'{ + src_identity_id = SrcIdentityId, + dst_identity_id = DstIdentityId, + version = Version, + rules = RuleBin + }), + [<>] + else _ -> + [] + end, + ok_result(Session, Packets); + +%% 处理命令的响应逻辑 +handle_frame(<>, Session = #session{status = registered, pending_commands = PendingCommands, transport = Transport}) -> + logger:debug("[sdlan_session] transport: ~p command_ack", [Transport]), + maybe + CommandAck = sdlan_pb:decode_msg(Body, 'SDLCommandAck'), + #'SDLCommandAck'{pkt_id = PktId} ?= CommandAck, + + {{Ref, ReceiverPid}, RestPendingCommands} ?= maps:take(PktId, PendingCommands), + case is_process_alive(ReceiverPid) of + true -> + ReceiverPid ! {quic_command_ack, Ref, CommandAck}; + false -> + ok + end, + ok_result(Session#session{pending_commands = RestPendingCommands}, []) + else _ -> + ok_result(Session, []) + end; + +handle_frame(<>, Session = #session{ping_counter = PingCounter, client_id = ClientId, transport = Transport}) -> + logger:warning("[sdlan_session] transport: ~p, get ping: ~p", [Transport, ClientId]), + ok_result(Session#session{ping_counter = PingCounter + 1}, [<>]); + +%% 取消注册 +handle_frame(<>, Session = #session{status = registered, client_id = ClientId, mac = Mac, network_pid = NetworkPid, transport = Transport}) + when is_pid(NetworkPid) -> + + logger:warning("[sdlan_session] transport: ~p, unregister client_id: ~p", [Transport, ClientId]), + sdlan_network:unregister(NetworkPid, ClientId, Mac), + stop_result(normal, Session, []); + +handle_frame(Frame, Session = #session{transport = Transport}) -> + logger:notice("[sdlan_session] transport: ~p, unexpected frame: ~p, status: ~p", [Transport, Frame, Session#session.status]), + ok_result(Session, []). + +-spec handle_timeout(TimerRef :: reference(), Session :: #session{}) -> + {ok, StateName :: initialized | registered, NewSession :: #session{}} | + {stop, Reason :: term(), StateName :: initialized | registered, NewSession :: #session{}}. +handle_timeout(TimerRef, Session = #session{ping_timer = TimerRef, client_id = ClientId, ping_counter = PingCounter, transport = Transport}) -> + case PingCounter > 0 of + true -> + ok_timeout_result(schedule_ping(Session#session{ping_counter = 0, ping_timer = undefined})); + false -> + logger:debug("[sdlan_session] transport: ~p, client_id: ~p, ping losted", [Transport, ClientId]), + stop_timeout_result(heartbeat_timeout, Session#session{ping_counter = 0, ping_timer = undefined}) + end; +handle_timeout(_TimerRef, Session) -> + ok_timeout_result(Session). + +-spec send_event(Event :: binary(), Session :: #session{}) -> + {ok, StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]} | {error, not_registered}. +send_event(Event, Session = #session{status = registered}) when is_binary(Event) -> + ok_result(Session, [<>]); +send_event(_Event, _Session) -> + {error, not_registered}. + +-spec command(Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}, Session :: #session{}) -> + {ok, StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]} | {error, not_registered}. +command(Ref, ReceiverPid, SubCommand, Session = #session{status = registered, pkt_id = PktId, pending_commands = PendingCommands, client_id = ClientId, transport = Transport}) + when is_reference(Ref), is_pid(ReceiverPid) -> + CommandPkt = sdlan_pb:encode_msg(#'SDLCommand'{ + pkt_id = PktId, + command = SubCommand + }), + logger:debug("[sdlan_session] transport: ~p, client_id: ~p, will send Command: ~p", [Transport, ClientId, SubCommand]), + + ok_result(Session#session{pkt_id = PktId + 1, pending_commands = maps:put(PktId, {Ref, ReceiverPid}, PendingCommands)}, + [<>]); +command(_Ref, _ReceiverPid, _SubCommand, _Session) -> + {error, not_registered}. + +-spec close(Session :: #session{}) -> ok. +close(#session{offline_cb = OfflineCb}) -> + %% 触发客户端的离线逻辑 + is_function(OfflineCb) andalso OfflineCb(), + ok. + +-spec debug_info(Session :: #session{}) -> map(). +debug_info(#session{ status = Status, client_id = ClientId, network_id = NetworkId, mac = Mac, ip = Ip, + pending_commands = PendingCommands, heartbeat_sec = HeartbeatSec}) -> + + #{ + session_state => Status, + client_id => ClientId, + network_id => NetworkId, + mac => Mac, + ip => Ip, + pending_commands => maps:size(PendingCommands), + heartbeat_sec => HeartbeatSec + }. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +-spec register_nak_reply(ErrorCode :: integer(), ErrorMsg :: binary()) -> binary(). +register_nak_reply(ErrorCode, ErrorMsg) when is_integer(ErrorCode), is_binary(ErrorMsg) -> + RegisterNakReply = sdlan_pb:encode_msg(#'SDLRegisterSuperNak'{ + error_code = ErrorCode, + error_message = ErrorMsg + }), + <>. + +rsa_encode(PlainText, RsaPubKey) when is_binary(PlainText) -> + iolist_to_binary(sdlan_cipher:rsa_encrypt(PlainText, RsaPubKey)). + +-spec get_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> {ok, [{Proto :: integer(), Port :: integer()}]}. +get_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) -> + SrcPolicyIds = identity_policy_ets:get_policies(SrcIdentityId), + DstPolicyIds = identity_policy_ets:get_policies(DstIdentityId), + rule_ets:get_rules(SrcPolicyIds, DstPolicyIds). + +schedule_ping(Session = #session{heartbeat_sec = HeartbeatSec}) -> + Session#session{ping_timer = erlang:start_timer(heartbeat_ms(HeartbeatSec), self(), ping_ticker)}. + +ok_result(Session = #session{status = StateName}, Packets) -> + {ok, StateName, Session, Packets}. + +stop_result(Reason, Session = #session{status = StateName}, Packets) -> + {stop, Reason, StateName, Session, Packets}. + +ok_timeout_result(Session = #session{status = StateName}) -> + {ok, StateName, Session}. + +stop_timeout_result(Reason, Session = #session{status = StateName}) -> + {stop, Reason, StateName, Session}. + +heartbeat_ms(HeartbeatSec) when is_integer(HeartbeatSec), HeartbeatSec > 0 -> + HeartbeatSec * 1000; +heartbeat_ms(_) -> + ?PING_TICKER. diff --git a/apps/sdlan/src/sdlan_stun.erl b/src/sdlan_stun.erl similarity index 58% rename from apps/sdlan/src/sdlan_stun.erl rename to src/sdlan_stun.erl index 66e1449..bacc7f7 100644 --- a/apps/sdlan/src/sdlan_stun.erl +++ b/src/sdlan_stun.erl @@ -21,9 +21,11 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -define(SERVER, ?MODULE). +-define(FLOW_REPORT_INTERVAL, 60 * 1000). -record(state, { - socket + socket, + flow_counters = #{} }). %%%=================================================================== @@ -62,6 +64,7 @@ init([Port]) -> ], {ok, Socket} = gen_udp:open(Port, Opts), inet_udp:controlling_process(Socket, self()), + erlang:start_timer(?FLOW_REPORT_INTERVAL, self(), flow_report_ticker), logger:debug("[sdlan_stun] start at port: ~p", [Port]), {ok, #state{socket = Socket}}. @@ -85,10 +88,8 @@ handle_call(_Request, _From, State = #state{}) -> {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). - %% 当前node下的转发,基于进程间的通讯 -handle_cast({stun_relay, Ip, Port, Reply}, State = #state{socket = Sock}) -> - ok = gen_udp:send(Sock, Ip, Port, Reply), +handle_cast(_Request, State) -> {noreply, State}. %% @private @@ -97,70 +98,69 @@ handle_cast({stun_relay, Ip, Port, Reply}, State = #state{socket = Sock}) -> {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). - handle_info({udp, Sock, Ip, Port, <>}, State = #state{socket = Sock}) -> - #sdl_stun_request{cookie = Cookie, client_id = ClientId, network_id = NetworkId, mac = Mac, nat_type = NatType, v6_info = V6Info} = sdlan_pb:decode_msg(Body, sdl_stun_request), + StunRequest = catch sdlan_pb:decode_msg(Body, 'SDLStunRequest'), %% 告知网络当前的ip对应的nat的映射关系 - - case sdlan_network:get_pid(NetworkId) of - undefined -> - logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, not found", [NetworkId, ClientId]), - {noreply, State}; - NetworkPid when is_pid(NetworkPid) -> - sdlan_network:update_hole(NetworkPid, ClientId, Mac, {Ip, Port}, NatType, V6Info), - StunReply = sdlan_pb:encode_msg(#sdl_stun_reply{ - cookie = Cookie - }), - ok = gen_udp:send(Sock, Ip, Port, <>), - logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, hole: ~p", [NetworkId, ClientId, {Ip, Port}]), - {noreply, State} - end; + maybe + #'SDLStunRequest'{session_token = SessionToken, client_id = ClientId, network_id = NetworkId, mac = Mac, nat_type = NatType, v6_info = V6Info} ?= StunRequest, + {ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId), + sdlan_network:update_hole(NetworkPid, SessionToken, ClientId, Mac, {Ip, Port}, NatType, V6Info), + StunReply = sdlan_pb:encode_msg(#'SDLStunReply'{}), + ok = gen_udp:send(Sock, Ip, Port, <>), + logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, mac: ~p, hole: ~p, replied", [NetworkId, ClientId, sdlan_util:format_mac(Mac), {Ip, Port}]) + end, + {noreply, State}; %% 网络nat类型的探测机制, 需要借助其他服务一起才能实现 %% 辅助节点没有assist的配置,不支持attr = 2的探测 handle_info({udp, Sock, ClientIp, ClientPort, <>}, State = #state{socket = Sock}) -> - #sdl_stun_probe{cookie = Cookie, attr = Attr} = sdlan_pb:decode_msg(Body, sdl_stun_probe), - logger:debug("[sdlan_stun] get stun_probe request, att: ~p", [Attr]), - - ProbeReplyPkt = sdlan_pb:encode_msg(#sdl_stun_probe_reply { - cookie = Cookie, - port = ClientPort, - ip = int_ip(ClientIp) - }), - - case Attr of - ?STUN_ATTR_CHANGE_NONE -> - ok = gen_udp:send(Sock, ClientIp, ClientPort, <>); - ?STUN_ATTR_CHANGE_PORT -> - %% 切换端口和ip - sdlan_stun_peer_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt); - ?STUN_ATTR_CHANGE_PEER -> - %% 切换端口返回 - sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt) + StunProbe = catch sdlan_pb:decode_msg(Body, 'SDLStunProbe'), + maybe + #'SDLStunProbe'{cookie = Cookie, attr = Attr} ?= StunProbe, + logger:debug("[sdlan_stun] get stun_probe request, att: ~p", [Attr]), + ProbeReplyPkt = sdlan_pb:encode_msg(#'SDLStunProbeReply' { + cookie = Cookie, + port = ClientPort, + ip = int_ip(ClientIp) + }), + ProbeReply = <>, + case Attr of + ?STUN_ATTR_CHANGE_NONE -> + ok = gen_udp:send(Sock, ClientIp, ClientPort, ProbeReply); + ?STUN_ATTR_CHANGE_PORT -> + %% 切换端口和ip + sdlan_stun_peer_assist:stun_relay(ClientIp, ClientPort, ProbeReply); + ?STUN_ATTR_CHANGE_PEER -> + %% 切换端口返回 + sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReply) + end end, {noreply, State}; -%% 转发消息, 跨服务器的stun_reply的转发通过socket来转发 -handle_info({udp, Sock, _, _, <>}, State = #state{socket = Sock}) -> - logger:debug("[sdlan_stun] get stun_probe_replay request, reply: ~p", [Reply]), - gen_udp:send(Sock, {Ip0, Ip1, Ip2, Ip3}, Port, Reply), - {noreply, State}; - -handle_info({udp, _, _Ip, _Port, <>}, State = #state{socket = Sock}) -> - Data = #sdl_data{network_id = NetworkId, src_mac = SrcMac, dst_mac = DstMac, ttl = TTL} = sdlan_pb:decode_msg(Body, sdl_data), - - logger:debug("[sdlan_stun] stun data, src_mac: ~p, dst_mac: ~p", [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), - - %% 重新打包数据ttl需要减1 - case sdlan_network:get_pid(NetworkId) of - NetworkPid when is_pid(NetworkPid) -> - NData = sdlan_pb:encode_msg(Data#sdl_data{ttl = TTL - 1, is_p2p = false}), - sdlan_network:forward(NetworkPid, Sock, SrcMac, DstMac, <>); - _ -> - ok +handle_info({udp, _, _Ip, _Port, <>}, State = #state{socket = Sock, flow_counters = FlowCounters}) -> + Data = catch sdlan_pb:decode_msg(Body, 'SDLData'), + NFlowCounters = maybe + #'SDLData'{network_id = NetworkId, src_mac = SrcMac, dst_mac = DstMac, ttl = TTL} ?= Data, + logger:debug("[sdlan_stun] forward data, network_id: ~p", [NetworkId]), + %% 重新打包数据ttl需要减1 + NData = sdlan_pb:encode_msg(Data#'SDLData'{ttl = TTL - 1, is_p2p = false}), + case sdlan_network:forward_by_ets(NetworkId, Sock, SrcMac, DstMac, <>) of + {ok, ForwardBytes} -> + incr_flow_counter(NetworkId, ForwardBytes, FlowCounters); + {error, _Reason} -> + FlowCounters + end + else _ -> + FlowCounters end, + {noreply, State#state{flow_counters = NFlowCounters}}; - {noreply, State}; +handle_info({timeout, _, flow_report_ticker}, State = #state{flow_counters = FlowCounters}) -> + erlang:start_timer(?FLOW_REPORT_INTERVAL, self(), flow_report_ticker), + maps:foreach(fun(NetworkId, ForwardBytes) -> + catch sdlan_api:network_forward_report(NetworkId, ForwardBytes) + end, FlowCounters), + {noreply, State#state{flow_counters = #{}}}; handle_info(Info, State) -> logger:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]), @@ -191,4 +191,8 @@ code_change(_OldVsn, State = #state{}, _Extra) -> -spec int_ip(tuple()) -> integer(). int_ip({Ip0, Ip1, Ip2, Ip3}) -> <> = <>, - Ip. \ No newline at end of file + Ip. + +-spec incr_flow_counter(NetworkId :: integer(), ForwardBytes :: integer(), Counters :: map()) -> map(). +incr_flow_counter(NetworkId, ForwardBytes, Counters) when is_integer(NetworkId), is_integer(ForwardBytes), is_map(Counters) -> + maps:update_with(NetworkId, fun(V) -> V + ForwardBytes end, ForwardBytes, Counters). diff --git a/apps/sdlan/src/sdlan_stun_peer_assist.erl b/src/sdlan_stun_peer_assist.erl similarity index 97% rename from apps/sdlan/src/sdlan_stun_peer_assist.erl rename to src/sdlan_stun_peer_assist.erl index d7f8327..053a963 100644 --- a/apps/sdlan/src/sdlan_stun_peer_assist.erl +++ b/src/sdlan_stun_peer_assist.erl @@ -8,6 +8,7 @@ %%%------------------------------------------------------------------- -module(sdlan_stun_peer_assist). -author("anlicheng"). +-include("sdlan.hrl"). -behaviour(gen_server). @@ -30,7 +31,7 @@ %%% API %%%=================================================================== --spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> no_return(). +-spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> ok. stun_relay(Ip, Port, Reply) when is_integer(Port), is_binary(Reply) -> gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}). @@ -58,7 +59,6 @@ init([]) -> {ok, Socket} = gen_udp:open(0, Opts), inet_udp:controlling_process(Socket, self()), logger:debug("[sdlan_stun_peer_assist] started"), - {ok, #state{socket = Socket, assist_ip = AssistIp, assist_port = AssistPort}}. %% @private @@ -81,7 +81,7 @@ handle_call(_Request, _From, State = #state{}) -> {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). handle_cast({stun_relay, _Ip = {Ip0, Ip1, Ip2, Ip3}, Port, Reply}, State = #state{socket = Sock, assist_ip = AssistIp, assist_port = AssistPort}) -> - Packet = <>, + Packet = <>, ok = gen_udp:send(Sock, AssistIp, AssistPort, Packet), {noreply, State}. diff --git a/apps/sdlan/src/sdlan_stun_port_assist.erl b/src/sdlan_stun_port_assist.erl similarity index 93% rename from apps/sdlan/src/sdlan_stun_port_assist.erl rename to src/sdlan_stun_port_assist.erl index f31921c..09a3793 100644 --- a/apps/sdlan/src/sdlan_stun_port_assist.erl +++ b/src/sdlan_stun_port_assist.erl @@ -8,6 +8,7 @@ %%%------------------------------------------------------------------- -module(sdlan_stun_port_assist). -author("anlicheng"). +-include("sdlan.hrl"). -behaviour(gen_server). @@ -28,7 +29,7 @@ %%% API %%%=================================================================== --spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> no_return(). +-spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> ok. stun_relay(Ip, Port, Reply) when is_integer(Port), is_binary(Reply) -> gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}). @@ -87,6 +88,10 @@ handle_cast({stun_relay, Ip, Port, Reply}, State = #state{socket = Sock}) -> {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). +handle_info({udp, Sock, _Ip, _Port, <>}, + State = #state{socket = Sock}) -> + ok = gen_udp:send(Sock, {Ip0, Ip1, Ip2, Ip3}, ClientPort, Reply), + {noreply, State}; handle_info(_Info, State = #state{}) -> {noreply, State}. diff --git a/apps/sdlan/src/sdlan_stun_sup.erl b/src/sdlan_stun_sup.erl similarity index 89% rename from apps/sdlan/src/sdlan_stun_sup.erl rename to src/sdlan_stun_sup.erl index 06ceae7..3df2fde 100644 --- a/apps/sdlan/src/sdlan_stun_sup.erl +++ b/src/sdlan_stun_sup.erl @@ -12,6 +12,7 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). @@ -23,7 +24,9 @@ start_link() -> %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional -%% modules => modules()} % optional +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, Specs = [ @@ -62,4 +65,4 @@ stun_acceptors() -> type => worker, modules => ['sdlan_stun'] } - end, lists:seq(1, AcceptorNums)). \ No newline at end of file + end, lists:seq(1, AcceptorNums)). diff --git a/apps/sdlan/src/sdlan_sup.erl b/src/sdlan_sup.erl similarity index 55% rename from apps/sdlan/src/sdlan_sup.erl rename to src/sdlan_sup.erl index 8c4b3b9..e61f5d4 100644 --- a/apps/sdlan/src/sdlan_sup.erl +++ b/src/sdlan_sup.erl @@ -13,6 +13,7 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). @@ -24,18 +25,29 @@ start_link() -> %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional -%% modules => modules()} % optional +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, Specs = [ + %% 暂时注释掉dns的逻辑 #{ - id => dns_proxy_sup, - start => {dns_proxy_sup, start_link, []}, + id => dns_server_sup, + start => {dns_server_sup, start_link, []}, restart => permanent, shutdown => 2000, type => supervisor, - modules => ['dns_proxy_sup'] + modules => ['dns_server_sup'] + }, + #{ + id => ipv6_assist_server_sup, + start => {ipv6_assist_server_sup, start_link, []}, + restart => permanent, + shutdown => 2000, + type => supervisor, + modules => ['ipv6_assist_server_sup'] }, #{ id => sdlan_network_coordinator, @@ -61,6 +73,42 @@ init([]) -> shutdown => 2000, type => supervisor, modules => ['sdlan_stun_sup'] + }, + + #{ + id => sdlan_quic_channel_sup, + start => {sdlan_quic_channel_sup, start_link, []}, + restart => permanent, + shutdown => 2000, + type => supervisor, + modules => ['sdlan_quic_channel_sup'] + }, + + #{ + id => sdlan_quic_server, + start => {sdlan_quic_server, start_link, []}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['sdlan_quic_server'] + }, + + #{ + id => sdlan_sync_mysql, + start => {sdlan_sync_mysql, start_link, []}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['sdlan_sync_mysql'] + }, + + #{ + id => maxwell_redis_server, + start => {maxwell_redis_server, start_link, [16379]}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['maxwell_redis_server'] } ], @@ -72,4 +120,4 @@ pools() -> {ok, Pools} = application:get_env(sdlan, pools), lists:map(fun({Name, PoolArgs, WorkerArgs}) -> poolboy:child_spec(Name, [{name, {local, Name}}|PoolArgs], WorkerArgs) - end, Pools). \ No newline at end of file + end, Pools). diff --git a/src/sdlan_sync_mysql.erl b/src/sdlan_sync_mysql.erl new file mode 100644 index 0000000..d5072ff --- /dev/null +++ b/src/sdlan_sync_mysql.erl @@ -0,0 +1,117 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 11. 2月 2026 23:00 +%%%------------------------------------------------------------------- +-module(sdlan_sync_mysql). +-author("anlicheng"). +-include("policy.hrl"). + +-behaviour(gen_statem). + +%% 心跳包监测机制 +-define(PING_TICKER, 15000). + +%% 注册失败的的错误码 + +%% 网络错误 +-define(NAK_NETWORK_FAULT, 4). +%% 内部错误 +-define(NAK_INTERNAL_FAULT, 5). + +%% API +-export([start_link/0]). + +%% gen_statem callbacks +-export([init/1, handle_event/4, terminate/3, code_change/4, callback_mode/0]). + +-record(state, { + +}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +%% @doc Creates a gen_statem process which calls Module:init/1 to +%% initialize. To ensure a synchronized start-up procedure, this +%% function does not return until Module:init/1 has returned. +-spec start_link() -> gen_statem:start_ret(). +start_link() -> + gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []). + +%%%=================================================================== +%%% gen_statem callbacks +%%%=================================================================== + +%% @private +%% @doc Whenever a gen_statem is started using gen_statem:start/[3,4] or +%% gen_statem:start_link/[3,4], this function is called by the new +%% process to initialize. +-spec init(Args :: term()) -> gen_statem:init_result(atom(), #state{}). +init([]) -> + {ok, initializing, #state{}, [{next_event, internal, do_sync}]}. + +%% @private +%% @doc This function is called by a gen_statem when it needs to find out +%% the callback mode of the callback module. +-spec callback_mode() -> gen_statem:callback_mode_result(). +callback_mode() -> + handle_event_function. + +%% @private +%% @doc If callback_mode is handle_event_function, then whenever a +%% gen_statem receives an event from call/2, cast/2, or as a normal +%% process message, this function is called. + +-spec handle_event(EventType :: gen_statem:event_type(), EventContent :: term(), + StateName :: atom(), State :: #state{}) -> gen_statem:event_handler_result(atom(), #state{}). +handle_event(internal, do_sync, initializing, State=#state{}) -> + sync_identity_policy(), + sync_rule(), + {next_state, initialized, State}. + +%% @private +%% @doc This function is called by a gen_statem when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any +%% necessary cleaning up. When it returns, the gen_statem terminates with +%% Reason. The return value is ignored. +-spec terminate(Reason :: term(), StateName :: atom(), State :: #state{}) -> ok. +terminate(Reason, _StateName, _State) -> + logger:debug("[sdlan_sync_mysql] terminate with reason: ~p", [Reason]), + ok. + +%% @private +%% @doc Convert process state when code is changed +-spec code_change(OldVsn :: term(), StateName :: atom(), State :: #state{}, Extra :: term()) -> + {ok, atom(), #state{}}. +code_change(_OldVsn, StateName, State = #state{}, _Extra) -> + {ok, StateName, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +sync_identity_policy() -> + {ok, Rows} = mysql_pool:get_all(mysql_sdlan, <<"select * from identity_policy">>), + lists:map(fun(R) -> identity_policy_ets:insert(R) end, Rows). + +sync_rule() -> + sync_rule0(0). +sync_rule0(RuleIdOffset) -> + {ok, Rows} = mysql_pool:get_all(mysql_sdlan, <<"select * from rule where rule_id > ? order by rule_id asc limit 5000">>, [RuleIdOffset]), + logger:debug("rule rows: ~p", [Rows]), + case length(Rows) > 0 of + true -> + RuleIds = lists:map(fun(R = #{<<"rule_id">> := RuleId}) -> + rule_ets:insert(R), + RuleId + end, Rows), + LastRuleOffset = lists:max(RuleIds), + sync_rule0(LastRuleOffset); + false -> + ok + end. diff --git a/src/sdlan_util.erl b/src/sdlan_util.erl new file mode 100644 index 0000000..d49397f --- /dev/null +++ b/src/sdlan_util.erl @@ -0,0 +1,183 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2024, +%%% @doc +%%% +%%% @end +%%% Created : 11. 3月 2024 11:10 +%%%------------------------------------------------------------------- +-module(sdlan_util). +-author("anlicheng"). + +%% API +-export([rand_byte/1, md5/1, format_mac/1, assert_call/2, mac_str_to_bin/1]). +-export([json_data/1, json_error/2]). +-export([is_broadcast_mac/1, is_multicast_mac/1]). +-export([ipv4_to_int/1, int_to_ipv4/1, ips/2, format_ip/1]). +-export([ipv6_to_bytes/1, ipv6_bytes_to_binary/1, ipv6_assist_info/0]). +-export([hmac/2, term_to_binary/1]). +-export([certificate_config/0]). + +-spec format_mac(Mac :: binary()) -> binary(). +format_mac(Mac) when is_binary(Mac) -> + Hex = fun + (N) when N < 10 -> + $0 + N; + (N) -> + $a + (N - 10) + end, + Y = [[Hex(X0), Hex(X1)] || <> <= Mac], + list_to_binary(lists:flatten(lists:join(":", Y))). + +-spec mac_str_to_bin(MacBin :: binary()) -> binary(). +mac_str_to_bin(MacBin) when is_binary(MacBin) -> + % 过滤掉 : 和 -,只保留十六进制字符 + HexBin = binary:replace(MacBin, <<":">>, <<>>, [global]), + HexBin2 = binary:replace(HexBin, <<"-">>, <<>>, [global]), + % 解码为 6 字节 MAC 二进制 + binary:decode_hex(HexBin2). + +%% 生成随机字节 +-spec rand_byte(Num :: pos_integer()) -> binary(). +rand_byte(Num) when is_integer(Num), Num > 0 -> + crypto:strong_rand_bytes(Num). + +%% md5哈希算法 +-spec md5(string() | binary()) -> string(). +md5(Str) when is_binary(Str) -> + md5(binary_to_list(Str)); +md5(Str) when is_list(Str) -> + Hash = binary_to_list(erlang:md5(Str)), + lists:flatten([hex(I) || I <- Hash]). + +hex(I) when I > 16#f -> + [hex0((I band 16#f0) bsr 4), hex0(I band 16#0f)]; +hex(I) -> + [$0, hex0(I)]. +hex0(10) -> $a; +hex0(11) -> $b; +hex0(12) -> $c; +hex0(13) -> $d; +hex0(14) -> $e; +hex0(15) -> $f; +hex0(I) -> $0 + I. + +-spec json_data(Data :: term()) -> iodata(). +json_data(Data) -> + json:encode(#{<<"result">> => Data}). + +-spec json_error(ErrCode :: integer(), ErrMessage :: binary()) -> iodata(). +json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) -> + json:encode(#{<<"error">> => #{<<"code">> => ErrCode, <<"message">> => ErrMessage}}). + +-spec assert_call(Condition :: boolean(), F :: fun(() -> T)) -> T | ok. +assert_call(true, F) -> + F(); +assert_call(false, _) -> + ok. + +-spec is_broadcast_mac(Mac :: binary()) -> boolean(). +is_broadcast_mac(Mac) when is_binary(Mac) -> + Mac =:= <<16#FF,16#FF,16#FF,16#FF,16#FF,16#FF>>. + +-spec is_multicast_mac(Mac :: binary()) -> boolean(). +is_multicast_mac(Mac) when is_binary(Mac) -> + binary:part(Mac, 0, 3) =:= <<16#01,16#00,16#5E>>. + + +-spec format_ip(Ip :: term()) -> term(). +format_ip(Ip) when is_integer(Ip) -> + int_to_ipv4(Ip); +format_ip(Ip) -> + Ip. + +-spec ipv4_to_int(Ip :: integer() | binary() | inet:ip4_address()) -> integer(). +ipv4_to_int(Ip) when is_integer(Ip) -> + Ip; +ipv4_to_int({Ip0, Ip1, Ip2, Ip3}) -> + <> = <>, + Ip; +ipv4_to_int(Ip) when is_binary(Ip) -> + Parts0 = binary:split(Ip, <<".">>, [global]), + Parts = lists:map(fun binary_to_integer/1, Parts0), + <> = iolist_to_binary(Parts), + IpInt. + +-spec int_to_ipv4(Ip :: integer()) -> binary(). +int_to_ipv4(Ip) when is_integer(Ip) -> + <> = <>, + <<(integer_to_binary(Ip0))/binary, $., (integer_to_binary(Ip1))/binary, $., (integer_to_binary(Ip2))/binary, $., (integer_to_binary(Ip3))/binary>>. + +-spec ips(NetAddr :: binary(), MaskLen :: integer()) -> [Ip :: integer()]. +ips(NetAddr, MaskLen) when is_binary(NetAddr), is_integer(MaskLen) -> + Mask = 16#FFFFFFFF bsr MaskLen, + Net0 = ipv4_to_int(NetAddr), + %% 防止网络地址给得不对,比如: "192.168.1.101", + L = 32 - MaskLen, + Net = (Net0 bsr L) bsl L, + lists:map(fun(V) -> Net + V end, lists:seq(1, Mask - 1)). + +-spec ipv6_to_bytes(Address :: binary() | string() | inet:ip6_address()) -> binary(). +ipv6_to_bytes(Address) when is_binary(Address) -> + ipv6_to_bytes(binary_to_list(Address)); +ipv6_to_bytes({A, B, C, D, E, F, G, H}) -> + <>; +ipv6_to_bytes(Address) when is_list(Address) -> + case inet:parse_ipv6strict_address(string:trim(Address)) of + {ok, Ip6Address} -> + ipv6_to_bytes(Ip6Address); + {error, _} -> + <<"">> + end; +ipv6_to_bytes(_) -> + <<"">>. + +-spec ipv6_bytes_to_binary(Bytes :: binary()) -> Bin :: binary(). +ipv6_bytes_to_binary(<>) -> + Segments = [integer_to_list(X, 16) || X <- [A, B, C, D, E, F, G, H]], + % 填充每个段以确保是4位 + Padded = [string:pad(S, 4, leading, $0) || S <- Segments], + % 合并成IPv6地址格式,这里没有处理最简化形式的缩写 + iolist_to_binary(lists:flatten(string:join(Padded, ":"))); +ipv6_bytes_to_binary(_) -> + <<"">>. + +-spec ipv6_assist_info() -> undefined | {ok, {binary(), integer()}}. +ipv6_assist_info() -> + case application:get_env(sdlan, ipv6_assist) of + {ok, Props} -> + Port = proplists:get_value(port, Props, 0), + GlobalAddr6 = proplists:get_value(global_addr6, Props, <<"">>), + case {Port, ipv6_to_bytes(GlobalAddr6)} of + {Port0, V6Bytes = <<_:128>>} when is_integer(Port0), Port0 > 0 -> + {ok, {V6Bytes, Port0}}; + _ -> + undefined + end; + _ -> + undefined + end. + +-spec hmac(Key :: binary(), Data :: binary()) -> string(). +hmac(Key, Data) when is_binary(Key), is_binary(Data) -> + Digest = crypto:mac(hmac, md5, Key, Data), + %% 转成十六进制小写字符串,和 PHP hash_hmac 一致 + lists:flatten([io_lib:format("~2.16.0b", [B]) || B <- binary:bin_to_list(Digest)]). + +-spec term_to_binary(Term :: term()) -> binary(). +term_to_binary(Term) -> + iolist_to_binary(io_lib:format("~p", [Term])). + +-spec certificate_config() -> {CertFile :: string(), KeyFile :: string()}. +certificate_config() -> + {ok, Props} = application:get_env(sdlan, certificate), + CertFile = proplists:get_value(certfile, Props), + KeyFile = proplists:get_value(keyfile, Props), + + %% 获取环境变量 + case os:getenv("QUIC_CERT_PATH") of + false -> + {CertFile, KeyFile}; + Path -> + {Path ++ "/" ++ CertFile, Path ++ "/" ++ KeyFile} + end. \ No newline at end of file diff --git a/src/ssl/sdlan_ssl_server.erl b/src/ssl/sdlan_ssl_server.erl new file mode 100644 index 0000000..568cb65 --- /dev/null +++ b/src/ssl/sdlan_ssl_server.erl @@ -0,0 +1,52 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 03. 5月 2026 13:31 +%%%------------------------------------------------------------------- +-module(sdlan_ssl_server). +-author("anlicheng"). + +%% API +-export([start/0]). + +%% 启动ssl服务 +-spec start() -> ok. +start() -> + {ok, Props} = application:get_env(sdlan, ssl_server), + Acceptors = proplists:get_value(acceptors, Props, 50), + MaxConnections = proplists:get_value(max_connections, Props, 10240), + Backlog = proplists:get_value(backlog, Props, 1024), + Port = proplists:get_value(port, Props), + Limits = proplists:get_value(limits, Props, []), + + %% 证书配置 + {CertFile, KeyFile} = sdlan_util:certificate_config(), + + TransOpts = #{ + max_connections => MaxConnections, + num_acceptors => Acceptors, + shutdown => 2000, + socket_opts => [ + binary, + {active, false}, + {nodelay, true}, + {backlog, Backlog}, + {port, Port}, + {send_timeout, 30000}, + {send_timeout_close, true}, + {certfile, CertFile}, + {keyfile, KeyFile}, + {verify, verify_none}, + {alpn_preferred_protocols, [<<"punchnet/1.0">>]}, + {versions, ['tlsv1.3', 'tlsv1.2']}, + {secure_renegotiate, true}, + {reuse_sessions, true}, + {honor_cipher_order, true}, + {client_renegotiation, false} + ] + }, + {ok, Pid} = ranch:start_listener(ssl_server, ranch_ssl, TransOpts, sdlan_ssl_transport, Limits), + logger:debug("[sdlan_ssl_server] the ssl server start at: ~p, pid is: ~p", [Port, Pid]). \ No newline at end of file diff --git a/src/ssl/sdlan_ssl_transport.erl b/src/ssl/sdlan_ssl_transport.erl new file mode 100644 index 0000000..90f425b --- /dev/null +++ b/src/ssl/sdlan_ssl_transport.erl @@ -0,0 +1,186 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% SSL transport for sdlan sessions. +%%% @end +%%%------------------------------------------------------------------- +-module(sdlan_ssl_transport). +-author("anlicheng"). +-include("sdlan.hrl"). +-include("sdlan_pb.hrl"). + +-behaviour(gen_statem). +-behaviour(ranch_protocol). + +%% Ranch protocol callback +-export([start_link/4]). + +%% gen_statem callbacks +-export([init/1, handle_event/4, terminate/3, code_change/4, callback_mode/0]). + +-record(state, { + ref :: ranch:ref(), + socket :: undefined | ssl:sslsocket(), + transport :: module(), + + max_packet_size = 16384, + heartbeat_sec = 15, + + session :: sdlan_session:session(), + + close_reason = undefined +}). + +%%%=================================================================== +%%% Ranch protocol callback +%%%=================================================================== + +-spec start_link(Ref :: ranch:ref(), Socket :: inet:socket(), Transport :: module(), + Limits :: proplists:proplist()) -> gen_statem:start_ret(). +start_link(Ref, Socket, Transport, Limits) -> + gen_statem:start_link(?MODULE, [Ref, Socket, Transport, Limits], []). + +%%%=================================================================== +%%% gen_statem callbacks +%%%=================================================================== + +-spec init(Args :: term()) -> gen_statem:init_result(atom(), #state{}). +init([Ref, Socket, Transport, Limits]) -> + MaxPacketSize = proplists:get_value(max_packet_size, Limits, 16384), + HeartbeatSec = proplists:get_value(heartbeat_sec, Limits, 15), + Session = sdlan_session:new(HeartbeatSec, ?MODULE), + {ok, handshaking, #state{ + ref = Ref, + socket = Socket, + transport = Transport, + max_packet_size = MaxPacketSize, + heartbeat_sec = HeartbeatSec, + session = Session + }}. + +-spec callback_mode() -> gen_statem:callback_mode_result(). +callback_mode() -> + handle_event_function. + +-spec handle_event(EventType :: gen_statem:event_type(), EventContent :: term(), + StateName :: atom(), State :: #state{}) -> gen_statem:event_handler_result(atom(), #state{}). +handle_event(info, {handshake, Ref, Transport, Socket, Timeout}, handshaking, + State = #state{ref = Ref, transport = Transport, max_packet_size = MaxPacketSize, heartbeat_sec = HeartbeatSec}) -> + case Transport:handshake(Socket, [], Timeout) of + {ok, SslSocket} -> + ok = Transport:setopts(SslSocket, [{mode, binary}, {packet, 2}, {active, true}]), + ssl_send(Transport, SslSocket, sdlan_session:welcome_packet(MaxPacketSize, HeartbeatSec)), + logger:debug("[sdlan_ssl_transport] ssl handshake ok, send welcome"), + {next_state, initialized, State#state{socket = SslSocket}}; + {error, Reason} -> + {stop, {ssl_handshake_failed, Reason}, State} + end; + +handle_event(info, {ssl, Socket, Frame}, _StateName, + State = #state{socket = Socket, transport = Transport, session = Session}) when is_binary(Frame) -> + case sdlan_session:handle_frame(Frame, Session) of + {ok, NStateName, NSession, Packets} -> + ssl_send(Transport, Socket, Packets), + {next_state, NStateName, State#state{session = NSession}}; + {stop, Reason, _NStateName, NSession, Packets} -> + ssl_send(Transport, Socket, Packets), + {stop, Reason, State#state{session = NSession}} + end; + +handle_event(info, {ssl_closed, Socket}, _StateName, State = #state{socket = Socket}) -> + expected_stop(socket_closed, State); + +handle_event(info, {ssl_error, Socket, Reason}, _StateName, State = #state{socket = Socket}) -> + expected_stop({socket_error, Reason}, State); + +handle_event(info, {timeout, TimerRef, ping_ticker}, _StateName, State = #state{session = Session}) -> + case sdlan_session:handle_timeout(TimerRef, Session) of + {ok, NStateName, NSession} -> + {next_state, NStateName, State#state{session = NSession}}; + {stop, Reason, _NStateName, NSession} -> + expected_stop(Reason, State#state{session = NSession}) + end; + +%% 发送事件信息 +handle_event(cast, {send_event, Event}, _StateName, State = #state{socket = Socket, transport = Transport, session = Session}) -> + case sdlan_session:send_event(Event, Session) of + {ok, NStateName, NSession, Packets} -> + ssl_send(Transport, Socket, Packets), + {next_state, NStateName, State#state{session = NSession}}; + {error, not_registered} -> + keep_state_and_data + end; + +%% 发送命令信息 +handle_event(cast, {command, Ref, ReceiverPid, SubCommand}, _StateName, State = #state{socket = Socket, transport = Transport, session = Session}) -> + case sdlan_session:command(Ref, ReceiverPid, SubCommand, Session) of + {ok, NStateName, NSession, Packets} -> + ssl_send(Transport, Socket, Packets), + {next_state, NStateName, State#state{session = NSession}}; + {error, not_registered} -> + keep_state_and_data + end; + +handle_event({call, From}, debug_info, StateName, State) -> + {keep_state, State, [{reply, From, debug_info(StateName, State)}]}; + +handle_event(EventType, Info, StateName, State) -> + logger:notice("[sdlan_ssl_transport] state: ~p, state_name: ~p, event_type: ~p, info: ~p", [State, StateName, EventType, Info]), + keep_state_and_data. + +-spec terminate(Reason :: term(), StateName :: atom(), State :: #state{}) -> ok. +terminate(Reason, _StateName, #state{socket = Socket, transport = Transport, session = Session, close_reason = CloseReason}) -> + Socket =/= undefined andalso catch Transport:close(Socket), + logger:notice("[sdlan_ssl_transport] terminate closed with reason: ~p, close_reason: ~p", [Reason, CloseReason]), + sdlan_session:close(Session), + ok. + +-spec code_change(OldVsn :: term(), StateName :: atom(), State :: #state{}, Extra :: term()) -> + {ok, atom(), #state{}}. +code_change(_OldVsn, StateName, State = #state{}, _Extra) -> + {ok, StateName, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +ssl_send(_Transport, _Socket, []) -> + ok; +ssl_send(Transport, Socket, Data) -> + Len = iolist_size(Data), + true = Len =< 65535, + case Transport:send(Socket, Data) of + ok -> + incr_counter(ssl_frames_sent, 1), + incr_counter(ssl_bytes_sent, Len + 2), + ok; + {error, Reason} -> + exit({ssl_send_failed, Reason}) + end. + +expected_stop(Reason, State) -> + logger:notice("[sdlan_ssl_transport] expected close: ~p", [Reason]), + {stop, normal, State#state{close_reason = Reason}}. + +debug_info(StateName, #state{session = Session, heartbeat_sec = HeartbeatSec}) -> + ProcInfo = maps:from_list(process_info(self(), [message_queue_len, memory, reductions])), + SessionInfo = sdlan_session:debug_info(Session), + maps:merge(SessionInfo, ProcInfo#{ + state => StateName, + session => SessionInfo, + frames_sent => get_counter(ssl_frames_sent), + bytes_sent => get_counter(ssl_bytes_sent), + heartbeat_sec => HeartbeatSec + }). + +incr_counter(Key, Inc) -> + erlang:put(Key, get_counter(Key) + Inc). + +get_counter(Key) -> + case erlang:get(Key) of + undefined -> + 0; + Value when is_integer(Value) -> + Value + end. diff --git a/src/test/test_ipv6_udp.erl b/src/test/test_ipv6_udp.erl new file mode 100644 index 0000000..e059584 --- /dev/null +++ b/src/test/test_ipv6_udp.erl @@ -0,0 +1,27 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2026, +%%% @doc +%%% +%%% @end +%%% Created : 16. 4月 2026 20:53 +%%%------------------------------------------------------------------- +-module(test_ipv6_udp). +-author("anlicheng"). + +%% API +-export([test/0]). + +-spec test() -> ok. +test() -> + Opts = [ + binary, + inet6, + {reuseaddr, true}, + {reuseport, true}, + {active, true}, + {recbuf, 5 * 1024 * 1024}, + {sndbuf, 5 * 1024 * 1024} + ], + {ok, Socket} = gen_udp:open(0, Opts), + ok = gen_udp:send(Socket, "2408:4005:318:4900:164a:b5c6:9023:ca8d", 1367, <<"hello world">>). diff --git a/swift_pb.sh b/swift_pb.sh new file mode 100755 index 0000000..ab3bff3 --- /dev/null +++ b/swift_pb.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +rm -rf tmp +mkdir tmp + +cp proto/sdlan.proto tmp/sdlan_pb.proto + +cd tmp + +protoc sdlan_pb.proto --swift_out=. +cp sdlan_pb.pb.swift SDLMessage.pb.swift +cp SDLMessage.pb.swift /usr/local/code/macos/punchnet/Tun/Punchnet/Protobuf/ diff --git a/tun.proto b/tun.proto new file mode 100644 index 0000000..a76cb37 --- /dev/null +++ b/tun.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +// 定义App发送给NE的事件 +message AppRequest { + + message ChangeExitNodeRequest { + // 空字符串表示清除出口节点 + string ip = 1; + } + + oneof command { + ChangeExitNodeRequest change_exit_node = 1; + } +} + +message TunnelResponse { + int32 code = 1; + string message = 2; +} + + +// Tunnel产生的事件 + +message TunnelEvent { + string id = 1; + uint64 timestamp_ms = 2; + int32 code = 3; + string message = 4; +} \ No newline at end of file