diff --git a/.gitignore b/.gitignore index 040e2c3..56f8934 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,8 @@ /shard.lock .DS_Store + +*.swp +*.swo + +/sox diff --git a/README.md b/README.md index 347f8f1..05cf6a4 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ end #### Basic Client -`Sox::Client` functions almost like the Crystal (HTTP::Client)[https://crystal-lang.org/api/latest/HTTP/Client.html] +`Sox::Client` functions almost like the Crystal [HTTP::Client](https://crystal-lang.org/api/latest/HTTP/Client.html) ```crystal client = Sox::Client.new("www.example.com", host_addr: "127.0.0.1", host_port: 1080) @@ -92,7 +92,7 @@ client.close #### Basic UDP -`Sox::UDP` functions almost like the Crystal (UDPSocket)[https://crystal-lang.org/api/latest/UDPSocket.html] +`Sox::UDP` functions almost like the Crystal [UDPSocket](https://crystal-lang.org/api/latest/UDPSocket.html) ```crystal server = UDPSocket.new @@ -104,14 +104,14 @@ client.connect "localhost", 9999 client.send "message" message, client_addr = server.receive -message # => "message" -client_addr # => Socket::IPAddress(127.0.0.1:50516) +puts message # => "message" +puts client_addr # => Socket::IPAddress(127.0.0.1:50516) client.close server.close ``` -you can use `Sox::Client` almost like the Crystal (HTTP::Client)[https://crystal-lang.org/api/latest/HTTP/Client.html] +you can use `Sox::Client` almost like the Crystal [HTTP::Client](https://crystal-lang.org/api/latest/HTTP/Client.html) ```crystal client = Sox::Client.new("www.example.com", host_addr: "127.0.0.1", host_port: 1080) @@ -141,7 +141,7 @@ if response.success? end ``` -### Connection using none default ports +### Connection using non-default ports Sometimes you connect to web servers or remote SOCKS servers on ports that are not default. This is built into the top level interface no having to deal with requests or connection requests directly. @@ -178,7 +178,7 @@ enable key based authentication for testing ```bash # enable key based localhost authentication -cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys +cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys ``` ### TOR diff --git a/shard.yml b/shard.yml index 1320489..0505198 100644 --- a/shard.yml +++ b/shard.yml @@ -1,4 +1,4 @@ -name: sos +name: sox version: 0.2.0 authors: diff --git a/sox b/sox deleted file mode 100755 index aaaffde..0000000 Binary files a/sox and /dev/null differ diff --git a/src/request.cr b/src/request.cr index 4d7def9..275f7c1 100644 --- a/src/request.cr +++ b/src/request.cr @@ -10,13 +10,13 @@ class Sox::Request else ip_address = Socket::IPAddress.new(addr, port) case ip_address.family - when Family::INET + when Socket::Family::INET @buffer = Bytes.new(10) @buffer[3] = ADDR_TYPE::IPV4.value ip_address.address.split(".").each_with_index { |b, i| @buffer[4 + i] = b.to_u8 } - when Family::INET6 + when Socket::Family::INET6 @buffer = Bytes.new(22) @buffer[3] = ADDR_TYPE::IPV6.value {% if flag?(:darwin) || flag?(:openbsd) || flag?(:freebsd) %} diff --git a/src/sox.cr b/src/sox.cr index 79d89c4..8e215af 100644 --- a/src/sox.cr +++ b/src/sox.cr @@ -1,6 +1,8 @@ require "socket" require "./sox/tcp/socket" +require "./sox/tcp/server" +require "./sox/udp/socket" module Sox V4 = 4_u8 @@ -39,18 +41,19 @@ module Sox case command when COMMAND::CONNECT Sox::TCP::Socket.new( - host: host, - port: port, - dns_timeout: nil, - connect_timeout: nil, - proxy_host: proxy_host, - proxy_port: proxy_port, + proxy_host, + proxy_port, + nil, # dns_timeout + nil, # connect_timeout + host_addr: host, + host_port: port, ) when COMMAND::UDP_ASSOCIATE socket = Sox::UDP::Socket.new - socket.connect host_addr, host_port + socket.connect proxy_host, proxy_port + socket when COMMAND::BIND - Sox::TCP::Server.new(host: addr, port: port) + Sox::TCP::Server.new(host: host, port: port) else raise "invalid command type" end @@ -79,8 +82,3 @@ module Sox @command == UDP_ASSOCIATE end end - -require "./connection_request.cr" -require "./connection_response.cr" -require "./request.cr" -require "./reply.cr" diff --git a/src/sox/client.cr b/src/sox/client.cr index 354cacf..677aa36 100644 --- a/src/sox/client.cr +++ b/src/sox/client.cr @@ -8,7 +8,7 @@ module Sox end class Sox::Client < HTTP::Client - def initialize(*args, @host_addr : String, @host_port : Int32) + def initialize(*args, @proxy_host : String, @proxy_port : Int32, tls : TLSContext = nil) super(*args) end @@ -17,17 +17,24 @@ class Sox::Client < HTTP::Client return socket if socket hostname = @host.starts_with?('[') && @host.ends_with?(']') ? @host[1..-2] : @host - socket = Sox.new hostname, @port + socket = Sox.new host: hostname, port: @port, proxy_host: @proxy_host, proxy_port: @proxy_port socket.read_timeout = @read_timeout if @read_timeout + socket.write_timeout = @write_timeout if @write_timeout socket.sync = false @socket = socket {% if !flag?(:without_openssl) %} if tls = @tls - tls_socket = OpenSSL::SSL::Socket::Client.new(socket, context: tls, sync_close: true, hostname: @host) - @socket = socket = tls_socket + tcp_socket = socket + begin + socket = OpenSSL::SSL::Socket::Client.new(socket, context: tls, sync_close: true, hostname: @host) + rescue exc + tcp_socket.close + raise exc + end end {% end %} - socket + + @socket = socket end end diff --git a/src/sox/tcp/socket.cr b/src/sox/tcp/socket.cr index 8b69a41..3d7a6ec 100644 --- a/src/sox/tcp/socket.cr +++ b/src/sox/tcp/socket.cr @@ -1,24 +1,29 @@ +require "../../connection_request.cr" +require "../../connection_response.cr" +require "../../request.cr" +require "../../reply.cr" + class Sox::TCP::Socket < TCPSocket - def initialize(*args, proxy_host : String, proxy_port : Int) - super(args) + def initialize(*args, host_addr : String, host_port : Int) + super(*args) connect_host - connect_remote(host: proxy_host, port: proxy_port) + connect_remote(host: host_addr, port: host_port) end private def connect_host - connection_request = ConnectionRequest.new + connection_request = Sox::ConnectionRequest.new write(connection_request.buffer) - connection_response = ConnectionResponse.new + connection_response = Sox::ConnectionResponse.new read(connection_response.buffer) connection_response end private def connect_remote(host : String, port : Int) - request = Request.new(addr: host, port: port) + request = Sox::Request.new(addr: host, port: port) write(request.buffer) - reply = Reply.new(buffer_size: request.size) + reply = Sox::Reply.new(buffer_size: request.size) read(reply.buffer) reply end