隔离出udp包的处理逻辑
This commit is contained in:
parent
ce69bfd730
commit
c1f196fa96
@ -100,77 +100,11 @@ 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, <<?PACKET_STUN_REQUEST:8, Body/binary>>}, 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),
|
||||
%% 告知网络当前的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, <<?PACKET_STUN_REPLY, StunReply/binary>>),
|
||||
logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, hole: ~p", [NetworkId, ClientId, {Ip, Port}]),
|
||||
{noreply, State}
|
||||
end;
|
||||
|
||||
%% 网络nat类型的探测机制, 需要借助其他服务一起才能实现
|
||||
%% 辅助节点没有assist的配置,不支持attr = 2的探测
|
||||
handle_info({udp, Sock, Ip, Port, <<?PACKET_STUN_PROBE:8, Body/binary>>}, 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]),
|
||||
|
||||
ProbeReply = sdlan_pb:encode_msg(#sdl_stun_probe_reply {
|
||||
cookie = Cookie,
|
||||
port = Port,
|
||||
ip = int_ip(Ip)
|
||||
}),
|
||||
Packet = <<?PACKET_STUN_PROBE_REPLY, ProbeReply/binary>>,
|
||||
|
||||
case Attr of
|
||||
?STUN_ATTR_CHANGE_NONE ->
|
||||
ok = gen_udp:send(Sock, Ip, Port, Packet);
|
||||
?STUN_ATTR_CHANGE_PORT ->
|
||||
sdlan_stun_port_assist:stun_relay(Ip, Port, Packet);
|
||||
?STUN_ATTR_CHANGE_PEER ->
|
||||
sdlan_stun_peer_assist:stun_relay(Ip, Port, Packet)
|
||||
end,
|
||||
handle_info({udp, Sock, Ip, Port, Packet}, State = #state{socket = Sock}) ->
|
||||
catch handle_packet(Sock, Ip, Port, Packet),
|
||||
{noreply, State};
|
||||
|
||||
%% 转发消息, 跨服务器的stun_reply的转发通过socket来转发
|
||||
handle_info({udp, Sock, _, _, <<?PACKET_STUN_PROBE_RELAY:8, Ip0, Ip1, Ip2, Ip3, Port:16, Reply/binary>>}, 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, <<?PACKET_STUN_DATA, 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),
|
||||
|
||||
logger:debug("[sdlan_stun] stun data, src_mac: ~p, dst_mac: ~p", [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]),
|
||||
maybe
|
||||
{ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId),
|
||||
%% 重新打包数据ttl需要减1
|
||||
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>>)
|
||||
end,
|
||||
{noreply, State};
|
||||
|
||||
handle_info({udp, _, Ip, Port, <<?PACKET_ARP_REQUEST, Body/binary>>}, State = #state{socket = Sock}) ->
|
||||
#sdl_arp_request{network_id = NetworkId, target_ip = TargetIp} = sdlan_pb:decode_msg(Body, sdl_arp_request),
|
||||
logger:debug("[sdlan_stun] stun sdl_arp_request, network_id: ~p, target_ip: ~p", [NetworkId, TargetIp]),
|
||||
maybe
|
||||
{ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId),
|
||||
{ok, TargetMac} ?= sdlan_network:arp_query(NetworkPid, TargetIp),
|
||||
ArpResponse = sdlan_pb:encode_msg(#sdl_arp_response{network_id = NetworkId, target_ip = TargetIp, target_mac = TargetMac}),
|
||||
ok ?= gen_udp:send(Sock, Ip, Port, ArpResponse)
|
||||
end,
|
||||
{noreply, State};
|
||||
|
||||
handle_info({udp_error , Sock, Reason}, State = #state{socket = Sock}) ->
|
||||
{stop, Reason, State};
|
||||
handle_info(Info, State) ->
|
||||
logger:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]),
|
||||
{noreply, State}.
|
||||
@ -197,6 +131,70 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
-spec handle_packet(Sock :: inet:socket(), Ip :: inet:ip4_address(), Port :: integer(), Packet :: binary()) -> no_return().
|
||||
handle_packet(Sock, Ip, Port, <<?PACKET_STUN_REQUEST:8, Body/binary>>) ->
|
||||
#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),
|
||||
%% 告知网络当前的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]),
|
||||
ok;
|
||||
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, <<?PACKET_STUN_REPLY, StunReply/binary>>),
|
||||
logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, hole: ~p", [NetworkId, ClientId, {Ip, Port}])
|
||||
end;
|
||||
|
||||
%% 网络nat类型的探测机制, 需要借助其他服务一起才能实现
|
||||
%% 辅助节点没有assist的配置,不支持attr = 2的探测
|
||||
handle_packet(Sock, Ip, Port, <<?PACKET_STUN_PROBE:8, Body/binary>>) ->
|
||||
#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]),
|
||||
|
||||
ProbeReply = sdlan_pb:encode_msg(#sdl_stun_probe_reply {
|
||||
cookie = Cookie,
|
||||
port = Port,
|
||||
ip = int_ip(Ip)
|
||||
}),
|
||||
Packet = <<?PACKET_STUN_PROBE_REPLY, ProbeReply/binary>>,
|
||||
|
||||
case Attr of
|
||||
?STUN_ATTR_CHANGE_NONE ->
|
||||
ok = gen_udp:send(Sock, Ip, Port, Packet);
|
||||
?STUN_ATTR_CHANGE_PORT ->
|
||||
sdlan_stun_port_assist:stun_relay(Ip, Port, Packet);
|
||||
?STUN_ATTR_CHANGE_PEER ->
|
||||
sdlan_stun_peer_assist:stun_relay(Ip, Port, Packet)
|
||||
end;
|
||||
|
||||
%% 转发消息, 跨服务器的stun_reply的转发通过socket来转发
|
||||
handle_packet(Sock, _, _, <<?PACKET_STUN_PROBE_RELAY:8, Ip0, Ip1, Ip2, Ip3, Port:16, Reply/binary>>) ->
|
||||
logger:debug("[sdlan_stun] get stun_probe_replay request, reply: ~p", [Reply]),
|
||||
gen_udp:send(Sock, {Ip0, Ip1, Ip2, Ip3}, Port, Reply);
|
||||
|
||||
handle_packet(Sock, _Ip, _Port, <<?PACKET_STUN_DATA, Body/binary>>) ->
|
||||
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)]),
|
||||
maybe
|
||||
{ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId),
|
||||
%% 重新打包数据ttl需要减1
|
||||
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>>)
|
||||
end;
|
||||
|
||||
handle_packet(Sock, Ip, Port, <<?PACKET_ARP_REQUEST, Body/binary>>) ->
|
||||
#sdl_arp_request{network_id = NetworkId, target_ip = TargetIp} = sdlan_pb:decode_msg(Body, sdl_arp_request),
|
||||
logger:debug("[sdlan_stun] stun sdl_arp_request, network_id: ~p, target_ip: ~p", [NetworkId, TargetIp]),
|
||||
maybe
|
||||
{ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId),
|
||||
{ok, TargetMac} ?= sdlan_network:arp_query(NetworkPid, TargetIp),
|
||||
ArpResponse = sdlan_pb:encode_msg(#sdl_arp_response{network_id = NetworkId, target_ip = TargetIp, target_mac = TargetMac}),
|
||||
ok ?= gen_udp:send(Sock, Ip, Port, ArpResponse)
|
||||
end.
|
||||
|
||||
-spec int_ip(tuple()) -> integer().
|
||||
int_ip({Ip0, Ip1, Ip2, Ip3}) ->
|
||||
<<Ip:32>> = <<Ip0, Ip1, Ip2, Ip3>>,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user