简化代码逻辑
This commit is contained in:
parent
ef8ded9f35
commit
a597ecbf2e
@ -4,7 +4,7 @@
|
||||
-module(arp_packet).
|
||||
|
||||
-export([parse/1, marshal/1, is_broadcast_mac/1, arp_request/3, arp_response/3]).
|
||||
-export([opcode/1]).
|
||||
-export([opcode/1, target_ip/1]).
|
||||
|
||||
-define(ETHERNET, 16#0001).
|
||||
-define(IPV4, 16#0800).
|
||||
@ -26,6 +26,20 @@
|
||||
target_ip
|
||||
}).
|
||||
|
||||
-type arp_packet() :: #arp_packet{
|
||||
hardware_type :: integer(),
|
||||
protocol_type :: integer(),
|
||||
hardware_size :: integer(),
|
||||
protocol_size :: integer(),
|
||||
opcode :: atom() | integer(),
|
||||
sender_mac :: binary(),
|
||||
sender_ip :: integer(),
|
||||
target_mac :: binary(),
|
||||
target_ip :: integer()
|
||||
}.
|
||||
|
||||
-export_type([arp_packet/0]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Parsing
|
||||
%%--------------------------------------------------------------------
|
||||
@ -70,6 +84,10 @@ parse(Bin) when is_binary(Bin) ->
|
||||
opcode(#arp_packet{opcode = Opcode}) ->
|
||||
Opcode.
|
||||
|
||||
-spec target_ip(Arp_packet :: #arp_packet{}) -> TargetIp :: integer().
|
||||
target_ip(#arp_packet{target_ip = TargetIp}) ->
|
||||
TargetIp.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Marshal
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
%%% Created : 27. 3月 2024 15:13
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(sdlan_network).
|
||||
-feature(maybe_expr, enable).
|
||||
|
||||
-author("anlicheng").
|
||||
-include("sdlan.hrl").
|
||||
-include("sdlan_pb.hrl").
|
||||
@ -340,46 +342,34 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
||||
case sdlan_util:is_broadcast_mac(DstMac) orelse sdlan_util:is_multicast_mac(DstMac) of
|
||||
true ->
|
||||
%% 解析Packet是不是arp请求
|
||||
case layer_packet:parse(Packet) of
|
||||
{ok, LayerPacket} ->
|
||||
case layer_packet:packet_type(LayerPacket) of
|
||||
arp ->
|
||||
case arp_packet:parse(layer_packet:payload(LayerPacket)) of
|
||||
{ok, ArpPacket} ->
|
||||
case maybe_arp_request(Packet) of
|
||||
{ok, ArpRequestPkt} ->
|
||||
TargetIp = arp_packet:target_ip(ArpRequestPkt),
|
||||
%% 通过ip查找到对应的Endpoint
|
||||
|
||||
case arp_packet:opcode(ArpPacket) of
|
||||
request ->
|
||||
%% TODO
|
||||
Mac = <<>>,
|
||||
Ip = 12,
|
||||
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpPacket, Mac, Ip)),
|
||||
TargetMac = <<>>,
|
||||
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpRequestPkt, TargetMac, TargetIp)),
|
||||
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, UsedMap),
|
||||
gen_udp:send(Sock, NatIp, NatPort, ArpResponse);
|
||||
|
||||
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, UsedMap),
|
||||
gen_udp:send(Sock, NatIp, NatPort, ArpResponse)
|
||||
end;
|
||||
error ->
|
||||
PacketBytes = byte_size(Packet),
|
||||
%% 消息广播
|
||||
maps:foreach(fun(Mac, #endpoint{hole = Hole}) ->
|
||||
case {Mac =/= SrcMac, Hole} of
|
||||
{true, #hole{peer = {NatIp, NatPort}}} ->
|
||||
gen_udp:send(Sock, NatIp, NatPort, Packet);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end, UsedMap),
|
||||
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end
|
||||
end,
|
||||
%% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat
|
||||
lager: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)]),
|
||||
|
||||
PacketBytes = byte_size(Packet),
|
||||
%% 消息广播
|
||||
maps:foreach(fun(Mac, #endpoint{hole = Hole}) ->
|
||||
case {Mac =/= SrcMac, Hole} of
|
||||
{true, #hole{peer = {NatIp, NatPort}}} ->
|
||||
gen_udp:send(Sock, NatIp, NatPort, Packet);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end, UsedMap),
|
||||
|
||||
%% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat
|
||||
lager: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}};
|
||||
{noreply, State#state{forward_bytes = ForwardBytes + PacketBytes}}
|
||||
end;
|
||||
false ->
|
||||
lager: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)]),
|
||||
@ -474,6 +464,19 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
-spec maybe_arp_request(Packet :: binary()) -> error | {ok, ArpPkt :: arp_packet:arp_packet()}.
|
||||
maybe_arp_request(Packet) when is_binary(Packet) ->
|
||||
maybe
|
||||
{ok, LayerPacket} ?= layer_packet:parse(Packet),
|
||||
arp ?= layer_packet:packet_type(LayerPacket),
|
||||
{ok, ArpPacket} ?= arp_packet:parse(layer_packet:payload(LayerPacket)),
|
||||
request ?= arp_packet:opcode(ArpPacket),
|
||||
{ok, ArpPacket}
|
||||
else
|
||||
_ ->
|
||||
error
|
||||
end.
|
||||
|
||||
-spec limiting_check(ThrottleKey :: any()) -> pass | denied.
|
||||
limiting_check(ThrottleKey) ->
|
||||
case throttle:check(sdlan_network, ThrottleKey) of
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user