GithubHelp home page GithubHelp logo

bane's People

Contributors

danielwellman avatar trevoke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

bane's Issues

Command line script does not display all Behaviors when no arguments present in Ruby 1.8.6

Running "bane" with no arguments should print all the known behaviors and a usage message, but it fails in Ruby 1.8.6.

$ ruby --version
ruby 1.8.6 (2008-03-03 patchlevel 114) [x86_64-linux]

$ bane
Usage: bane port_number

All behaviors:
/usr/lib64/ruby/gems/1.8/gems/bane-0.1.0/bin/bane:10: wrong argument type Symbol (expected Proc) (TypeError)
from /usr/bin/bane:19:in `load'
from /usr/bin/bane:19

Provide option to listen on 0.0.0.0

Bane currently defaults to listening to only connections from localhost (127.0.0.1). It would be helpful if Bane could also listen on all incoming connections, even from remote machines (0.0.0.0).

It's not clear to me if 0.0.0.0 should be the new default or enabled via a command-line option. Listening to all incoming connections by default may be a security concern, but I'm not entirely sure. While it means malicious parties could connect to Bane, the types of responses Bane sends are meant to be malicious themselves (e.g. never hanging up the connection). If there are security problems with the underlying TCP server (currently Ruby's GServer) then these will be publicly exposed.

Add full socket listen queue behavior

One behavior suggested in Release It! is:

The request can sit in a listen queue until the caller times out

After reading Jesse Storimer's "Working with TCP Sockets" book, I believe this is possible to implement entirely in Ruby.

See the video: What happens with the listen backlog is full?

Also see the second man page for listen: man 2 listen and note the backlog parameter.

Implementation Idea

My proposed idea is to create a TCPServer on the given port, listen with a queue of one, and then have Bane immediately connect to that socket -- effectively filling the listen queue. There may be some other way to simulate this, but I'm not yet sure.

Note that I first thought we could pass in zero as the backlog size, but as far as I can tell, passing in zero does not necessarily mean "no backlog", but rather "implementation specific" behavior. See one example man page for listen.

Impact to Bane architecture

I suspect this will require changes to BehaviorServer, or the creation of some different types of BehaviorServers. Specifically, BehaviorServer currently is a GServer, but from what I see of the GServer source code, it supports a maxConnections option. However, it looks to me like this does not actually specify a backlog size to listen(). Instead, it looks to me like GServer keeps track of the open connection count, and waits until the count is below the maxConnections option. I'm not exactly sure what this will do, but I suspect it will not actually use the backlog like we'd like.

To do this, I suspect this Behavior will need to specify startup options for the server - which means making the Behaviors more coupled to the server. That is, right now behaviors cannot control the socket-level options of a server, they are only notified when a connection has been established by the BehaviorServer. To implement the low-level TCP packet-munging I'd like for the other lower level behaviors (e.g. "The remote end can send nothing but RESET packets") this may be required anyway.

Protect "unqualified_name" from name collision

extensions.rb defines the method unqualified_name on the Class object. In insolation, this is fine, however if Bane is used by other libraries (say, in integration tests) this method name might clash with another implementation of unqualified_name. In particular, I'm concerned about ActiveSupport which is widely used.

To use a name which might be more familiar to ActiveSupport, we could define

class.demodulize_name

(which would be defined on Module)

This uses a name which is probably familiar to anyone who uses ActiveSupport, since it has a 'demodulize' method on String.

As a bonus, 'demodulize_name' is also unused in ActiveSupport -- and didn't turn up any Google search results when we looked today.

Support Windows

Bane does not work when installed on Windows machines.

Bane only ships with a "bin/bane" executable. For Windows, this needs a corresponding extension that the OS will recognize.

To do this, it seems like extracting the launcher code in bin/bane into a class would avoid duplicating the logic in the Windows and Unix/Mac launcher script.

Integration Tests fail in Ruby 1.9.1 on Ubuntu

The integration tests fail on Ruby 1.9.1 (as tested in Ubuntu) with a "Port already in use" error.

It appears that the first integration test passes and sends the stop request to the Bane servers. However the port is still in use by the time the second integration test attempts to start a new server on the same port. As a first attempt, putting in a "sleep 1" in setup fixes the problem, which makes me think there is a problem in how the threads are stopped in Bane::Launcher.

This behavior is not present in Ruby 1.8.6 or 1.8.7 on the same installation of Ubuntu (using rvm).

See the stack trace below for an example of the failure:

wellman@wellman-uvm:~/dev/ruby/bane$ ruby test/bane/integration_test.rb
Loaded suite test/bane/integration_test
Started
.E
Finished in 0.008375 seconds.

  1. Error:
    test_uses_specified_port_and_server(BaneIntegrationTest):
    RuntimeError: Port already in use: 127.0.0.1:4000!
    internal:prelude:8:in synchronize' /home/wellman/dev/ruby/bane/lib/bane/configuration.rb:25:instart'
    /home/wellman/dev/ruby/bane/lib/bane/configuration.rb:11:in block in start' /home/wellman/dev/ruby/bane/lib/bane/configuration.rb:10:inmap'
    /home/wellman/dev/ruby/bane/lib/bane/configuration.rb:10:in start' /home/wellman/dev/ruby/bane/lib/bane/launcher.rb:12:instart'
    test/bane/integration_test.rb:33:in run_server_with' test/bane/integration_test.rb:9:intest_uses_specified_port_and_server'

2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
wellman@wellman-uvm:~/dev/ruby/bane$

Intermittent BaneIntegrationTest failures

The second and third integration tests occasionally fail due to attempting to start a server as the test port is already in use.

This appears to be happening because the Bane BehaviorServers (a.k.a. GServer) do not stop immediately, and new servers are being started on the same port. There is a race condition between stopping and starting the server.

Upon investigation, it appears that GServer's stop instance method does not stop the server immediately (it is a graceful shutdown, eventually stopping the server), whereas GServer's stop class method does.

  1. Error:
    test_uses_behavior_options(BaneIntegrationTest):
    RuntimeError: Port already in use: 127.0.0.1:4000!
    internal:prelude:10:in synchronize' /home/vagrant/builds/danielwellman/bane/lib/bane/launcher.rb:11:inblock in art'
    /home/vagrant/builds/danielwellman/bane/lib/bane/launcher.rb:11:in each' /home/vagrant/builds/danielwellman/bane/lib/bane/launcher.rb:11:instart'
    /home/vagrant/builds/danielwellman/bane/test/bane/integration_test.rb:45:in un_server_with'
    /home/vagrant/builds/danielwellman/bane/test/bane/integration_test.rb:21:in est_uses_behavior_options'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p194/gems/mocha-0.12.lib/mocha/monkey_patching/mini_test/version_230_to_2101.rb:28:in `run'

  2. Error:
    test_uses_specified_port_and_server(BaneIntegrationTest):
    RuntimeError: Port already in use: 127.0.0.1:4000!
    internal:prelude:10:in synchronize' /home/vagrant/builds/danielwellman/bane/lib/bane/launcher.rb:11:inblock in art'
    /home/vagrant/builds/danielwellman/bane/lib/bane/launcher.rb:11:in each' /home/vagrant/builds/danielwellman/bane/lib/bane/launcher.rb:11:instart'
    /home/vagrant/builds/danielwellman/bane/test/bane/integration_test.rb:45:in un_server_with'
    /home/vagrant/builds/danielwellman/bane/test/bane/integration_test.rb:9:in est_uses_specified_port_and_server'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p194/gems/mocha-0.12.2/lib/mocha/monkey_patching/mini_test/version_230_to_2101.rb:28:in `run'

