<commit_before>%%
%%   Copyright (c) 2012 - 2013, <NAME>
%%   Copyright (c) 2012 - 2013, <NAME>
%%   All Rights Reserved.
%%
%%   Licensed under the Apache License, Version 2.0 (the "License");
%%   you may not use this file except in compliance with the License.
%%   You may obtain a copy of the License at
%%
%%       http://www.apache.org/licenses/LICENSE-2.0
%%
%%   Unless required by applicable law or agreed to in writing, software
%%   distributed under the License is distributed on an "AS IS" BASIS,
%%   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%   See the License for the specific language governing permissions and
%%   limitations under the License.
%%
%% @description
%%   client-server ssl konduit
-module(knet_ssl).
-behaviour(pipe).

-include("knet.hrl").

-export([
   start_link/1, 
   init/1, 
   free/2, 
   ioctl/2,
   'IDLE'/3, 
   'LISTEN'/3, 
   'ESTABLISHED'/3
]).


%% internal state
-record(fsm, {
   sock :: port(),  % ssl socket
   peer :: any(),   % peer address  
   addr :: any(),   % local address

   % socket options
   topt        = undefined   :: list(),              %% list of tcp socket opts
   sopt        = undefined   :: list(),              %% list of ssl socket opts    
   active      = true        :: once | true | false, %% socket activity (pipe internally uses active once)
   tout_peer   = ?SO_TIMEOUT :: integer(),           %% timeout to connect peer
   tout_io     = ?SO_TIMEOUT :: integer(),           %% timeout to handle io
   packet      = 0           :: integer(),           %% number of packets handled by socket in between of io timeouts

   service     = undefined :: pid(),                 %% service supervisor
   pool        = 0         :: integer(),             %% socket acceptor pool size

   stats       = undefined :: pid(),                 %% knet stats function
   ts          = undefined :: integer()              %% stats timestamp
}).


%%%------------------------------------------------------------------
%%%
%%% Factory
%%%
%%%------------------------------------------------------------------   

start_link(Opts) ->
   pipe:start_link(?MODULE, Opts ++ ?SO_TCP, []).

%%
init(Opts) ->
   {ok, 'IDLE', 
      #fsm{
         topt      = opts:filter(?SO_TCP_ALLOWED, Opts),
         sopt      = opts:filter(?SO_SSL_ALLOWED, Opts),
         active    = opts:val(active, Opts),
         tout_peer = opts:val(timeout_peer, ?SO_TIMEOUT, Opts),
         tout_io   = opts:val(timeout_io,   ?SO_TIMEOUT, Opts),
         pool      = opts:val(pool, 0, Opts),
         stats     = opts:val(stats, undefined, Opts)
      }
   }.

