Class: Erlang::NodeConnection
- Inherits:
-
EM::Connection
- Object
- EM::Connection
- Erlang::NodeConnection
- Includes:
- EM::Deferrable
- Defined in:
- lib/rinterface/node.rb
Instance Attribute Summary collapse
-
#args ⇒ Object
Returns the value of attribute args.
-
#cookie ⇒ Object
Returns the value of attribute cookie.
-
#destnode ⇒ Object
Returns the value of attribute destnode.
-
#fun ⇒ Object
Returns the value of attribute fun.
-
#host ⇒ Object
Returns the value of attribute host.
-
#mod ⇒ Object
Returns the value of attribute mod.
-
#myname ⇒ Object
Returns the value of attribute myname.
-
#port ⇒ Object
Returns the value of attribute port.
Class Method Summary collapse
-
.build_nodename ⇒ Object
Build a nodename for us.
-
.get_cookie ⇒ Object
Get the Cookie from the home directory.
-
.rpc_call(node, port, mod, fun, args) ⇒ Object
node = destination node port = the port of the Erlang node (from epmd) mod = the module to call fun = the function to call args = args to pass to fun.
Instance Method Summary collapse
- #call_remote ⇒ Object
- #connection_completed ⇒ Object
- #determine_message ⇒ Object
- #handle_any_response ⇒ Object
- #make_challenge(her_challenge) ⇒ Object
- #post_init ⇒ Object
- #receive_challenge(packet_size, decoder) ⇒ Object
-
#receive_challenge_ack(packet_size, decoder) ⇒ Object
Handshake complete…send the RPC.
- #receive_data(data) ⇒ Object
- #receive_status(packet_size, decoder) ⇒ Object
- #send_name ⇒ Object
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def args @args end |
#cookie ⇒ Object
Returns the value of attribute cookie.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def @cookie end |
#destnode ⇒ Object
Returns the value of attribute destnode.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def destnode @destnode end |
#fun ⇒ Object
Returns the value of attribute fun.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def fun @fun end |
#host ⇒ Object
Returns the value of attribute host.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def host @host end |
#mod ⇒ Object
Returns the value of attribute mod.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def mod @mod end |
#myname ⇒ Object
Returns the value of attribute myname.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def myname @myname end |
#port ⇒ Object
Returns the value of attribute port.
79 80 81 |
# File 'lib/rinterface/node.rb', line 79 def port @port end |
Class Method Details
.build_nodename ⇒ Object
Build a nodename for us
108 109 110 111 112 |
# File 'lib/rinterface/node.rb', line 108 def self.build_nodename require 'socket' myhostname = Socket.gethostname.split(".")[0] "ruby_client@#{myhostname}" end |
.get_cookie ⇒ Object
Get the Cookie from the home directory
100 101 102 103 104 105 |
# File 'lib/rinterface/node.rb', line 100 def self. # ... I did it all for the cookie, come on the cookie ... fp = File.("~#{ENV['USER']}/.erlang.cookie") fh = File.open(fp,'r') fh.readline.strip end |
.rpc_call(node, port, mod, fun, args) ⇒ Object
node = destination node port = the port of the Erlang node (from epmd) mod = the module to call fun = the function to call args = args to pass to fun
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/rinterface/node.rb', line 86 def self.rpc_call(node,port,mod,fun,args) EM.connect("127.0.0.1",port,self) do |c| c.destnode = node c.mod = mod c.fun = fun c.args = args c.port = port c.myname = build_nodename c. = end end |
Instance Method Details
#call_remote ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/rinterface/node.rb', line 220 def call_remote myPid = Erlang::Terms::Pid.new(self.myname.intern,5,5,5) call_tuple = [:call,self.mod.intern,self.fun.intern,Erlang::Terms::List.new(self.args),:user] rpc_tuple = [myPid,call_tuple] ctl_msg = [6,myPid,self..intern,:rex] encode_data = Encoder.new encode_data.term_to_binary(ctl_msg) encode_data.term_to_binary(rpc_tuple) data = encode_data.out.string f = Encoder.new f.write_4(data.length + 1) final_out = f.out.string + 'p' + data send_data final_out end |
#connection_completed ⇒ Object
118 119 120 |
# File 'lib/rinterface/node.rb', line 118 def connection_completed send_data send_name end |
#determine_message ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/rinterface/node.rb', line 163 def decoder = Decode.read_bits(@resp) packet_size = decoder.read_2 #puts "PacketSize: #{packet_size}" status_code = decoder.read_string(1) case status_code when 's' then receive_status(packet_size,decoder) when 'n' then receive_challenge(packet_size,decoder) when 'a' then receive_challenge_ack(packet_size,decoder) else "Got back a weird packet" end end |
#handle_any_response ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/rinterface/node.rb', line 127 def handle_any_response result = "" decoder = Decode.read_bits(@resp) s = decoder.read_4 #puts "Size: #{s}" code = decoder.read_string(1) if code == 'p' #puts "found the p" # read the control message and ignore decoder.read_any # read the message result = decoder.read_any #puts "Raw Response: #{result.inspect}" set_deferred_success result[1] else # This seems to never happen...always 'p' result = decoder.read_any set_deferred_failure result end end |
#make_challenge(her_challenge) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/rinterface/node.rb', line 200 def make_challenge(her_challenge) incr_digest = Digest::MD5.new() incr_digest << @cookie incr_digest << her_challenge.to_s digest = incr_digest.digest our_challenge = rand(10000) encoder = Encoder.new encoder.write_2(21) encoder.write_string('r') encoder.write_4(our_challenge) encoder.write_string(digest) encoder.out.string end |
#post_init ⇒ Object
114 115 116 |
# File 'lib/rinterface/node.rb', line 114 def post_init @responder = :determine_message end |
#receive_challenge(packet_size, decoder) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/rinterface/node.rb', line 187 def receive_challenge(packet_size,decoder) dist_code = decoder.read_2 #puts "Code: #{dist_code}" flags = decoder.read_4 #puts "Flags #{flags}" challenge = decoder.read_4 his_name = decoder.read_string(decoder.in.size-13) #puts "His name: #{his_name}" #puts "Got the challenge #{challenge}" #out_challenge = make_challenge(challenge) send_data make_challenge(challenge) end |
#receive_challenge_ack(packet_size, decoder) ⇒ Object
Handshake complete…send the RPC
215 216 217 218 |
# File 'lib/rinterface/node.rb', line 215 def receive_challenge_ack(packet_size,decoder) @responder = :handle_any_response call_remote end |
#receive_data(data) ⇒ Object
122 123 124 125 |
# File 'lib/rinterface/node.rb', line 122 def receive_data data @resp = data send @responder end |
#receive_status(packet_size, decoder) ⇒ Object
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rinterface/node.rb', line 176 def receive_status(packet_size,decoder) status = decoder.read_string(packet_size-1) if decoder.in.size > (packet_size + 2) # Hack when both receive packets are crammed together into 1 next_packet_size = decoder.read_2 # read size status_code = decoder.read_string(1) receive_challenge(next_packet_size, decoder) end set_deferred_failure "Failed on Recv Status: #{status_code}" unless status == 'ok' end |
#send_name ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rinterface/node.rb', line 148 def send_name full_host_name = self.myname encode = Encoder.new encode.write_2(full_host_name.length + 7) # node type encode.write_1(110) # distChoose encode.write_2(5) # flags encode.write_4(4|256|1024|2048) # node name encode.write_string(full_host_name) encode.out.string end |