em-udp-proxy 0.1.0
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.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/README +12 -0
- data/Rakefile +2 -0
- data/bin/em-udp-proxy +23 -0
- data/em-udp-proxy.gemspec +18 -0
- data/lib/udp_proxy.rb +30 -0
- data/lib/udp_proxy/client.rb +39 -0
- data/lib/udp_proxy/server.rb +14 -0
- metadata +73 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/
|
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
EventMachine based UDP proxy.
|
2
|
+
|
3
|
+
Example usage:
|
4
|
+
|
5
|
+
> em-udp-proxy -a 127.0.0.1 -p 5001 -A 192.168.1.1 -P 5001
|
6
|
+
|
7
|
+
Starts the proxy binded to 127.0.0.1 with port 5001 and forwards traffic to/from 192.168.1.1 on port 5001.
|
8
|
+
|
9
|
+
TODO:
|
10
|
+
1. More documentation :-)
|
11
|
+
2. Remove Client objects for inactive clients (after certain threshold).
|
12
|
+
3. Add some way to get stats from it.
|
data/Rakefile
ADDED
data/bin/em-udp-proxy
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require File.expand_path('../lib/udp_proxy.rb', File.dirname(__FILE__))
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: em-udp-proxy [options]"
|
10
|
+
|
11
|
+
opts.on('-a', '--address ADDRESS', String, "Address to use") { |value| options[:address] = value }
|
12
|
+
opts.on('-p', '--port PORT', Numeric, "Listening port") { |value| options[:port] = value }
|
13
|
+
opts.on('-A','--remote-address ADDRESS', String, "Remote address to connect to") { |value| options[:remote_address] = value}
|
14
|
+
opts.on('-P','--remote-port PORT', Numeric, "Remote port to connect to") { |value| options[:remote_port] = value}
|
15
|
+
|
16
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
17
|
+
puts opts
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
end.parse!
|
21
|
+
|
22
|
+
Kernel.abort "Missing arguments, see --help for details." if options.length < 4
|
23
|
+
UDPProxy.start options[:address], options[:port], options[:remote_address], options[:remote_port]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "em-udp-proxy"
|
5
|
+
s.version = "0.1.0"
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Arik Fraimovich"]
|
8
|
+
s.email = ["arik@arikfr.com"]
|
9
|
+
s.homepage = "http://github.com/arikfr/em-udp-proxy"
|
10
|
+
s.summary = %q{EventMachine UDP Proxy}
|
11
|
+
s.description = s.summary
|
12
|
+
|
13
|
+
s.add_dependency "eventmachine"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
end
|
data/lib/udp_proxy.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'syslog'
|
3
|
+
require 'socket'
|
4
|
+
require File.expand_path('./udp_proxy/server.rb', File.dirname(__FILE__))
|
5
|
+
require File.expand_path('./udp_proxy/client.rb', File.dirname(__FILE__))
|
6
|
+
|
7
|
+
module UDPProxy
|
8
|
+
def self.start(ip, port, relay_ip, relay_port)
|
9
|
+
start_logger
|
10
|
+
|
11
|
+
EM::run do
|
12
|
+
Syslog.notice "Starting proxy on: #{ip}:#{port}"
|
13
|
+
EM::open_datagram_socket ip, port, UDPProxy::Server, ip, relay_ip, relay_port
|
14
|
+
trap("TERM") { stop }
|
15
|
+
trap("INT") { stop }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.stop
|
20
|
+
Syslog.warning "Stopping proxy..."
|
21
|
+
EventMachine.stop
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def self.start_logger
|
26
|
+
Syslog.open('UDP-Proxy')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# UDPProxy.start "127.0.0.1", 50001, "127.0.0.1", 50000
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# TODO: periodically kill all dead connections
|
2
|
+
module UDPProxy
|
3
|
+
class Client < EM::Connection
|
4
|
+
attr_accessor :client_ip, :client_port
|
5
|
+
|
6
|
+
def initialize(client_ip, client_port, server)
|
7
|
+
@client_ip, @client_port = client_ip, client_port
|
8
|
+
@server = server
|
9
|
+
end
|
10
|
+
|
11
|
+
def receive_data(data)
|
12
|
+
port, ip = Socket.unpack_sockaddr_in(get_peername)
|
13
|
+
@server.send_datagram(data, client_ip, client_port)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Clients
|
18
|
+
def initialize(server, address)
|
19
|
+
@address = address
|
20
|
+
@clients = {}
|
21
|
+
@server = server
|
22
|
+
end
|
23
|
+
|
24
|
+
def client(ip, port)
|
25
|
+
@clients[key(ip, port)] || @clients[key(ip,port)] = create_client(ip, port)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def key(ip, port)
|
30
|
+
"#{ip}:#{port}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_client(ip, port)
|
34
|
+
Syslog.notice "Creating new client for #{ip}:#{port}"
|
35
|
+
client = EM::open_datagram_socket @address, 0, Client, ip, port, @server
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module UDPProxy
|
2
|
+
class Server < EM::Connection
|
3
|
+
def initialize(address, relay_ip, relay_port)
|
4
|
+
@relay_ip, @relay_port = relay_ip, relay_port
|
5
|
+
@clients = Clients.new(self, address)
|
6
|
+
end
|
7
|
+
|
8
|
+
def receive_data(data)
|
9
|
+
port, ip = Socket.unpack_sockaddr_in(get_peername)
|
10
|
+
client = @clients.client(ip, port)
|
11
|
+
client.send_datagram(data, @relay_ip, @relay_port)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: em-udp-proxy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Arik Fraimovich
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-03-06 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: eventmachine
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
description: EventMachine UDP Proxy
|
27
|
+
email:
|
28
|
+
- arik@arikfr.com
|
29
|
+
executables:
|
30
|
+
- em-udp-proxy
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- .gitignore
|
37
|
+
- Gemfile
|
38
|
+
- README
|
39
|
+
- Rakefile
|
40
|
+
- bin/em-udp-proxy
|
41
|
+
- em-udp-proxy.gemspec
|
42
|
+
- lib/udp_proxy.rb
|
43
|
+
- lib/udp_proxy/client.rb
|
44
|
+
- lib/udp_proxy/server.rb
|
45
|
+
homepage: http://github.com/arikfr/em-udp-proxy
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.10
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: EventMachine UDP Proxy
|
72
|
+
test_files: []
|
73
|
+
|