em-udp-proxy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'eventmachine'
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.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -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
@@ -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
+