ji2p 0.0.1-jruby
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/ctxirb +114 -0
- data/bin/simple_http_server +20 -0
- data/bin/simple_outproxy +96 -0
- data/lib/ji2p/cluster/etcd/version3.rb +6 -0
- data/lib/ji2p/cluster/etcd.rb +5 -0
- data/lib/ji2p/cluster/kubernetes/kube_api.rb +6 -0
- data/lib/ji2p/cluster/kubernetes.rb +5 -0
- data/lib/ji2p/cluster.rb +6 -0
- data/lib/ji2p/control/client_manager.rb +14 -0
- data/lib/ji2p/control/dest.rb +34 -0
- data/lib/ji2p/control/keypair.rb +176 -0
- data/lib/ji2p/control/server.rb +80 -0
- data/lib/ji2p/control/socket_manager.rb +74 -0
- data/lib/ji2p/control/tunnel_ctrl.rb +48 -0
- data/lib/ji2p/control/tunnel_manager.rb +62 -0
- data/lib/ji2p/control.rb +14 -0
- data/lib/ji2p/server/api.rb +15 -0
- data/lib/ji2p/server/database.rb +66 -0
- data/lib/ji2p/server/http.rb +69 -0
- data/lib/ji2p/server/http_server.rb +37 -0
- data/lib/ji2p/server/initializer.rb +4 -0
- data/lib/ji2p/server/models/base_record.rb +7 -0
- data/lib/ji2p/server/models/keypair.rb +32 -0
- data/lib/ji2p/server/models/tunnel.rb +4 -0
- data/lib/ji2p/server/models.rb +9 -0
- data/lib/ji2p/server.rb +6 -0
- data/lib/ji2p/startup/bootstrap.rb +60 -0
- data/lib/ji2p/startup/router_manager.rb +21 -0
- data/lib/ji2p/startup.rb +12 -0
- data/lib/ji2p/version.rb +3 -0
- data/lib/ji2p.rb +19 -0
- metadata +299 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
require 'java'
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
module Ji2p::Control
|
7
|
+
class TunnelManager
|
8
|
+
@@tunnelctrl = nil
|
9
|
+
include_package 'net.i2p'
|
10
|
+
include_package 'net.i2p.i2ptunnel'
|
11
|
+
include_package 'net.i2p.client'
|
12
|
+
|
13
|
+
def self.context
|
14
|
+
I2PAppContext.getGlobalContext
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.startTunnelWithConfig conf, createPrivKey = false
|
18
|
+
unless ['client','httpclient','server','httpserver','sockstunnel'].include? conf['type']
|
19
|
+
raise ArgumentError, 'Invalid i2p tunnel type!', caller
|
20
|
+
end
|
21
|
+
tctrl = TunnelController.new conf, '', createPrivKey
|
22
|
+
TunnelCtrl.new tctrl, conf
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.createNewConfig hash = Hash.new
|
26
|
+
props = java.util.Properties.new
|
27
|
+
dfl = {
|
28
|
+
'option.maxPosts'=>'3',
|
29
|
+
'option.i2cp.destination.sigType'=>'EdDSA_SHA512_Ed25519',
|
30
|
+
'option.i2p.streaming.limitAction'=>'http',
|
31
|
+
'description'=>'jruby-tunnel',
|
32
|
+
'interface'=>'127.0.0.1',
|
33
|
+
'type'=>'httpserver',
|
34
|
+
'option.outbound.quantity'=>'4',
|
35
|
+
'option.inbound.quantity'=>'4',
|
36
|
+
'option.postBanTime'=>'1800',
|
37
|
+
'targetPort'=>'8000',
|
38
|
+
'option.postTotalBanTime'=>'600',
|
39
|
+
'i2cpHost'=>'127.0.0.1',
|
40
|
+
'option.postCheckTime'=>'300',
|
41
|
+
'option.i2p.streaming.maxConnsPerHour'=>'40',
|
42
|
+
'option.shouldBundleReplyInfo'=>'false',
|
43
|
+
'option.outbound.length'=>'1',
|
44
|
+
'targetHost'=>'127.0.0.1',
|
45
|
+
'option.inbound.length'=>'1',
|
46
|
+
'i2cpPort'=>'7654',
|
47
|
+
'persistentClientKey'=>'true',
|
48
|
+
'option.maxTotalPosts'=>'10',
|
49
|
+
'option.i2p.streaming.maxConnsPerDay'=>'100',
|
50
|
+
'option.i2p.streaming.maxTotalConnsPerMinute'=>'25',
|
51
|
+
'option.i2p.streaming.maxConnsPerMinute'=>'15',
|
52
|
+
'name'=>'jruby-tunnel',
|
53
|
+
'option.i2p.streaming.maxConcurrentStreams'=>'20',
|
54
|
+
'privKeyFile'=>'kake.dat',
|
55
|
+
'listenPort'=>'8000'
|
56
|
+
}
|
57
|
+
merged = dfl.merge(hash)
|
58
|
+
merged.keys.each { |k| props[k.to_s] = merged[k].to_s }
|
59
|
+
props
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/ji2p/control.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Ji2p
|
4
|
+
module Control
|
5
|
+
autoload :ClientManager, File.expand_path('control/client_manager.rb', __dir__)
|
6
|
+
autoload :Dest, File.expand_path('control/dest.rb', __dir__)
|
7
|
+
autoload :Keypair, File.expand_path('control/keypair.rb', __dir__)
|
8
|
+
autoload :TunnelManager, File.expand_path('control/tunnel_manager.rb', __dir__)
|
9
|
+
|
10
|
+
def self.unique_id
|
11
|
+
Digest::SHA1.hexdigest([Time.now, rand].join)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'rack'
|
3
|
+
require 'puma'
|
4
|
+
require 'faye/websocket'
|
5
|
+
|
6
|
+
module Ji2p::Server
|
7
|
+
class Api
|
8
|
+
def initialize
|
9
|
+
configure { set :server, :puma }
|
10
|
+
|
11
|
+
Faye::WebSocket.load_adapter('puma')
|
12
|
+
@puma = Rack::Handler.get('puma')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Ji2p::Server
|
4
|
+
module Database
|
5
|
+
@@connections = Hash.new
|
6
|
+
@@default_connection = nil
|
7
|
+
|
8
|
+
def self.connect! db=':memory:', db_type='sqlite3'
|
9
|
+
conn = ActiveRecord::Base.establish_connection(database: db, adapter: db_type)
|
10
|
+
key = "#{db}/#{db_type}/#{Ji2p::Control.unique_id.to_s}"
|
11
|
+
@@connections[key] = conn
|
12
|
+
@@default_connection = conn if @@default_connection.nil?
|
13
|
+
define_state_schema!
|
14
|
+
conn
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.connect_with_local_path! name
|
18
|
+
java_import 'net.i2p.I2PAppContext'
|
19
|
+
ctx = Java::NetI2p::I2PAppContext.getGlobalContext
|
20
|
+
path = File.join ctx.getConfigDir.toString, name
|
21
|
+
connect! path
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.flush
|
25
|
+
@@default_connection.flush
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.default
|
29
|
+
@@default_connection
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.is_connected?
|
33
|
+
get_connections.size > 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.get_connections
|
37
|
+
@@connections
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.define_state_schema! b_force=false
|
41
|
+
ActiveRecord::Schema.define do
|
42
|
+
create_table :keypairs, force: b_force do |t|
|
43
|
+
t.string :strid
|
44
|
+
t.string :name
|
45
|
+
t.text :destination
|
46
|
+
t.string :base32
|
47
|
+
t.text :private_key_data
|
48
|
+
t.json :metadata
|
49
|
+
t.timestamps
|
50
|
+
end unless ActiveRecord::Base.connection.table_exists? 'keypairs' or b_force
|
51
|
+
create_table :tunnels, force: b_force do |t|
|
52
|
+
t.string :name
|
53
|
+
t.text :description
|
54
|
+
t.json :metadata
|
55
|
+
t.references :keypair
|
56
|
+
t.string :tunnel_type
|
57
|
+
t.integer :listen_port
|
58
|
+
t.integer :target_port
|
59
|
+
t.string :listen_interface
|
60
|
+
t.string :target_host
|
61
|
+
t.timestamps
|
62
|
+
end unless ActiveRecord::Base.connection.table_exists? 'tunnels' or b_force
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module Ji2p::Server
|
4
|
+
class HTTP
|
5
|
+
VERSION = "HTTP/1.1" unless defined? VERSION
|
6
|
+
CRLF = "\r\n" unless defined? CRLF
|
7
|
+
|
8
|
+
def initialize(socket, application)
|
9
|
+
@socket = socket
|
10
|
+
@application = application
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse
|
14
|
+
matches = /\A(?<method>\S+)\s+(?<uri>\S+)\s+(?<version>\S+)#{CRLF}\Z/.match(@socket.readline)
|
15
|
+
uri = URI.parse(matches[:uri])
|
16
|
+
|
17
|
+
env = {
|
18
|
+
"rack.errors" => $stderr,
|
19
|
+
"rack.version" => Rack::VERSION,
|
20
|
+
"rack.url_scheme" => uri.scheme || "http",
|
21
|
+
"REQUEST_METHOD" => matches[:method],
|
22
|
+
"REQUEST_URI" => matches[:uri],
|
23
|
+
"HTTP_VERSION" => matches[:version],
|
24
|
+
"QUERY_STRING" => uri.query || "",
|
25
|
+
"SERVER_PORT" => uri.port || 80,
|
26
|
+
"SERVER_NAME" => uri.host || "localhost",
|
27
|
+
"PATH_INFO" => uri.path || "",
|
28
|
+
"SCRIPT_NAME" => "",
|
29
|
+
}
|
30
|
+
|
31
|
+
while matches = /\A(?<key>[^:]+):\s*(?<value>.+)#{CRLF}\Z/.match(hl = @socket.readline)
|
32
|
+
case matches[:key]
|
33
|
+
when Rack::CONTENT_TYPE then env["CONTENT_TYPE"] = matches[:value]
|
34
|
+
when Rack::CONTENT_LENGTH then env["CONTENT_LENGTH"] = Integer(matches[:value])
|
35
|
+
else env["HTTP_" + matches[:key].tr("-", "_").upcase] ||= matches[:value]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
env["rack.input"] = StringIO.new(@socket.read(env["CONTENT_LENGTH"] || 0))
|
40
|
+
|
41
|
+
return env #.map { |_,v| String.new v }
|
42
|
+
end
|
43
|
+
|
44
|
+
def handle
|
45
|
+
env = parse
|
46
|
+
|
47
|
+
status, headers, body = @application.call(env)
|
48
|
+
|
49
|
+
time = Time.now.httpdate
|
50
|
+
|
51
|
+
@socket.write "#{env['HTTP_VERSION']} #{status} #{Rack::Utils::HTTP_STATUS_CODES.fetch(status.to_i) { 'UNKNOWN' }}#{CRLF}"
|
52
|
+
@socket.write "Date: #{time}#{CRLF}"
|
53
|
+
@socket.write "Connection: close#{CRLF}"
|
54
|
+
|
55
|
+
headers.each do |key, value|
|
56
|
+
@socket.write "#{key}: #{value}#{CRLF}"
|
57
|
+
end
|
58
|
+
|
59
|
+
@socket.write(CRLF)
|
60
|
+
|
61
|
+
body.each do |chunk|
|
62
|
+
@socket.write(chunk)
|
63
|
+
end
|
64
|
+
|
65
|
+
Ji2p.logger.info("[#{time}] '#{env["REQUEST_METHOD"]} #{env["REQUEST_URI"]} #{env["HTTP_VERSION"]}' #{status}")
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'http.rb'
|
2
|
+
|
3
|
+
module Ji2p::Server
|
4
|
+
class HttpServer
|
5
|
+
|
6
|
+
def initialize(application, socket)
|
7
|
+
@application = application
|
8
|
+
@socket = socket
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
loop do
|
13
|
+
begin
|
14
|
+
monitor
|
15
|
+
rescue Interrupt
|
16
|
+
Ji2p.logger.log("INTERRUPTED")
|
17
|
+
return
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def monitor
|
23
|
+
#selections, = IO.select(@sockets)
|
24
|
+
#io, = selections
|
25
|
+
io = @socket
|
26
|
+
|
27
|
+
begin
|
28
|
+
socket = io.accept
|
29
|
+
http = Ji2p::Server::HTTP::new(socket, @application)
|
30
|
+
http.handle
|
31
|
+
ensure
|
32
|
+
socket.close
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Ji2p::Server::Models
|
5
|
+
Ji2p::Control::Keypair.class_eval do
|
6
|
+
def to_activerecord
|
7
|
+
row = Ji2p::Server::Models::Keypair.new
|
8
|
+
row.destination = @dest.base64
|
9
|
+
row.base32 = @dest.base32
|
10
|
+
row.private_key_data = Base64.encode64(@data)
|
11
|
+
row
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def write_dummy_stream obj
|
17
|
+
s = StringIO.new
|
18
|
+
obj.writeBytes(s.to_outputstream)
|
19
|
+
Base64.encode64 s.string
|
20
|
+
end
|
21
|
+
end
|
22
|
+
class Keypair < BaseRecord
|
23
|
+
|
24
|
+
def pk_data
|
25
|
+
Base64.decode64(private_key_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
def getKeypairInstance
|
29
|
+
Ji2p::Control::Keypair.load_from_stream! StringIO.new(pk_data)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Ji2p::Server
|
4
|
+
module Models
|
5
|
+
autoload :BaseRecord, File.expand_path('models/base_record.rb', __dir__)
|
6
|
+
autoload :Keypair, File.expand_path('models/keypair.rb', __dir__)
|
7
|
+
autoload :Tunnel, File.expand_path('models/tunnel.rb', __dir__)
|
8
|
+
end
|
9
|
+
end
|
data/lib/ji2p/server.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module Ji2p::Startup
|
4
|
+
java_import java.lang.ClassLoader
|
5
|
+
java_import java.lang.System
|
6
|
+
|
7
|
+
class Bootstrap
|
8
|
+
def initialize defaults={'i2p.dir.config' => TMPDIR}
|
9
|
+
@defaults = defaults
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_system_property key, value
|
13
|
+
System.setProperty key.to_s, value.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_system_property value
|
17
|
+
System.getProperty[value.to_s]
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_jars
|
21
|
+
java_import java.lang.Thread
|
22
|
+
java_import java.net.URL
|
23
|
+
cl = Thread.currentThread.getContextClassLoader
|
24
|
+
dirname = System.getProperties['i2p.dir.base']
|
25
|
+
Dir["#{dirname}/lib/**.jar"].each do |jar|
|
26
|
+
u = Java::JavaNet::URL.new "file://#{jar}"
|
27
|
+
cl.addURL u
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def i2p_loaded?
|
32
|
+
java_import java.lang.Thread
|
33
|
+
cl = Thread.currentThread.getContextClassLoader
|
34
|
+
cl.getURLs.select { |item| item.to_s.include? 'i2p.jar' }.size > 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_and_set_props!
|
38
|
+
if System.getProperties['i2p.dir.base'].nil?
|
39
|
+
unless ENV['I2PDIR'].nil?
|
40
|
+
System.setProperty 'i2p.dir.base', ENV['I2PDIR'].to_s
|
41
|
+
else
|
42
|
+
raise ArgumentError, 'The system property i2p.dir.base is missing!', caller if @defaults['i2p.dir.base'].nil?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
if System.getProperties['i2p.dir.config'].nil?
|
46
|
+
raise ArgumentError, 'The system property i2p.dir.config is missing!', caller if @defaults['i2p.dir.config'].nil?
|
47
|
+
System.setProperty 'i2p.dir.config', @defaults['i2p.dir.config']
|
48
|
+
end
|
49
|
+
System.setProperty 'java.awt.headless', 'true' if System.getProperties['java.awt.headless'].nil?
|
50
|
+
System.setProperty 'java.library.path', "#{System.getProperties['i2p.dir.base']}/lib" if System.getProperties['java.library.path'].nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
def boot!
|
54
|
+
check_and_set_props!
|
55
|
+
load_jars unless i2p_loaded?
|
56
|
+
RouterManager.start_router!
|
57
|
+
RouterManager.router_context
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module Ji2p::Startup
|
4
|
+
class RouterManager
|
5
|
+
@@router = nil
|
6
|
+
include_package 'net.i2p.router'
|
7
|
+
|
8
|
+
def self.start_router!
|
9
|
+
@@router = RouterLaunch.main ARGV if @@router.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.router_context
|
13
|
+
RouterContext.getCurrentContext
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get_leases
|
17
|
+
ctx = RouterManager.router_context
|
18
|
+
ctx.netDb.get_leases.to_a
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ji2p/startup.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Ji2p
|
2
|
+
module Startup
|
3
|
+
autoload :Bootstrap, File.expand_path('startup/bootstrap.rb', __dir__)
|
4
|
+
autoload :RouterManager, File.expand_path('startup/router_manager.rb', __dir__)
|
5
|
+
|
6
|
+
TMPDIR = File.expand_path('../../tmp', __dir__) unless defined? TMPDIR
|
7
|
+
|
8
|
+
def self.tmp_dir
|
9
|
+
TMPDIR
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/ji2p/version.rb
ADDED
data/lib/ji2p.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'active_support/dependencies'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module Ji2p
|
5
|
+
require_relative 'ji2p/version.rb'
|
6
|
+
autoload :Cluster, File.expand_path('ji2p/cluster.rb', __dir__)
|
7
|
+
autoload :Control, File.expand_path('ji2p/control.rb', __dir__)
|
8
|
+
autoload :Server, File.expand_path('ji2p/server.rb', __dir__)
|
9
|
+
autoload :Startup, File.expand_path('ji2p/startup.rb', __dir__)
|
10
|
+
ActiveSupport::Dependencies.autoload_paths << __dir__
|
11
|
+
Dir.glob('**/').each do |dir|
|
12
|
+
ActiveSupport::Dependencies.autoload_paths << File.expand_path(dir, __dir__)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.logger
|
16
|
+
@logger ||= Logger.new(STDOUT)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|