Skip to content

Commit

Permalink
Preparation for checking session transmitted bytes
Browse files Browse the repository at this point in the history
Modify session record and state to maintain transmitted bytes in both
directions. If the number of bytes is not kept, lost packets will disrupt
the session.

When the client is sending data, the byte count should be equal to our
count plus the size of the new data. Otherwise, the packet is assumed
to be a duplicate and will be dropped.

When the client is requesting pending data, the byte count should be
equal to ours. If it is smaller, we should re-send our last packet.
  • Loading branch information
msantos committed Nov 4, 2010
1 parent 91f6159 commit 596a84d
Showing 1 changed file with 35 additions and 18 deletions.
53 changes: 35 additions & 18 deletions seds/src/seds_proxy.erl
Expand Up @@ -40,7 +40,8 @@
dnsfd, % dns server socket dnsfd, % dns server socket
s, % proxied socket s, % proxied socket


sum = 0, % number of bytes sent sum_up = 0, % number of bytes sent to server
sum_down = 0, % number of bytes received from server
data = [<<>>] % list of binaries: data returned by proxied server data = [<<>>] % list of binaries: data returned by proxied server
}). }).


Expand All @@ -62,9 +63,9 @@
%%% Interface %%% Interface
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
send(Pid, IP, Port, #dns_rec{} = Query, {up, Data}) when is_pid(Pid) -> send(Pid, IP, Port, #dns_rec{} = Query, {up, Data}) when is_pid(Pid) ->
gen_fsm:send_event(Pid, {dns_query, IP, Port, Query, Data}); gen_fsm:send_event(Pid, {up, IP, Port, Query, Data});
send(Pid, IP, Port, #dns_rec{} = Query, {down, _}) when is_pid(Pid) -> send(Pid, IP, Port, #dns_rec{} = Query, {down, _}) when is_pid(Pid) ->
gen_fsm:send_event(Pid, {dns_query, IP, Port, Query}). gen_fsm:send_event(Pid, {down, IP, Port, Query}).


%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%%% Behaviours %%% Behaviours
Expand Down Expand Up @@ -110,11 +111,13 @@ handle_info({tcp_closed, Socket}, proxy, #state{s = Socket} = State) ->
terminate(Reason, StateName, #state{ terminate(Reason, StateName, #state{
ip = IP, ip = IP,
port = Port, port = Port,
sum = Sum sum_up = Up,
sum_down = Down
}) -> }) ->
error_logger:info_report([ error_logger:info_report([
{session_end, {IP, Port}}, {session_end, {IP, Port}},
{bytes_sent, Sum}, {bytes_sent, Up},
{bytes_rcvd, Down},
{state, StateName}, {state, StateName},
{reason, Reason} {reason, Reason}
]), ]),
Expand All @@ -127,6 +130,10 @@ code_change(_OldVsn, StateName, State, _Extra) ->
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%%% States %%% States
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

%%
%% connect
%%
connect(timeout, #state{ip = IP, port = Port} = State) -> connect(timeout, #state{ip = IP, port = Port} = State) ->
{ok, Socket} = gen_tcp:connect(IP, Port, [ {ok, Socket} = gen_tcp:connect(IP, Port, [
binary, binary,
Expand All @@ -135,7 +142,13 @@ connect(timeout, #state{ip = IP, port = Port} = State) ->
], 5000), ], 5000),
{next_state, proxy, State#state{s = Socket}}. {next_state, proxy, State#state{s = Socket}}.


proxy({dns_query, IP, Port,
%%
%% proxy
%%

% client sent data to be forwarded to server
proxy({up, IP, Port,
#dns_rec{ #dns_rec{
header = Header, header = Header,
qdlist = [#dns_query{ qdlist = [#dns_query{
Expand All @@ -144,17 +157,16 @@ proxy({dns_query, IP, Port,
}|_] }|_]
} = Rec, Data}, } = Rec, Data},
#state{ #state{
sum = Sum, sum_up = Sum,
dnsfd = DNSSocket, dnsfd = DNSSocket,
s = Socket s = Socket
} = State) -> } = State) ->


Payload = base32:decode(string:to_upper(Data)), Payload = base32:decode(string:to_upper(Data)),
Sum1 = Sum + length(Payload),


ok = gen_tcp:send(Socket, Payload), ok = gen_tcp:send(Socket, Payload),


Sum1 = Sum + length(Payload),

Packet = inet_dns:encode( Packet = inet_dns:encode(
Rec#dns_rec{ Rec#dns_rec{
header = Header#dns_header{ header = Header#dns_header{
Expand All @@ -174,25 +186,29 @@ proxy({dns_query, IP, Port,
]), ]),


ok = gen_udp:send(DNSSocket, IP, Port, Packet), ok = gen_udp:send(DNSSocket, IP, Port, Packet),
{next_state, proxy, State, ?PROXY_TIMEOUT}; {next_state, proxy, State#state{sum_up = Sum1},
proxy({dns_query, IP, Port, ?PROXY_TIMEOUT};

% client requested any pending data from server
proxy({down, IP, Port,
#dns_rec{ #dns_rec{
header = Header, header = Header,
qdlist = [#dns_query{ qdlist = [#dns_query{
domain = Domain, domain = Domain,
type = Type type = Type
}|_] }|_]} = Rec},
} = Rec}, #state{
#state{ sum_down = Sum,
dnsfd = DNSSocket, dnsfd = DNSSocket,
s = Socket, s = Socket,
data = Data data = Data
} = State) -> } = State) ->


% Client polled, allow more data from server % Client polled, allow more data from server
ok = inet:setopts(Socket, [{active, once}]), ok = inet:setopts(Socket, [{active, once}]),


{Payload, Rest} = data(Type, Data), {Payload, Rest} = data(Type, Data),
Sum1 = Sum + length(Payload),


Response = Rec#dns_rec{ Response = Rec#dns_rec{
header = Header#dns_header{ header = Header#dns_header{
Expand All @@ -215,6 +231,7 @@ proxy({dns_query, IP, Port,
ok = gen_udp:send(DNSSocket, IP, Port, Packet), ok = gen_udp:send(DNSSocket, IP, Port, Packet),


{next_state, proxy, State#state{ {next_state, proxy, State#state{
sum_down = Sum1,
data = [Rest] data = [Rest]
}, ?PROXY_TIMEOUT}; }, ?PROXY_TIMEOUT};
proxy(timeout, State) -> proxy(timeout, State) ->
Expand Down

0 comments on commit 596a84d

Please sign in to comment.