Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions src/tsung/ts_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ handle_next_action(State=#state_rcv{dynvars = DynVars}) ->
RateConf=#token_bucket{rate=Rate,burst=Burst,last_packet_date=?NOW},
Thresh=lists:min([Burst,State#state_rcv.size_mon_thresh]),
handle_next_action(State#state_rcv{size_mon=Thresh,size_mon_thresh=Thresh,rate_limit=RateConf,count=Count});
{set_option, undefined, certificate, {Cacert, KeyFile, KeyPass, CertFile}} ->
?LOGF("Set client certificate: ~p ~p ~p ~p~n",[Cacert, KeyFile, KeyPass, CertFile],?DEB),
{set_option, undefined, certificate, {Cacert, KeyFile, TLSKey, KeyPass, CertFile, TLSCert}} ->
?LOGF("Set client certificate: ~p ~p ~p ~p ~p ~p ~n",[Cacert, KeyFile, TLSKey, KeyPass, CertFile, TLSCert],?DEB),
Opts = ts_utils:filtermap(fun({N,V}) ->
case V of
undefined ->
Expand All @@ -507,14 +507,33 @@ handle_next_action(State=#state_rcv{dynvars = DynVars}) ->
Val ->
{true, {N,ts_search:subst(Val, DynVars)}}
end
end ,
end,
[{certfile, CertFile},
{cert,TLSCert},
{keyfile,KeyFile},
{key,TLSKey},
{password,KeyPass},
{cacertfile,Cacert}]),
?LOGF("SSL options for certificate: ~p~n",[Opts],?DEB),

Opts2 = ts_utils:filtermap(
fun({N,V}) ->
case {N,V} of
{_, undefined} -> false;
{key, _} ->
[{KeyType, KeyData, _} | _] = public_key:pem_decode(list_to_binary(V)),
{true, {key, {KeyType, KeyData}}};
{cert, _} ->
[{'Certificate', CertData, _} | _] = public_key:pem_decode(list_to_binary(V)),
{true, {cert, CertData}};
{_, V} -> {true, {N,V}}
end
end,
Opts
),

?LOGF("SSL options for certificate: ~p~n",[Opts2],?DEB),
OldOpts = State#state_rcv.proto_opts,
NewOpts = OldOpts#proto_opts{certificate = Opts},
NewOpts = OldOpts#proto_opts{certificate = Opts2},
%% close connection if necessary
(State#state_rcv.protocol):close(State#state_rcv.socket),
set_connected_status(false),
Expand Down Expand Up @@ -1050,6 +1069,11 @@ reconnect(none, ServerName, Port, {Protocol, Proto_opts}, {IP,CPort, Try}) when
end,
?LOGF("Connect failed with client port ~p, retry with ~p~n",[CPort, NewCPort],?INFO),
reconnect(none, ServerName, Port, {Protocol, Proto_opts}, {IP,NewCPort, undefined});
{{options, {Option, _}}, _, _} ->
CountName="error_connect_option_"++atom_to_list(Option),
ts_mon_cache:add({ count, list_to_atom(CountName) });
{tls_alert, "bad certificate"} ->
ts_mon_cache:add({ count, list_to_atom("error_connect_tls_bad_certificate") });
_ ->
CountName="error_connect_"++atom_to_list(Reason),
ts_mon_cache:add({ count, list_to_atom(CountName) })
Expand Down
17 changes: 15 additions & 2 deletions src/tsung_controller/ts_config.erl
Original file line number Diff line number Diff line change
Expand Up @@ -720,14 +720,27 @@ parse( Element = #xmlElement{name=set_option, attributes=Attrs},
Max = getAttr(integer, Attrs, max, Rate),
{undefined, rate_limit, {1024*Rate div 1000, 1024 * Max}};
"certificate" ->
{value, #xmlElement{attributes=AttrCert}} = lists:keysearch(certificate,
{value, CertificateElement = #xmlElement{attributes=AttrCert}} = lists:keysearch(certificate,
#xmlElement.name,
Element#xmlElement.content),
Cacert = getAttr(string, AttrCert, cacertfile, undefined),
KeyFile = getAttr(string, AttrCert, keyfile, undefined),
KeyPass = getAttr(string, AttrCert, keypass, undefined),
CertFile = getAttr(string, AttrCert, certfile, undefined),
{undefined, certificate, {Cacert, KeyFile,KeyPass,CertFile}};

TLSCert = case lists:keysearch(cert, #xmlElement.name, CertificateElement#xmlElement.content) of
{value, #xmlElement{content=CertRaw}} ->
ts_utils:clean_str(getText(CertRaw));
_ -> undefined
end,

TLSKey = case lists:keysearch(key, #xmlElement.name, CertificateElement#xmlElement.content) of
{value, #xmlElement{content=KeyRaw}} ->
ts_utils:clean_str(getText(KeyRaw));
_ -> undefined
end,

{undefined, certificate, {Cacert, KeyFile, TLSKey, KeyPass, CertFile, TLSCert}};
"connect_timeout" ->
ConnectTimeout = getAttr(integer, Attrs, value),
{undefined, connect_timeout, {ConnectTimeout}}
Expand Down
4 changes: 3 additions & 1 deletion tsung-1.0.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,15 @@
type (ts_http | ts_jabber | ts_pgsql) #IMPLIED
value CDATA #IMPLIED>

<!ELEMENT certificate EMPTY >
<!ELEMENT certificate (cert | key)*>
<!ATTLIST certificate
cacertfile CDATA #IMPLIED
keyfile CDATA #IMPLIED
keypass CDATA #IMPLIED
certfile CDATA #IMPLIED
>
<!ELEMENT key (#PCDATA)>
<!ELEMENT cert (#PCDATA)>

<!ELEMENT sessions (session+)>
<!ELEMENT session ( request | thinktime | transaction | setdynvars | for |
Expand Down