Package com.subgraph.orchid.circuits.hs

Source Code of com.subgraph.orchid.circuits.hs.HSDirectories

package com.subgraph.orchid.circuits.hs;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.subgraph.orchid.ConsensusDocument;
import com.subgraph.orchid.Directory;
import com.subgraph.orchid.Router;
import com.subgraph.orchid.crypto.TorRandom;
import com.subgraph.orchid.data.HexDigest;

public class HSDirectories {
  private final static int DIR_CLUSTER_SZ = 3;
  private final Directory directory;
  private final TorRandom random;
  private ConsensusDocument currentConsensus;
  private List<Router> hsDirectories;
 
  HSDirectories(Directory directory) {
    this.directory = directory;
    this.hsDirectories = new ArrayList<Router>();
    this.random = new TorRandom();
  }
 
  List<HSDescriptorDirectory> getDirectoriesForHiddenService(HiddenService hs) {
    final List<HSDescriptorDirectory> dirs = new ArrayList<HSDescriptorDirectory>(2 * DIR_CLUSTER_SZ);
    for(HexDigest id: hs.getAllCurrentDescriptorIds()) {
      for(Router r: getDirectoriesForDescriptorId(id)) {
        dirs.add(new HSDescriptorDirectory(id, r));
      }
    }
    return dirs;
  }
 
  private List<Router> getDirectoriesForDescriptorId(HexDigest descriptorId) {
    final String hexId = descriptorId.toString();
    refreshFromDirectory();
    final int idx = getIndexForDescriptorId(hexId);
    return selectDirectoriesAtIndex(idx);
  }
 
  private int getIndexForDescriptorId(String hexId) {
    for(int i = 0; i < hsDirectories.size(); i++) {
      String routerId = getHexIdForIndex(i);
      if(routerId.compareTo(hexId) > 0) {
        return i;
      }
    }
    return 0;
  }
 
  private String getHexIdForIndex(int idx) {
    final Router r = hsDirectories.get(idx);
    return r.getIdentityHash().toString();
  }
 
  private List<Router> selectDirectoriesAtIndex(int idx) {
    if(idx < 0 || idx >= hsDirectories.size()) {
      throw new IllegalArgumentException("idx = "+ idx);
    }
    if(hsDirectories.size() < DIR_CLUSTER_SZ) {
      throw new IllegalStateException();
    }
    final List<Router> dirs = new ArrayList<Router>(DIR_CLUSTER_SZ);
    for(int i = 0; i < DIR_CLUSTER_SZ; i++) {
      dirs.add(hsDirectories.get(idx));
      idx += 1;
      if(idx == hsDirectories.size()) {
        idx = 0;
      }
    }
    randomShuffle(dirs);
    return dirs;
  }
 
 
 
  private void refreshFromDirectory() {
    ConsensusDocument consensus = directory.getCurrentConsensusDocument();
    if(currentConsensus == consensus) {
      return;
    }
    currentConsensus = consensus;
    hsDirectories.clear();
    for(Router r: directory.getAllRouters()) {
      if(r.isHSDirectory()) {
        hsDirectories.add(r);
      }
    }
   
    Collections.sort(hsDirectories, new Comparator<Router>() {
      public int compare(Router r1, Router r2) {
        final String s1 = r1.getIdentityHash().toString();
        final String s2 = r2.getIdentityHash().toString();
        return s1.compareTo(s2);
      }
    });
  }
 
  private void randomShuffle(List<Router> dirs) {
    for(int i = 0; i < dirs.size(); i++) {
      swap(dirs, i, random.nextInt(dirs.size()));
    }
  }
 
  private void swap(List<Router> dirs, int idx1, int idx2) {
    if(idx1 != idx2) {
      final Router r1 = dirs.get(idx1);
      final Router r2 = dirs.get(idx2);
      dirs.set(idx1, r2);
      dirs.set(idx2, r1);
    }
  }
}
TOP

Related Classes of com.subgraph.orchid.circuits.hs.HSDirectories

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.