diff --git a/docs/heartbeat.md b/docs/heartbeat.md index d792b8a..fadd2a7 100644 --- a/docs/heartbeat.md +++ b/docs/heartbeat.md @@ -41,4 +41,4 @@ Payload = < false; - [#efka_client{token_hash = TokenHash}] -> - ExpectedMac = crypto:mac(hmac, sha256, TokenHash, Payload), + [#efka_client{heartbeat_secret = HeartbeatSecret}] -> + ExpectedMac = crypto:mac(hmac, sha256, HeartbeatSecret, Payload), ExpectedMac =:= Mac end; false -> @@ -61,7 +61,14 @@ register(UUID, Token) when is_binary(UUID), UUID =/= <<>>, is_binary(Token), byt %% 1. 生成 16 字节随机盐 Salt = crypto:strong_rand_bytes(16), TokenHash = hash_token(Token, Salt), - ok = mnesia:write(#efka_client{uuid = UUID, token_hash = TokenHash, salt = Salt, timestamp = iot_util:timestamp()}), + HeartbeatSecret = heartbeat_secret(Token), + ok = mnesia:write(#efka_client{ + uuid = UUID, + token_hash = TokenHash, + salt = Salt, + heartbeat_secret = HeartbeatSecret, + timestamp = iot_util:timestamp() + }), ok; [_] -> {error, already_exists} @@ -137,7 +144,11 @@ list() -> hash_token(Token, Salt) when is_binary(Token), is_binary(Salt) -> crypto:pbkdf2_hmac(sha256, Token, Salt, ?TOKEN_HASH_ITERATIONS, ?TOKEN_HASH_BYTES). +-spec heartbeat_secret(binary()) -> binary(). +heartbeat_secret(Token) when is_binary(Token) -> + crypto:hash(sha256, Token). + -spec valid_heartbeat_timestamp(integer()) -> boolean(). valid_heartbeat_timestamp(Timestamp) -> Now = iot_util:current_time(), - Timestamp =< Now andalso Now - Timestamp =< ?HEARTBEAT_TIMESTAMP_WINDOW. \ No newline at end of file + Timestamp =< Now andalso Now - Timestamp =< ?HEARTBEAT_TIMESTAMP_WINDOW. diff --git a/src/transport/udp/udp_server.erl b/src/transport/udp/udp_server.erl index a61a854..6a04552 100644 --- a/src/transport/udp/udp_server.erl +++ b/src/transport/udp/udp_server.erl @@ -82,6 +82,9 @@ handle_cast(_Request, State = #state{}) -> {stop, Reason :: term(), NewState :: #state{}}). handle_info({udp, Socket, Ip, Port, Packet}, State = #state{socket = Socket}) -> handle_heartbeat_packet(Packet, {Ip, Port}), + {noreply, State}; +handle_info(Info, State = #state{}) -> + logger:warning("[udp_server] ignore unknown info: ~p", [Info]), {noreply, State}. %% @private @@ -91,7 +94,8 @@ handle_info({udp, Socket, Ip, Port, Packet}, State = #state{socket = Socket}) -> %% with Reason. The return value is ignored. -spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), State :: #state{}) -> term()). -terminate(_Reason, _State = #state{}) -> +terminate(_Reason, _State = #state{socket = Socket}) -> + gen_udp:close(Socket), ok. %% @private @@ -132,4 +136,4 @@ decode_heartbeat_packet(Packet = <> = Packet, {ok, UUID, Timestamp, Payload, Mac}; decode_heartbeat_packet(_Packet) -> - error. \ No newline at end of file + error.