Browse files

implement protocol version checking and reject connection from incomp…

…atible clients
  • Loading branch information...
1 parent 2ce2f04 commit cbf0f9c6a87d485c49cd079770ef197c26921d79 @RJ committed Jan 8, 2010
View
1 playdar_modules/playdar-tcp/src/playdartcp.hrl
@@ -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
View
57 playdar_modules/playdar-tcp/src/playdartcp_conn.erl
@@ -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 ->
@@ -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:
View
2 playdar_modules/playdar-tcp/src/playdartcp_stream.erl
@@ -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}) ->
View
35 playdar_modules/playdar-tcp/src/playdartcp_web.erl
@@ -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]),

0 comments on commit cbf0f9c

Please sign in to comment.