Commit Graph

29 Commits

Author SHA1 Message Date
David Wilson d6329f3446 Merge devel/290 @ 79b979ec8544ef5d8620c64068d4a42fabf50415 2019-11-02 16:46:59 +00:00
David Wilson bcca47df3c issue #533: update routing to account for DEL_ROUTE propagation race 2019-08-17 14:48:08 +01:00
David Wilson 3d72cf82e3 tests: use defer_sync() Rather than defer() + ancient sync_with_broker() 2019-08-17 14:35:31 +01:00
David Wilson 3f5ff17c8c issue #615: route a dead message to recipients when no reply is expected 2019-08-17 03:14:15 +01:00
David Wilson 0c1d882547 issue #613: must await 'exit' and 'disconnect' in wait=False test 2019-08-12 11:46:38 +01:00
David Wilson 4fa760cd21 issue #613: add tests for all the weird shutdown methods 2019-08-10 20:30:24 +01:00
David Wilson cf23d0dee6 issue #279: add one more test for max_message_size 2019-08-09 20:33:36 +01:00
David Wilson 1e3621a88b tests: fix format string error 2019-08-09 19:26:52 +01:00
David Wilson 5924af1566 [security] core: undirectional routing wasn't respected in some cases
When creating a context using Router.method(via=somechild),
unidirectional mode was set on the new child correctly, however if the
child were to call Router.method(), due to a typing mistake the new
child would start without it.

This doesn't impact the Ansible extension, as only forked tasks are
started directly by children, and they are not responsible for routing
messages.

Add test so it can't happen again.
2019-08-08 23:03:43 +01:00
David Wilson 8d1b01d8ef Refactor Stream, introduce quasi-asynchronous connect, much more
Split Stream into many, many classes

  * mitogen.parent.Connection: Handles connection setup logic only.
    * Maintain references to stdout and stderr streams.
    * Manages TimerList timer to cancel connection attempt after
      deadline
    * Blocking setup code replaced by async equivalents running on the
      broker

  * mitogen.parent.Options: Tracks connection-specific options. This
    keeps the connection class small, but more importantly, it is
    generic to the future desire to build and execute command lines
    without starting a full connection.

  * mitogen.core.Protocol: Handles program behaviour relating to events
    on a stream. Protocol performs no IO of its own, instead deferring
    it to Stream and Side. This makes testing much easier, and means
    libssh can reimplement Stream and Side to reuse MitogenProtocol

  * mitogen.core.MitogenProtocol: Guts of the old Mitogen stream
    implementtion

  * mitogen.core.BufferedWriter: Guts of the old Mitogen buffered
    transmit implementation, made generic

  * mitogen.core.DelineatedProtocol: Guts of the old IoLogger, knows how
    to split up input and pass it on to a
    on_line_received()/on_partial_line_received() callback.

  * mitogen.parent.BootstrapProtocol: Asynchronous equivalent of the old
    blocking connect code. Waits for various prompts (MITO001 etc) and
    writes the bootstrap using a BufferedWriter. On success, switches
    the stream to MitogenProtocol.

  * mitogen.core.Message: move encoding parts of MitogenProtocol out to
    Message (where it belongs) and write a bunch of new tests for
    pickling.

  * The bizarre Stream.construct() is gone now, Option.__init__ is its
    own constructor. Should fix many LGTM errors.

* Update all connection methods:  Every connection method is updated to
  use async logic, defining protocols as required to handle interactive
  prompts like in SSH or su. Add new real integration tests for at least
  doas and su.

* Eliminate manual fd management: File descriptors are trapped in file
  objects at their point of origin, and Side is updated to use file
  objects rather than raw descriptors. This eliminates a whole class of
  bugs where unrelated FDs could be closed by the wrong component. Now
  an FD's open/closed status is fused to it everywhere in the library.

* Halve file descriptor usage: now FD open/close state is tracked by
  its file object, we don't need to duplicate FDs everywhere so that
  receive/transmit side can be closed independently. Instead both sides
  back on to the same file object. Closes #26, Closes #470.

* Remove most uses of dup/dup2: Closes #256. File descriptors are
  trapped in a common file object and shared among classes. The
  remaining few uses for dup/dup2 are as close to minimal as possible.

* Introduce mitogen.parent.Process: uniform interface for subprocesses
  created either via mitogen.fork or the subprocess module. Remove all
  the crap where we steal a pid from subprocess guts. Now we use
  subprocess to manage its processes as it should be. Closes #169 by
  using the new Timers facility to poll for a slow-to-exit subprocess.