Remove Ruby 1.8.7 support

With Ruby 1.8.7 now retired, shall we remove support for this version from Bane?

This would mean removing the compatibility.rb extensions which add 1.9-era methods to String and Symbol.

Integration tests fail due to Telnet#close error in 1.9.2

In ruby 1.9.2 p0, the tests which use Telnet in BaneIntegrationTest fail due to a NoMethodError:

daniel-wellmans-macbook:bane wellman$ rvm 1.9.2
daniel-wellmans-macbook:bane wellman$ ruby test/bane/integration_test.rb 
Loaded suite test/bane/integration_test
Started
.EE
Finished in 0.052258 seconds.

  1) Error:
test_uses_behavior_options(BaneIntegrationTest):
NoMethodError: undefined method `close' for #<Net::Telnet:0x000001011d7a70>
    test/bane/integration_test.rb:64:in `ensure in telnet_to'
    test/bane/integration_test.rb:64:in `telnet_to'
    test/bane/integration_test.rb:23:in `block in test_uses_behavior_options'
    test/bane/integration_test.rb:47:in `run_server_with'
    test/bane/integration_test.rb:22:in `test_uses_behavior_options'

  2) Error:
test_uses_specified_port_and_server(BaneIntegrationTest):
RuntimeError: Port already in use: 127.0.0.1:4000!
    <internal:prelude>:10:in `synchronize'
    /Users/wellman/dev/ruby/bane/lib/bane/launcher.rb:13:in `block in start'
    /Users/wellman/dev/ruby/bane/lib/bane/launcher.rb:11:in `each'
    /Users/wellman/dev/ruby/bane/lib/bane/launcher.rb:11:in `start'
    test/bane/integration_test.rb:46:in `run_server_with'
    test/bane/integration_test.rb:10:in `test_uses_specified_port_and_server'

3 tests, 1 assertions, 0 failures, 2 errors, 0 skips

