class RemoteOriginReadSession(TFTPBootstrap): """Bootstraps a L{ReadSession}, that was started remotely, - we've received a RRQ. """ timeout = (1, 3, 7) def __init__(self, remote, reader, options=None, _clock=None): TFTPBootstrap.__init__(self, remote, reader, options, _clock) self.session = ReadSession(reader, self._clock) def startProtocol(self): """Start sending an OACK datagram if we were initialized with options or start the L{ReadSession} immediately. """ self.transport.connect(*self.remote) if self.options: self.resultant_options = self.processOptions(self.options) bytes = OACKDatagram(self.resultant_options).to_wire() self.timeout_watchdog = SequentialCall.run( self.timeout[:-1], callable=self.transport.write, callable_args=[bytes], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock, ) else: self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock() def _datagramReceived(self, datagram): if datagram.opcode == OP_ACK and datagram.blocknum == 0: return self.tftp_ACK(datagram) elif self.session.started: return self.session.datagramReceived(datagram) def tftp_ACK(self, datagram): """Handle incoming ACK datagram. Hand over control to the underlying L{ReadSession}. @param datagram: ACK datagram @type datagram: L{ACKDatagram} """ if self.timeout_watchdog is not None: self.timeout_watchdog.cancel() if not self.session.started: self.applyOptions(self.session, self.resultant_options) self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock()
class LocalOriginReadSession(TFTPBootstrap): """Bootstraps a L{ReadSession}, that was originated locally, - we've requested a write to a remote server. """ def __init__(self, remote, reader, options=None, _clock=None): TFTPBootstrap.__init__(self, remote, reader, options, _clock) self.session = ReadSession(reader, self._clock) def startProtocol(self): """Connect the transport and start the L{timeout_watchdog}""" self.transport.connect(*self.remote) if self.timeout_watchdog is not None: self.timeout_watchdog.start() def _datagramReceived(self, datagram): if datagram.opcode == OP_OACK: return self.tftp_OACK(datagram) elif (datagram.opcode == OP_ACK and datagram.blocknum == 0 and not self.session.started): self.session.transport = self.transport self.session.startProtocol() if self.timeout_watchdog is not None and self.timeout_watchdog.active( ): self.timeout_watchdog.cancel() return self.session.nextBlock() elif self.session.started: return self.session.datagramReceived(datagram) def tftp_OACK(self, datagram): """Handle incoming OACK datagram, process and apply options and hand over control to the underlying L{ReadSession}. @param datagram: OACK datagram @type datagram: L{OACKDatagram} """ if not self.session.started: self.resultant_options = self.processOptions(datagram.options) if self.timeout_watchdog is not None and self.timeout_watchdog.active( ): self.timeout_watchdog.cancel() self.applyOptions(self.session, self.resultant_options) self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock() else: log.msg("Duplicate OACK received, ignored")
class LocalOriginReadSession(TFTPBootstrap): """Bootstraps a L{ReadSession}, that was originated locally, - we've requested a write to a remote server. """ def __init__(self, remote, reader, options=None, _clock=None): TFTPBootstrap.__init__(self, remote, reader, options, _clock) self.session = ReadSession(reader, self._clock) def startProtocol(self): """Connect the transport and start the L{timeout_watchdog}""" self.transport.connect(*self.remote) if self.timeout_watchdog is not None: self.timeout_watchdog.start() def _datagramReceived(self, datagram): if datagram.opcode == OP_OACK: return self.tftp_OACK(datagram) elif (datagram.opcode == OP_ACK and datagram.blocknum == 0 and not self.session.started): self.session.transport = self.transport self.session.startProtocol() if self.timeout_watchdog is not None and self.timeout_watchdog.active(): self.timeout_watchdog.cancel() return self.session.nextBlock() elif self.session.started: return self.session.datagramReceived(datagram) def tftp_OACK(self, datagram): """Handle incoming OACK datagram, process and apply options and hand over control to the underlying L{ReadSession}. @param datagram: OACK datagram @type datagram: L{OACKDatagram} """ if not self.session.started: self.resultant_options = self.processOptions(datagram.options) if self.timeout_watchdog is not None and self.timeout_watchdog.active(): self.timeout_watchdog.cancel() self.applyOptions(self.session, self.resultant_options) self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock() else: log.msg("Duplicate OACK received, ignored")
class RemoteOriginReadSession(TFTPBootstrap): """Bootstraps a L{ReadSession}, that was started remotely, - we've received a RRQ. """ timeout = (1, 3, 7) def __init__(self, remote, reader, options=None, _clock=None): TFTPBootstrap.__init__(self, remote, reader, options, _clock) self.session = ReadSession(reader, self._clock) def option_tsize(self, val): """Process tsize option. If tsize is zero, get the size of the file to be read so that it can be returned in the OACK datagram. @see: L{TFTPBootstrap.option_tsize} """ val = TFTPBootstrap.option_tsize(self, val) if val == b"0": val = self.session.reader.size if val is not None: val = intToBytes(val) return val def startProtocol(self): """Start sending an OACK datagram if we were initialized with options or start the L{ReadSession} immediately. """ self.transport.connect(*self.remote) if self.options: self.resultant_options = self.processOptions(self.options) bytes = OACKDatagram(self.resultant_options).to_wire() self.timeout_watchdog = SequentialCall.run( self.timeout[:-1], callable=self.transport.write, callable_args=[ bytes, ], on_timeout=lambda: self._clock.callLater( self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock) else: self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock() def _datagramReceived(self, datagram): if datagram.opcode == OP_ACK and datagram.blocknum == 0 and self.session.started is False: return self.tftp_ACK(datagram) elif self.session.started: return self.session.datagramReceived(datagram) def tftp_ACK(self, datagram): """Handle incoming ACK datagram. Hand over control to the underlying L{ReadSession}. @param datagram: ACK datagram @type datagram: L{ACKDatagram} """ if self.timeout_watchdog is not None: self.timeout_watchdog.cancel() if not self.session.started: self.applyOptions(self.session, self.resultant_options) self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock()
class RemoteOriginReadSession(TFTPBootstrap): """Bootstraps a L{ReadSession}, that was started remotely, - we've received a RRQ. """ timeout = (1, 3, 7) def __init__(self, remote, reader, options=None, _clock=None): TFTPBootstrap.__init__(self, remote, reader, options, _clock) self.session = ReadSession(reader, self._clock) def option_tsize(self, val): """Process tsize option. If tsize is zero, get the size of the file to be read so that it can be returned in the OACK datagram. @see: L{TFTPBootstrap.option_tsize} """ val = TFTPBootstrap.option_tsize(self, val) if val == b"0": val = self.session.reader.size if val is not None: val = intToBytes(val) return val def startProtocol(self): """Start sending an OACK datagram if we were initialized with options or start the L{ReadSession} immediately. """ self.transport.connect(*self.remote) if self.options: self.resultant_options = self.processOptions(self.options) bytes = OACKDatagram(self.resultant_options).to_wire() self.timeout_watchdog = timedCaller( chain((0,), self.timeout), partial(self.transport.write, bytes), self.timedOut, clock=self._clock) else: self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock() def _datagramReceived(self, datagram): if datagram.opcode == OP_ACK and datagram.blocknum == 0 and self.session.started is False: return self.tftp_ACK(datagram) elif self.session.started: return self.session.datagramReceived(datagram) def tftp_ACK(self, datagram): """Handle incoming ACK datagram. Hand over control to the underlying L{ReadSession}. @param datagram: ACK datagram @type datagram: L{ACKDatagram} """ self.timeout_watchdog.cancel() if not self.session.started: self.applyOptions(self.session, self.resultant_options) self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock()