fix
This commit is contained in:
parent
609bcd6cd5
commit
775ec28485
@ -77,6 +77,10 @@
|
|||||||
%% 数据转发
|
%% 数据转发
|
||||||
-define(PACKET_STUN_DATA, 16#FF).
|
-define(PACKET_STUN_DATA, 16#FF).
|
||||||
|
|
||||||
|
%% arp查询 request -> response
|
||||||
|
-define(PACKET_ARP_REQUEST, 16#a0).
|
||||||
|
-define(PACKET_ARP_RESPONSE, 16#a1).
|
||||||
|
|
||||||
-record(id_generator, {
|
-record(id_generator, {
|
||||||
tab :: atom(),
|
tab :: atom(),
|
||||||
increment_id = 0 :: integer()
|
increment_id = 0 :: integer()
|
||||||
|
|||||||
@ -333,7 +333,6 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
%% 网络数据转发, ip广播或组播, 不限流
|
%% 网络数据转发, ip广播或组播, 不限流
|
||||||
%% TODO 需要处理arp请求,arp请求就不要广播出去了,network是知道目标的ip信息的
|
|
||||||
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, endpoints = Endpoints, forward_bytes = ForwardBytes})
|
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, endpoints = Endpoints, forward_bytes = ForwardBytes})
|
||||||
when is_map_key(SrcMac, Endpoints) ->
|
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),
|
TargetIp = arp_packet:target_ip(ArpRequestPkt),
|
||||||
%% 通过ip查找到对应的Endpoint
|
%% 通过ip查找到对应的Endpoint
|
||||||
|
|
||||||
TargetMac = <<>>,
|
case search_endpoint(fun(#endpoint{ip = Ip0}) -> TargetIp =:= Ip0 end, Endpoints) of
|
||||||
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpRequestPkt, TargetMac, TargetIp)),
|
{ok, TargetMac, _} ->
|
||||||
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, Endpoints),
|
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpRequestPkt, TargetMac, TargetIp)),
|
||||||
gen_udp:send(Sock, NatIp, NatPort, ArpResponse);
|
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, Endpoints),
|
||||||
|
gen_udp:send(Sock, NatIp, NatPort, ArpResponse);
|
||||||
|
error ->
|
||||||
|
ok
|
||||||
|
end;
|
||||||
|
|
||||||
error ->
|
error ->
|
||||||
PacketBytes = byte_size(Packet),
|
PacketBytes = byte_size(Packet),
|
||||||
@ -582,4 +585,20 @@ format_endpoint({Mac, #endpoint{client_id = ClientId, ip = Ip, hole = Hole, v6_i
|
|||||||
ip => sdlan_ipaddr:int_to_ipv4(Ip),
|
ip => sdlan_ipaddr:int_to_ipv4(Ip),
|
||||||
hole_map => HoleMap,
|
hole_map => HoleMap,
|
||||||
v6_info => V6InfoMap
|
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};
|
{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) ->
|
handle_info(Info, State) ->
|
||||||
lager:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]),
|
lager:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user