Class: NetDSvr

Inherits:
Object
  • Object
show all
Defined in:
lib/netd_core.rb

Overview

the server class of netd

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(socket_path, logger) ⇒ NetDSvr

the server class of netd



9
10
11
12
13
# File 'lib/netd_core.rb', line 9

def initialize(socket_path, logger)
  @path = socket_path
  @net_ops = []
  @logger = logger
end

Class Method Details

.connect_to_netd(&block) ⇒ Object

standard connection to the netd.socket unix server



16
17
18
19
20
21
22
# File 'lib/netd_core.rb', line 16

def self.connect_to_netd(&block)
  # open the socket and execute the block
  UNIXSocket.open("#{Dir.home}/.local/run/netd.socket", &block)
# if failed, print error
rescue Errno::ECONNREFUSED => e
  puts "NetD server does not appear to be running #{e}"
end

.get_direction(command) ⇒ Object

if local then the field is ‘remote’ if remote the command requires ‘local’



25
26
27
# File 'lib/netd_core.rb', line 25

def self.get_direction(command)
  command == NetD::OperationRequest::LOCAL_PORT_FORWARD ? 'remote' : 'local'
end

.parse_line(line) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/netd_core.rb', line 29

def self.parse_line(line)
  tokens = line.split('|')
  # common to both commands
  req = { 'request': tokens[0], 'host': tokens[1], 'bind_addr': tokens[2], 'bind_port': tokens[3] }
  # detect last line
  return if tokens[0] == 'OKAY'

  # add the fields to the output
  direction = NetDSvr.get_direction(tokens[0])
  req["#{direction}_addr"] = tokens[4]
  req["#{direction}_port"] = tokens[5]
  req
end

.parse_list(sock) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/netd_core.rb', line 43

def self.parse_list(sock)
  # parse the first line (number of entries)
  entries = []
  number_of_lines = sock.readline.chomp[0..-2].to_i
  number_of_lines.times do
    # pretty print the hash result from parse_line
    entries << NetDSvr.parse_line(sock.readline.chomp)
  end
  entries
end

Instance Method Details

#current_net_opsObject



54
55
56
57
58
# File 'lib/netd_core.rb', line 54

def current_net_ops
  # get a list of the commands used
  # to dispatch the network operations
  @net_ops.map(&:request).map { |v| v.values.join('|') }
end

#del_request(request_args) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/netd_core.rb', line 60

def del_request(request_args)
  @net_ops.each do |n|
    case request_args[:request]
    when NetD::OperationRequest::DELETE_LOCAL_PORT_FORWARD
      if (n.request[:remote_addr] == request_args[:remote_addr]) && (n.request[:remote_port] == request_args[:remote_port])
        n.close
        @net_ops.delete(n)
        return true
      end
    when NetD::OperationRequest::DELETE_REMOTE_PORT_FORWARD
      if (n.request[:local_addr] == request_args[:local_addr]) && (n.request[:local_port] == request_args[:local_port])
        n.close
        @net_ops.delete(n)
        return true
      end
    end
  end
  false
end

#dispatch_command(request_args, server_socket) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/netd_core.rb', line 80

def dispatch_command(request_args, server_socket)
  # switch on the request type, dispatch the request,
  # and add the object to the tracking list
  case request_args[:request]
  when NetD::OperationRequest::LOCAL_PORT_FORWARD
    @net_ops << NetD::LocalPortForward.new(request_args)
  when NetD::OperationRequest::REMOTE_PORT_FORWARD
    @net_ops << NetD::RemotePortForward.new(request_args)
  when NetD::OperationRequest::DELETE_LOCAL_PORT_FORWARD
    del_request(request_args)
  when NetD::OperationRequest::DELETE_REMOTE_PORT_FORWARD
    del_request(request_args)
  when NetD::OperationRequest::LIST_FORWARDS
    server_socket.puts("#{current_net_ops.length}|\n#{current_net_ops.join("\n")}")
  else
    raise 'how did you get here?'
  end
end

#server_mainObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/netd_core.rb', line 99

def server_main
  UNIXServer.open(@path) do |serv|
    # accept, dispatch, respond for all connections
    loop do
      # accept new connection
      server_socket = serv.accept
      # read command, parse it, and dispatch it
      dispatch_command(NetD::OperationRequest.new(server_socket.readline).parse, server_socket)
      # respond with success
      server_socket.puts 'OKAY|'
    rescue EOFError, Errno::EPIPE, RuntimeError => e
      # if connection fails or bad data is sent, report error
      @logger.error("Malformed Request: #{e.message}\n#{e.backtrace} ")
      server_socket.puts 'ERR|' unless server_socket.closed?
    end
  end
end