ThreadError on SIGINT using Ruby 2.0.0

When running bane on the command line using Ruby 2.0, sending a SIGINT causes an exception to be thrown:

joe@warpaint:/dev/bane$ ruby -v
ruby 2.0.0dev (2012-12-01 trunk 38126) [i686-linux]
joe@warpaint:
/dev/bane$ ./bin/bane 8080
[Sun Dec 30 12:43:11 2012] CloseImmediately 127.0.0.1:8080 start
[Sun Dec 30 12:43:11 2012] CloseAfterPause 127.0.0.1:8081 start
[Sun Dec 30 12:43:11 2012] FixedResponse 127.0.0.1:8082 start[Sun Dec 30 12:43:11 2012] NewlineResponse 127.0.0.1:8084 start[Sun Dec 30 12:43:11 2012] FixedResponseForEachLine 127.0.0.1:8083 start
[Sun Dec 30 12:43:11 2012] NewlineResponseForEachLine 127.0.0.1:8085 start

[Sun Dec 30 12:43:11 2012] SlowResponseForEachLine 127.0.0.1:8089 start
[Sun Dec 30 12:43:11 2012] RandomResponseForEachLine 127.0.0.1:8087 start
[Sun Dec 30 12:43:11 2012] SlowResponse 127.0.0.1:8088 start
[Sun Dec 30 12:43:11 2012] RandomResponse 127.0.0.1:8086 start

[Sun Dec 30 12:43:11 2012] NeverRespond 127.0.0.1:8090 start
[Sun Dec 30 12:43:11 2012] DelugeResponse 127.0.0.1:8091 start
[Sun Dec 30 12:43:11 2012] DelugeResponseForEachLine 127.0.0.1:8092 start
[Sun Dec 30 12:43:11 2012] HttpRefuseAllCredentials 127.0.0.1:8093 start
^C[Sun Dec 30 12:43:12 2012] CloseImmediately 127.0.0.1:8080 stop
[Sun Dec 30 12:43:12 2012] CloseAfterPause 127.0.0.1:8081 stop
[Sun Dec 30 12:43:12 2012] HttpRefuseAllCredentials 127.0.0.1:8093 stop[Sun Dec 30 12:43:12 2012] DelugeResponse 127.0.0.1:8091 stop[Sun Dec 30 12:43:12 2012] SlowResponseForEachLine 127.0.0.1:8089 stop[Sun Dec 30 12:43:12 2012] SlowResponse 127.0.0.1:8088 stop[Sun Dec 30 12:43:12 2012] NewlineResponseForEachLine 127.0.0.1:8085 stop[Sun Dec 30 12:43:12 2012] FixedResponseForEachLine 127.0.0.1:8083 stop[Sun Dec 30 12:43:12 2012] FixedResponse 127.0.0.1:8082 stop[Sun Dec 30 12:43:12 2012] NewlineResponse 127.0.0.1:8084 stop[Sun Dec 30 12:43:12 2012] NeverRespond 127.0.0.1:8090 stop

[Sun Dec 30 12:43:12 2012] RandomResponse 127.0.0.1:8086 stop
[Sun Dec 30 12:43:12 2012] DelugeResponseForEachLine 127.0.0.1:8092 stop

[Sun Dec 30 12:43:12 2012] RandomResponseForEachLine 127.0.0.1:8087 stop

/home/joe/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:116:in synchronize': can't be called from trap context (ThreadError) from /home/joe/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:116:instop'
from /home/joe/dev/bane/lib/bane/launcher.rb:20:in block in stop' from /home/joe/dev/bane/lib/bane/launcher.rb:19:ineach'
from /home/joe/dev/bane/lib/bane/launcher.rb:19:in stop' from ./bin/bane:22:inblock in

'
from /home/joe/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:140:in call' from /home/joe/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:140:injoin'
from /home/joe/.rvm/rubies/ruby-2.0.0-preview2/lib/ruby/2.0.0/gserver.rb:140:in join' from /home/joe/dev/bane/lib/bane/launcher.rb:15:inblock in join'
from /home/joe/dev/bane/lib/bane/launcher.rb:15:in each' from /home/joe/dev/bane/lib/bane/launcher.rb:15:injoin'
from ./bin/bane:23:in `'
joe@warpaint:~/dev/bane$ ^C

Further investigation revealed the following discussion:

https://bugs.ruby-lang.org/issues/6416#change-33951

and subsequent patch:

https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/37852

If I'm reading this correctly, this patch was submitted to reduce the chances of deadlocking a system upon SIGINT.

I'd like to submit a patch to this after a little more research. Simply changing a line in the bane executable as follows:

trap("SIGINT") { exit! }

will keep the exception from being thrown but it's unclear if that's sufficient to clean up the threads. Also, it would be good to get a test around this behavior (currently all tests pass under Ruby 2.0).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.