fix
This commit is contained in:
parent
609bcd6cd5
commit
775ec28485
@ -77,6 +77,10 @@
|
||||
%% 数据转发
|
||||
-define(PACKET_STUN_DATA, 16#FF).
|
||||
|
||||
%% arp查询 request -> response
|
||||
-define(PACKET_ARP_REQUEST, 16#a0).
|
||||
-define(PACKET_ARP_RESPONSE, 16#a1).
|
||||
|
||||
-record(id_generator, {
|
||||
tab :: atom(),
|
||||
increment_id = 0 :: integer()
|
||||
|
||||
@ -333,7 +333,6 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
||||
end;
|
||||
|
||||
%% 网络数据转发, ip广播或组播, 不限流
|
||||
%% TODO 需要处理arp请求,arp请求就不要广播出去了,network是知道目标的ip信息的
|
||||
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, endpoints = Endpoints, forward_bytes = ForwardBytes})
|
||||
when is_map_key(SrcMac, Endpoints) ->
|
||||
%% 广播地址和组播地址,需要转发到整个网络
|
||||
@ -345,10 +344,14 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
||||
TargetIp = arp_packet:target_ip(ArpRequestPkt),
|
||||
%% 通过ip查找到对应的Endpoint
|
||||
|
||||
TargetMac = <<>>,
|
||||
case search_endpoint(fun(#endpoint{ip = Ip0}) -> TargetIp =:= Ip0 end, Endpoints) of
|
||||
{ok, TargetMac, _} ->
|
||||
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpRequestPkt, TargetMac, TargetIp)),
|
||||
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, Endpoints),
|
||||
gen_udp:send(Sock, NatIp, NatPort, ArpResponse);
|
||||
error ->
|
||||
ok
|
||||
end;
|
||||
|
||||
error ->
|
||||
PacketBytes = byte_size(Packet),
|
||||
@ -583,3 +586,19 @@ format_endpoint({Mac, #endpoint{client_id = ClientId, ip = Ip, hole = Hole, v6_i
|
||||
hole_map => HoleMap,
|
||||
v6_info => V6InfoMap
|
||||
}.
|
||||
|
||||
-spec search_endpoint(F :: fun((term(), term()) -> boolean()), Endpoints :: map()) -> error | {ok, Key :: any(), Val :: any()}.
|
||||
search_endpoint(F, Endpoints) when is_function(F, 1), is_map(Endpoints) ->
|
||||
search_endpoint0(F, maps:iterator(Endpoints)).
|
||||
search_endpoint0(F, Iter) when is_function(F, 1) ->
|
||||
case maps:next(Iter) of
|
||||
{Key, Value, NextIter} ->
|
||||
case F(Key, Value) of
|
||||
true ->
|
||||
{ok, Key, Value};
|
||||
false ->
|
||||
search_endpoint0(F, NextIter)
|
||||
end;
|
||||
'none' ->
|
||||
error
|
||||
end.
|
||||
@ -165,6 +165,23 @@ handle_info({udp, _, _Ip, _Port, <<?PACKET_STUN_DATA, Body/binary>>}, State = #s
|
||||
|
||||
{noreply, State};
|
||||
|
||||
handle_info({udp, _, _Ip, _Port, <<?PACKET_ARP_REQUEST, Body/binary>>}, 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),
|
||||
|
||||
lager: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, <<?PACKET_STUN_DATA, NData/binary>>);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
|
||||
{noreply, State};
|
||||
|
||||
|
||||
handle_info(Info, State) ->
|
||||
lager:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]),
|
||||
{noreply, State}.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user