Class: RubySMB::Dispatcher::Socket
- Defined in:
- lib/ruby_smb/dispatcher/socket.rb
Overview
This class provides a wrapper around a Socket for the packet Dispatcher. It allows for dependency injection of different Socket implementations.
Constant Summary collapse
- READ_TIMEOUT =
30
Instance Attribute Summary collapse
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(tcp_socket, read_timeout: READ_TIMEOUT) ⇒ Socket
constructor
A new instance of Socket.
-
#recv_packet(full_response: false) ⇒ String
Read a packet off the wire and parse it into a string.
- #send_packet(packet, nbss_header: true) ⇒ void
Methods inherited from Base
Constructor Details
#initialize(tcp_socket, read_timeout: READ_TIMEOUT) ⇒ Socket
Returns a new instance of Socket.
20 21 22 23 24 |
# File 'lib/ruby_smb/dispatcher/socket.rb', line 20 def initialize(tcp_socket, read_timeout: READ_TIMEOUT) @tcp_socket = tcp_socket @tcp_socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true) if @tcp_socket.respond_to?(:setsockopt) @read_timeout = read_timeout end |
Instance Attribute Details
#read_timeout ⇒ Integer
17 18 19 |
# File 'lib/ruby_smb/dispatcher/socket.rb', line 17 def read_timeout @read_timeout end |
#tcp_socket ⇒ IO
12 13 14 |
# File 'lib/ruby_smb/dispatcher/socket.rb', line 12 def tcp_socket @tcp_socket end |
Class Method Details
.connect(host, port: 445, socket: TCPSocket.new(host, port)) ⇒ Object
28 29 30 |
# File 'lib/ruby_smb/dispatcher/socket.rb', line 28 def self.connect(host, port: 445, socket: TCPSocket.new(host, port)) new(socket) end |
Instance Method Details
#recv_packet(full_response: false) ⇒ String
Read a packet off the wire and parse it into a string
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/ruby_smb/dispatcher/socket.rb', line 63 def recv_packet(full_response: false) raise RubySMB::Error::CommunicationError, 'Connection has already been closed' if @tcp_socket.closed? if IO.select([@tcp_socket], nil, nil, @read_timeout).nil? raise RubySMB::Error::CommunicationError, "Read timeout expired when reading from the Socket (timeout=#{@read_timeout})" end begin nbss_data = @tcp_socket.read(4) raise RubySMB::Error::CommunicationError, 'Socket read returned nil' if nbss_data.nil? nbss_header = RubySMB::Nbss::SessionHeader.read(nbss_data) rescue IOError raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing' end length = nbss_header.stream_protocol_length data = full_response ? nbss_header.to_binary_s : '' if length > 0 if IO.select([@tcp_socket], nil, nil, @read_timeout).nil? raise RubySMB::Error::CommunicationError, "Read timeout expired when reading from the Socket (timeout=#{@read_timeout})" end data << @tcp_socket.read(length) data << @tcp_socket.read(length - data.length) while data.length < length end data rescue Errno::EINVAL, Errno::ECONNABORTED, Errno::ECONNRESET, TypeError, NoMethodError => e raise RubySMB::Error::CommunicationError, "An error occurred reading from the Socket #{e.}" end |
#send_packet(packet, nbss_header: true) ⇒ void
This method returns an undefined value.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ruby_smb/dispatcher/socket.rb', line 35 def send_packet(packet, nbss_header: true) data = nbss_header ? nbss(packet) : '' data << packet.to_binary_s bytes_written = 0 begin while bytes_written < data.size retval = @tcp_socket.write(data[bytes_written..-1]) if retval == nil raise RubySMB::Error::CommunicationError else bytes_written += retval end end rescue IOError, Errno::ECONNABORTED, Errno::ECONNRESET => e raise RubySMB::Error::CommunicationError, "An error occurred writing to the Socket: #{e.}" end nil end |