%%
free(_, S) ->
	ssl:close(S#fsm.sock).

%% 
ioctl(socket,   S) -> 
   S#fsm.sock.

%%%------------------------------------------------------------------
%%%
%%% IDLE
%%%
%%%------------------------------------------------------------------   

%%
'IDLE'({connect, Uri}, Pipe, S) ->
   Host = scalar:c(uri:get(host, Uri)),
   Port = uri:get(port, Uri),
   T1   = os:timestamp(),
   case gen_tcp:connect(Host, Port, S#fsm.topt, S#fsm.tout_peer) of
      {ok, Tcp} ->
      	{ok, Peer} = inet:peername(Tcp),
      	so_stats({connect, tempus:diff(T1)}, S#fsm{peer=Peer}),
      	T2 = os:timestamp(),
         case ssl:connect(Tcp, S#fsm.sopt, S#fsm.tout_peer) of
            {ok, Sock} ->
      		   {ok, Addr} = ssl:sockname(Sock),
      		   %{ok, {Tls, Cipher}} = ssl:connection_info(Sock),
      		   {ok, Cert} = ssl:peercert(Sock),
		         ok         = pns:register(knet, {ssl, Peer}),
         		?DEBUG("knet ssl ~p: established ~p (local ~p)", [self(), Peer, Addr]),
         		so_stats({certificate,    size(Cert)}, S#fsm{peer=Peer}),
         		so_stats({handshake, tempus:diff(T2)}, S#fsm{peer=Peer}),
         		pipe:a(Pipe, {ssl, Peer, established}),
         		so_ioctl(Sock, S),
		         {next_state, 'ESTABLISHED', 
		            S#fsm{
		               sock    = Sock,
		               addr    = Addr,<commit_msg>report certificate size as packet message<commit_after>%%
%%   Copyright (c) 2012 - 2013, <NAME>
%%   Copyright (c) 2012 - 2013, <NAME>
%%   All Rights Reserved.
%%
%%   Licensed under the Apache License, Version 2.0 (the "License");
%%   you may not use this file except in compliance with the License.
%%   You may obtain a copy of the License at
%%
%%       http://www.apache.org/licenses/LICENSE-2.0
%%
%%   Unless required by applicable law or agreed to in writing, software
%%   distributed under the License is distributed on an "AS IS" BASIS,
%%   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%   See the License for the specific language governing permissions and
%%   limitations under the License.
%%
%% @description
%%   client-server ssl konduit
-module(knet_ssl).
-behaviour(pipe).

-include("knet.hrl").

-export([
   start_link/1, 
   init/1, 
   free/2, 
   ioctl/2,
   'IDLE'/3, 
   'LISTEN'/3, 
   'ESTABLISHED'/3
]).


%% internal state
-record(fsm, {
   sock :: port(),  % ssl socket
   peer :: any(),   % peer address  
   addr :: any(),   % local address

   % socket options
   topt        = undefined   :: list(),              %% list of tcp socket opts
   sopt        = undefined   :: list(),              %% list of ssl socket opts    
   active      = true        :: once | true | false, %% socket activity (pipe internally uses active once)
   tout_peer   = ?SO_TIMEOUT :: integer(),           %% timeout to connect peer
   tout_io     = ?SO_TIMEOUT :: integer(),           %% timeout to handle io
   packet      = 0           :: integer(),           %% number of packets handled by socket in between of io timeouts

   service     = undefined :: pid(),                 %% service supervisor
   pool        = 0         :: integer(),             %% socket acceptor pool size

   stats       = undefined :: pid(),                 %% knet stats function
   ts          = undefined :: integer()              %% stats timestamp
}).


%%%------------------------------------------------------------------
%%%
%%% Factory
%%%
%%%------------------------------------------------------------------   

start_link(Opts) ->
   pipe:start_link(?MODULE, Opts ++ ?SO_TCP, []).

%%
init(Opts) ->
   {ok, 'IDLE', 
      #fsm{
         topt      = opts:filter(?SO_TCP_ALLOWED, Opts),
         sopt      = opts:filter(?SO_SSL_ALLOWED, Opts),
         active    = opts:val(active, Opts),
         tout_peer = opts:val(timeout_peer, ?SO_TIMEOUT, Opts),
         tout_io   = opts:val(timeout_io,   ?SO_TIMEOUT, Opts),
         pool      = opts:val(pool, 0, Opts),
         stats     = opts:val(stats, undefined, Opts)
      }
   }.

%%
free(_, S) ->
	ssl:close(S#fsm.sock).

%% 
ioctl(socket,   S) -> 
   S#fsm.sock.

%%%------------------------------------------------------------------
%%%
%%% IDLE
%%%
%%%------------------------------------------------------------------   

%%
'IDLE'({connect, Uri}, Pipe, S) ->
   Host = scalar:c(uri:get(host, Uri)),
   Port = uri:get(port, Uri),
   T1   = os:timestamp(),
   case gen_tcp:connect(Host, Port, S#fsm.topt, S#fsm.tout_peer) of
      {ok, Tcp} ->
      	{ok, Peer} = inet:peername(Tcp),
      	so_stats({connect, tempus:diff(T1)}, S#fsm{peer=Peer}),
      	T2 = os:timestamp(),
         case ssl:connect(Tcp, S#fsm.sopt, S#fsm.tout_peer) of
            {ok, Sock} ->
      		   {ok, Addr} = ssl:sockname(Sock),
      		   %{ok, {Tls, Cipher}} = ssl:connection_info(Sock),
      		   {ok, Cert} = ssl:peercert(Sock),
		         ok         = pns:register(knet, {ssl, Peer}),
         		?DEBUG("knet ssl ~p: established ~p (local ~p)", [self(), Peer, Addr]),
         		so_stats({packet, size(Cert)}, S#fsm{peer=Peer}),
         		so_stats({handshake, tempus:diff(T2)}, S#fsm{peer=Peer}),
         		pipe:a(Pipe, {ssl, Peer, established}),
         		so_ioctl(Sock, S),
		         {next_state, 'ESTABLISHED', 
		            S#fsm{
		               sock    = Sock,
		               addr    = Addr,
{'fraction_non_alphanumeric': 0.20765164862824062, 'fraction_numerical': 0.008557764913163856, 'mean_word_length': 1.7815890794539726, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '573238', 'n_tokens_mistral': 2606, 'n_tokens_neox': 2469, 'n_words': 648}