* Fix su password race: Closes #363. DelineatedProtocol naturally
  retries partially received lines, preventing the cause of the original
  race.

* Delete old blocking IO utility functions
  iter_read()/write_all()/discard_until().

Closes #26
Closes #147
Closes #169
Closes #256
Closes #363
Closes #419
Closes #470
2019-07-22 18:30:51 +01:00
David Wilson 18b984a0b4 issue #535: activate Corker on 2.4 in master too. 2019-02-17 23:12:30 +00:00
David Wilson b7f39f26cd issue #477: stop using .fork() in router_test, one small 2.4 fix. 2019-01-26 01:14:37 +00:00
David Wilson f5d9af80ef tests: some more utility function tests + flake8. 2019-01-21 19:38:23 +00:00
David Wilson fcc403cc2f core: make Receiver.to_sender() use Router.myself(). 2019-01-20 22:20:29 +00:00
David Wilson de719fa249 core: throw error on duplicate add_handler(); closes #447. 2019-01-19 08:24:24 +00:00
David Wilson cf97932fad core: dead messages have optional body, use it everywhere; closes #387. 2018-11-04 15:26:25 +00:00
David Wilson 8a0b343760 issue #406: test for FD leak after every TestCase 2018-11-03 13:28:37 +00:00
David Wilson 1cbff1011e core: send dead message if max message size exceeded; closes #405 2018-10-30 10:53:54 +00:00
David Wilson babe3eec31 issue #76: record egress context IDs
Used in a subsequent change to broadcast DEL_ROUTE to potentially
interested children.
2018-10-23 23:07:49 +01:00
David Wilson 6cbf34d5fe tests: another smattering of 3.x type/API fixes. 2018-07-07 14:55:47 +01:00
David Wilson 410016ff47 Initial Python 3.x port work.
* ansible: use unicode_literals everywhere since it only needs to be
  compatible back to 2.6.
* compat/collections.py: delete this entirely and rip out the parts of
  functools that require it.
* Introduce serializable Kwargs dict subclass that translates keys to
  Unicode on instantiation.
* enable_debug_logging() must set _v/_vv globals.
* cStringIO does not exist in 3.x.
* Treat IOLogger and LogForwarder input as latin-1.
* Avoid ResourceWarnings in first stage by explicitly closing fps.
* Fix preamble_size.py syntax errors.
2018-07-07 14:55:47 +01:00
David Wilson 356647bef4 issue #132: initial unidirectional routing mode. 2018-05-08 16:06:08 +01:00
David Wilson e63ae4768e core: support Receiver.get(thread_dead=False)
For tests.
2018-04-22 05:08:37 +01:00
David Wilson 7c88e4d013 Move _DEAD into header, autogenerate dead messages
This change blocks off 2 common scenarios where a race condition is
upgraded to a hang, when the library could internally do better.

* Since we don't know whether the receiver of a `reply_to` is expecting
  a raw or pickled message, and since in the case of a raw reply, there
  is no way to signal "dead" to the receiver, override the reply_to
  field to explicitly mark a message as dead using a special handle.

  This replaces the serialized _DEAD sentinel value with a slightly
  neater interface, in the form of the reserved IS_DEAD handle, and
  enables an important subsequent change: when a context cannot route a
  message, it can send a generic 'dead' reply back towards the message
  source, ensuring any sleeping thread is woken with ChannelError.

  The use of this field could potentially be extended later on if
  additional flags are needed, but for now this seems to suffice.

* Teach Router._invoke() to reply with a dead message when it receives a
  message for an invalid local handle.

* Teach Router._async_route() to reply with a dead message when it
  receives an unroutable message.
2018-04-22 00:17:27 +01:00
David Wilson 6670cba41c Introduce handler policy functions; closes #138.
Now you can specify a function to add_handler() that authenticates the
message header, with has_parent_authority() and is_immediate_child()
built in.
2018-03-29 21:40:33 +05:45
David Wilson 40b978c9b7 core: Fix source verification.
Previously:

* src_id could be spoofed
* auth_id was checked but the message was still delivered!
2018-03-29 20:24:54 +05:45
David Wilson fe614aa966 core: cleanup handlers on broker crash; closes #112. 2018-03-29 19:32:31 +05:45
David Wilson 1ff27ada49 Add maximum message size checks. Closes #151. 2018-03-29 18:54:55 +05:45
David Wilson afc8697288 core: Ensure add_handler() callbacks really receive _DEAD on shutdown 2018-03-19 21:58:30 +05:45