diff --git a/apps/sdlan/src/sdlan_network.erl b/apps/sdlan/src/sdlan_network.erl index f4873de..c814e34 100644 --- a/apps/sdlan/src/sdlan_network.erl +++ b/apps/sdlan/src/sdlan_network.erl @@ -399,21 +399,46 @@ handle_cast({policy_request, Sock, {ClientIp, ClientPort}, #sdl_policy_request{c %% 分片逻辑,index必须从0开始 maybe {ok, #endpoint{client_id = ClientId, session_token = ST}} ?= maps:find(Mac, Endpoints), - PolicyResponse = sdlan_pb:encode_msg(#sdl_policy_response { - network_id = NetworkId, - src_identity_id = SrcIdentityId, - dst_identity_id = DstIdentityId, - version = Version, - total_num = 1, - index = 0, - rules = <<1, 80:16, 2, 9090:16>> - }), - PolicyResponsePkt = <>, - logger:debug("[sdlan_network] will send policy response: ~p", [PolicyResponsePkt]), - gen_udp:send(Sock, ClientIp, ClientPort, PolicyResponsePkt) + Bin = <<1, 80:16, 2, 9090:16>>, + RulesBin = iolist_to_binary(lists:map(fun(_Id) -> Bin end, lists:seq(1, 1000))), + case byte_size(RulesBin) > 1200 of + true -> + %% 分组 + Groups = chunk_rules(RulesBin, 1200), + logger:debug("[sdlan_network] policy_response, groups: ~p", [Groups]), + TotalNum = length(Groups), + Fragments = lists:zip(lists:seq(0, TotalNum - 1), Groups), + lists:foreach(fun({Idx, ChunkRulesBin}) -> + FragmentPolicyResponse = sdlan_pb:encode_msg(#sdl_policy_response { + network_id = NetworkId, + src_identity_id = SrcIdentityId, + dst_identity_id = DstIdentityId, + version = Version, + total_num = TotalNum, + index = Idx, + rules = ChunkRulesBin + }), + FragmentPolicyResponsePkt = <>, + logger:debug("[sdlan_network] will send policy response: ~p", [FragmentPolicyResponsePkt]), + gen_udp:send(Sock, ClientIp, ClientPort, FragmentPolicyResponsePkt) + end, Fragments); + false -> + %% 小于1200字节不分组 + PolicyResponse = sdlan_pb:encode_msg(#sdl_policy_response { + network_id = NetworkId, + src_identity_id = SrcIdentityId, + dst_identity_id = DstIdentityId, + version = Version, + total_num = 1, + index = 0, + rules = RulesBin + }), + PolicyResponsePkt = <>, + logger:debug("[sdlan_network] will send policy response: ~p", [PolicyResponsePkt]), + gen_udp:send(Sock, ClientIp, ClientPort, PolicyResponsePkt) + end end, - {noreply, State}. %% @private @@ -595,4 +620,12 @@ endpoint_peers(ExcludeMacs, Endpoints) when is_list(ExcludeMacs), is_map(Endpoin -spec gen_session_token() -> binary(). gen_session_token() -> Bytes = crypto:strong_rand_bytes(32), - base64:encode(Bytes). \ No newline at end of file + base64:encode(Bytes). + +%% 对rules进行分组 +chunk_rules(<<>>, _) -> + []; +chunk_rules(Bin, Size) when byte_size(Bin) =< Size -> + [Bin]; +chunk_rules(<>, Size) -> + [Head | chunk_rules(Tail, Size)]. \ No newline at end of file