client.rb
#Looks through the database for other nodes we've heard of, 
#and checks that they have running replications.
Looks through the database for other nodes we've heard of,
and checks that they have running replications.
Looks through the database for other nodes we ' ve heard of and checks that they have running replications .
def check_for_replications
  uri = URI(NODEVIEWURL)
  req = Net::HTTP::Get.new(uri.path)
  req["content-type"] = "application/json"
  data = nil
  Net::HTTP.start(uri.host, uri.port) do |http|
    response = http.request req 
    data = JSON.parse(response.body)
  end
  data['rows'].each do |node|
    begin
      d = node['value']
      puts "My address: #{@myaddress} Considering: #{d['address']}"
      if (d['address'] == @myaddress)
        puts "Won't replicate to myself."
        next
      else
        puts "Proceeding with replication."
      end
      a = d['address']
      c = d['cert']
      s = d['signature']
      revm = d['_rev'].match(/([0-9]+)-.+/)
      rev = revm[1]
      remote_certificate = OpenSSL::X509::Certificate.new c
      pubkey = OpenSSL::PKey::EC.new (remote_certificate.public_key)
      if pubkey.dsa_verify_asn1(rev+a+c, Base64.decode64(s))
        puts "Replications: Found valid ID document for #{a}"
        remoteaddress = "https://#{a}:34214/reticle/"
        insert_my_node_document(remoteaddress, remote_certificate)
        uri = URI(REPLICATORURL+"rep_#{a}")
        req = Net::HTTP::Get.new(uri.path)
        req["content-type"] = "application/json"
        crepdata = nil
        Net::HTTP.start(uri.host, uri.port) do |http|
          response = http.request req 
          crepdata = JSON.parse(response.body)
        end
        if (crepdata['_replication_state'] == "triggered")
          puts "I already have a replication for #{remoteaddress}."
          next
        end
        repdata = {
          "source" => remoteaddress,
          "continuous" => true,
          "target" => "reticle"
        }
        if crepdata['_rev'] 
          repdata['_rev'] = crepdata['_rev'] 
        end
        uri = URI(REPLICATORURL+"rep_#{a}")
        req = Net::HTTP::Put.new(uri.path)
        req["content-type"] = "application/json"
        req.body = JSON.generate(repdata)
        Net::HTTP.start(uri.host, uri.port) do |http|
          response = http.request req 
          puts "Response to inserting replication document for #{remoteaddress}: #{response.body}"
        end
      else
        puts "Replications: Invalid ID document for #{a}, disregarding."
      end
    rescue => e
      puts "Was unable to do the replication to #{node['value']['address']} because:"
      puts e.message  
      puts e.backtrace.join("\n")
    end
    puts "At the bottom of the replication loop for #{node['value']['address']}"
  end
end
def check_for_replications uri = URI ( NODEVIEWURL ) req = Net :: HTTP :: Get . new ( uri . path ) req [ "content-type" ] = "application/json" data = nil Net :: HTTP . start ( uri . host , uri . port ) do | http | response = http . request req data = JSON . parse ( response . body ) end data [ 'rows' ] . each do | node | begin d = node [ 'value' ] puts "My address: #{@myaddress} Considering: #{d['address']}" if ( d [ 'address' ] == @myaddress ) puts "Won't replicate to myself." next else puts "Proceeding with replication." end a = d [ 'address' ] c = d [ 'cert' ] s = d [ 'signature' ] revm = d [ '_rev' ] . match ( / ([0-9]+)-.+ / ) rev = revm [ 1 ] remote_certificate = OpenSSL :: X509 :: Certificate . new c pubkey = OpenSSL :: PKey :: EC . new ( remote_certificate . public_key ) if pubkey . dsa_verify_asn1 ( rev + a + c , Base64 . decode64 ( s ) ) puts "Replications: Found valid ID document for #{a}" remoteaddress = "https://#{a}:34214/reticle/" insert_my_node_document ( remoteaddress , remote_certificate ) uri = URI ( REPLICATORURL + "rep_#{a}" ) req = Net :: HTTP :: Get . new ( uri . path ) req [ "content-type" ] = "application/json" crepdata = nil Net :: HTTP . start ( uri . host , uri . port ) do | http | response = http . request req crepdata = JSON . parse ( response . body ) end if ( crepdata [ '_replication_state' ] == "triggered" ) puts "I already have a replication for #{remoteaddress}." next end repdata = { "source" => remoteaddress , "continuous" => true , "target" => "reticle" } if crepdata [ '_rev' ] repdata [ '_rev' ] = crepdata [ '_rev' ] end uri = URI ( REPLICATORURL + "rep_#{a}" ) req = Net :: HTTP :: Put . new ( uri . path ) req [ "content-type" ] = "application/json" req . body = JSON . generate ( repdata ) Net :: HTTP . start ( uri . host , uri . port ) do | http | response = http . request req puts "Response to inserting replication document for #{remoteaddress}: #{response.body}" end else puts "Replications: Invalid ID document for #{a}, disregarding." end rescue => e puts "Was unable to do the replication to #{node['value']['address']} because:" puts e . message puts e . backtrace . join ( "\n" ) end puts "At the bottom of the replication loop for #{node['value']['address']}" end end
Looks through the database for other nodes we've heard of,
and checks that they have running replications.
Looks through the database for other nodes we ' ve heard of and checks that they have running replications .
# Net::HTTPResponse object #This is me-- don't try to replicate to myself, it'd be dumb. #signature over (rev+address+cert) #Then we've got a valid ID document. #Now do two things: 1) Push my ID doc to it, and 2) Make sure a replication is running *from* it. #BaseURL: of the form "http://hostname.onion:34214/reticle/" # Net::HTTPResponse object #Then we've got a valid, working replication already. #And, importantly, if we're still here... #This means that the replication isn't working. #Make it rewrite correctly # Net::HTTPResponse object #Have to use kernel.puts here... not entirely sure why, but otherwise I get the #Error referenced in http://stackoverflow.com/questions/9911781/ruby-global-scope