Skip to content

Commit

Permalink
implement protocol version checking and reject connection from incomp…
Browse files Browse the repository at this point in the history
…atible clients
  • Loading branch information
RJ committed Jan 8, 2010
1 parent 2ce2f04 commit cbf0f9c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 39 deletions.
1 change: 1 addition & 0 deletions playdar_modules/playdar-tcp/src/playdartcp.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
-define(TCP_OPTS_SERVER, [ {backlog, 10} | ?TCP_OPTS ]).
-define(T2B(T), term_to_binary(T)).
-define(B2T(T), binary_to_term(T)).
-define(PROTOVER, 1). % bump this for incompatible protocol changes
57 changes: 35 additions & 22 deletions playdar_modules/playdar-tcp/src/playdartcp_conn.erl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ init([Sock, InOut, Share]) ->
out ->
% Needs more DRY - props also created in response to auth packet below
PublicPort = ?CONFVAL({playdartcp,port},60211),
Props = [{share, Share}, {public_port, PublicPort}],
Props = [{share, Share},
{public_port, PublicPort},
{protover, ?PROTOVER}
],
Msg = ?T2B({auth, ?CONFVAL(name, "unknown"), Props}),
ok = gen_tcp:send(Sock, Msg);
in ->
Expand Down Expand Up @@ -146,27 +149,37 @@ code_change(_OldVsn, State, _Extra) ->
%% Incoming auth/peer ID:
handle_packet({auth, Name, Props}, State = #state{sock=Sock, authed=false}) when is_list(Name), is_list(Props) ->
?LOG(info, "new playdartcp connection authed as ~s, props: ~p", [Name, Props]),
Sharing = {State#state.weshare, proplists:get_value(share, Props, false)==true},
case playdartcp_router:register_connection(self(), Name, Sharing) of
ok ->
TheyShare = proplists:get_value(share, Props) == true,
% send our details to them if the connection was inbound, ie we didnt send yet:
case State#state.inout of
in ->
DefName = "unknown-"++erlang:integer_to_list(random:uniform(9999999)), % HACK
% tell them if we are sharing content with them:
PublicPort = ?CONFVAL({playdartcp,port},60211),
OurProps = [{share, State#state.weshare}, {public_port, PublicPort}],
M = ?T2B({auth, ?CONFVAL(name, DefName), OurProps}),
ok = gen_tcp:send(Sock, M),
{noreply, State#state{authed=true, name=Name, props=Props, theyshare=TheyShare}};
out ->
{noreply, State#state{authed=true, name=Name, props=Props, theyshare=TheyShare}}
end;

disconnect ->
?LOG(info, "Abandoning connection, duplicate name",[]),
{stop, normal, State}
Theirver = proplists:get_value(protover, Props, -1),
if
Theirver < ?PROTOVER ->
?LOG(info, "Remote protocol version incompatible, kicking", []),
{stop, normal, State};
true ->
Sharing = {State#state.weshare, proplists:get_value(share, Props, false)==true},
case playdartcp_router:register_connection(self(), Name, Sharing) of
ok ->
TheyShare = proplists:get_value(share, Props) == true,
% send our details to them if the connection was inbound, ie we didnt send yet:
case State#state.inout of
in ->
DefName = "unknown-"++erlang:integer_to_list(random:uniform(9999999)), % HACK
% tell them if we are sharing content with them:
PublicPort = ?CONFVAL({playdartcp,port},60211),
OurProps = [{share, State#state.weshare},
{public_port, PublicPort},
{protover, ?PROTOVER}
],
M = ?T2B({auth, ?CONFVAL(name, DefName), OurProps}),
ok = gen_tcp:send(Sock, M),
{noreply, State#state{authed=true, name=Name, props=Props, theyshare=TheyShare}};
out ->
{noreply, State#state{authed=true, name=Name, props=Props, theyshare=TheyShare}}
end;

disconnect ->
?LOG(info, "Abandoning connection, duplicate name",[]),
{stop, normal, State}
end
end;

%% Incoming query:
Expand Down
2 changes: 1 addition & 1 deletion playdar_modules/playdar-tcp/src/playdartcp_stream.erl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ handle_info({Ref, error, Reason}, State=#state{current=send_stream_body,
Msg = ?T2B({sid_response, Ref, Sid, {error, Reason}}),
ok = gen_tcp:send(Sock, Msg),
gen_tcp:close(Sock),
{stop, normal, State};
{stop, norsmal, State};

handle_info({Ref, eof}, State=#state{current=send_stream_body,
sock=Sock, ref=Ref, sid=Sid}) ->
Expand Down
35 changes: 19 additions & 16 deletions playdar_modules/playdar-tcp/src/playdartcp_web.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,34 @@ index(Path, Req, DocRoot) ->
case Path of
"" ->
Streams = get_streams(),
?LOG(info, "~p", [Streams]),
Peers = get_peers(),
%?LOG(info, "~p", [Streams]),
Vars = [{ftok, playdar_auth:gen_formtoken()},
{streams, Streams},
{peers,
[ begin
ShareWe = case WeShare of true -> "yes"; _ -> "no" end,
ShareThey = case TheyShare of true -> "yes"; _ -> "no" end,
{{{Y,M,D},{H,Min,S}},{ok, Stats}} = playdartcp_conn:stats(P),
Date = io_lib:format("~w/~2..0w/~2..0w ~2..0w:~2..0w:~2..0w",[Y,M,D,H,Min,S]),
[ {name, N},
{pid, io_lib:format("~p",[P])},
{conndate, Date},
{stats, Stats},
{weshare, ShareWe},
{theyshare, ShareThey} ]
end
|| {N,P,{WeShare, TheyShare}} <- playdartcp_router:peers() ]
}],
{peers, Peers}
],

playdar_web:render(Req, DocRoot ++ "/playdartcp/index.html", Vars);

_ ->
Req:not_found()
end.

get_peers() ->
[ begin
ShareWe = case WeShare of true -> "yes"; _ -> "no" end,
ShareThey = case TheyShare of true -> "yes"; _ -> "no" end,
{{{Y,M,D},{H,Min,S}},{ok, Stats}} = playdartcp_conn:stats(P),
Date = io_lib:format("~w/~2..0w/~2..0w ~2..0w:~2..0w:~2..0w",[Y,M,D,H,Min,S]),
[ {name, N},
{pid, io_lib:format("~p",[P])},
{conndate, Date},
{stats, Stats},
{weshare, ShareWe},
{theyshare, ShareThey} ]
end
|| {N,P,{WeShare, TheyShare}} <- playdartcp_router:peers() ].

get_streams() ->
S = playdartcp_router:streams(),
% ?LOG(info, "Streams: ~p", [S]),
Expand Down

0 comments on commit cbf0f9c

Please sign in to comment.