Package com.subgraph.orchid.circuits

Source Code of com.subgraph.orchid.circuits.CircuitImpl

package com.subgraph.orchid.circuits;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

import com.subgraph.orchid.Cell;
import com.subgraph.orchid.Circuit;
import com.subgraph.orchid.CircuitNode;
import com.subgraph.orchid.Connection;
import com.subgraph.orchid.DirectoryCircuit;
import com.subgraph.orchid.ExitCircuit;
import com.subgraph.orchid.InternalCircuit;
import com.subgraph.orchid.RelayCell;
import com.subgraph.orchid.Router;
import com.subgraph.orchid.Stream;
import com.subgraph.orchid.StreamConnectFailedException;
import com.subgraph.orchid.TorException;
import com.subgraph.orchid.circuits.path.CircuitPathChooser;
import com.subgraph.orchid.circuits.path.PathSelectionFailedException;
import com.subgraph.orchid.dashboard.DashboardRenderable;
import com.subgraph.orchid.dashboard.DashboardRenderer;

/**
* This class represents an established circuit through the Tor network.
*
*/
public abstract class CircuitImpl implements Circuit, DashboardRenderable {
  protected final static Logger logger = Logger.getLogger(CircuitImpl.class.getName());
 
  static ExitCircuit createExitCircuit(CircuitManagerImpl circuitManager, Router exitRouter) {
    return new ExitCircuitImpl(circuitManager, exitRouter);
  }
 
  static ExitCircuit createExitCircuitTo(CircuitManagerImpl circuitManager, List<Router> prechosenPath) {
    return new ExitCircuitImpl(circuitManager, prechosenPath);
  }
 
  static DirectoryCircuit createDirectoryCircuit(CircuitManagerImpl circuitManager) {
    return new DirectoryCircuitImpl(circuitManager, null);
  }
 
  static DirectoryCircuit createDirectoryCircuitTo(CircuitManagerImpl circuitManager, List<Router> prechosenPath) {
    return new DirectoryCircuitImpl(circuitManager, prechosenPath);
  }
 
  static InternalCircuit createInternalCircuitTo(CircuitManagerImpl circuitManager, List<Router> prechosenPath) {
    return new InternalCircuitImpl(circuitManager, prechosenPath);
  }

  private final CircuitManagerImpl circuitManager;
  protected final List<Router> prechosenPath;
 
  private final List<CircuitNode> nodeList;
  private final CircuitStatus status;

  private CircuitIO io;


 
   
 
 
  protected CircuitImpl(CircuitManagerImpl circuitManager) {
    this(circuitManager, null);
  }
 
  protected CircuitImpl(CircuitManagerImpl circuitManager, List<Router> prechosenPath) {
    nodeList = new ArrayList<CircuitNode>();
    this.circuitManager = circuitManager;
    this.prechosenPath = prechosenPath;
    status = new CircuitStatus();
  }

  List<Router> choosePath(CircuitPathChooser pathChooser) throws InterruptedException, PathSelectionFailedException {
    if(prechosenPath != null) {
      return new ArrayList<Router>(prechosenPath);
    } else {
      return choosePathForCircuit(pathChooser);
    }
  }

  protected abstract List<Router> choosePathForCircuit(CircuitPathChooser pathChooser) throws InterruptedException, PathSelectionFailedException;

  void bindToConnection(Connection connection) {
    if(io != null) {
      throw new IllegalStateException("Circuit already bound to a connection");
    }
    final int id = connection.bindCircuit(this);
    io = new CircuitIO(this, connection, id);
  }

  public void markForClose() {
    if(io != null) {
      io.markForClose();
    }
  }

  public boolean isMarkedForClose() {
    if(io == null) {
      return false;
    } else {
      return io.isMarkedForClose();
    }
  }
 
  CircuitStatus getStatus() {
    return status;
  }
 
  public boolean isConnected() {
    return status.isConnected();
  }

  public boolean isPending() {
    return status.isBuilding();
  }
 
  public boolean isClean() {
    return !status.isDirty();
  }
 
  public int getSecondsDirty() {
    return (int) (status.getMillisecondsDirty() / 1000);
  }

  void notifyCircuitBuildStart() {
    if(!status.isUnconnected()) {
      throw new IllegalStateException("Can only connect UNCONNECTED circuits");
    }
    status.updateCreatedTimestamp();
    status.setStateBuilding();
    circuitManager.addActiveCircuit(this);
  }
 
  void notifyCircuitBuildFailed() {
    status.setStateFailed();
    circuitManager.removeActiveCircuit(this);
  }
 
  void notifyCircuitBuildCompleted() {
    status.setStateOpen();
    status.updateCreatedTimestamp();
  }
 
  public Connection getConnection() {
    if(!isConnected())
      throw new TorException("Circuit is not connected.");
    return io.getConnection();
  }

  public int getCircuitId() {
    if(io == null) {
      return 0;
    } else {
      return io.getCircuitId();
    }
  }

  public void sendRelayCell(RelayCell cell) {
    io.sendRelayCellTo(cell, cell.getCircuitNode());
  }

  public void sendRelayCellToFinalNode(RelayCell cell) {
    io.sendRelayCellTo(cell, getFinalCircuitNode());
  }

  public void appendNode(CircuitNode node) {
    nodeList.add(node);
  }

  List<CircuitNode> getNodeList() {
    return nodeList;
  }

  int getCircuitLength() {
    return nodeList.size();
  }

  public CircuitNode getFinalCircuitNode() {
    if(nodeList.isEmpty())
      throw new TorException("getFinalCircuitNode() called on empty circuit");
    return nodeList.get( getCircuitLength() - 1);
  }

  public RelayCell createRelayCell(int relayCommand, int streamId, CircuitNode targetNode) {
    return io.createRelayCell(relayCommand, streamId, targetNode);
  }

  public RelayCell receiveRelayCell() {
    return io.dequeueRelayResponseCell();
  }

  void sendCell(Cell cell) {
    io.sendCell(cell);
  }
 
  Cell receiveControlCellResponse() {
    return io.receiveControlCellResponse();
  }

  /*
   * This is called by the cell reading thread in ConnectionImpl to deliver control cells
   * associated with this circuit (CREATED or CREATED_FAST).
   */
  public void deliverControlCell(Cell cell) {
    io.deliverControlCell(cell);
  }

  /* This is called by the cell reading thread in ConnectionImpl to deliver RELAY cells. */
  public void deliverRelayCell(Cell cell) {
    io.deliverRelayCell(cell);
  }

  protected StreamImpl createNewStream(boolean autoclose) {
    return io.createNewStream(autoclose);
  }
  protected StreamImpl createNewStream() {
    return createNewStream(false);
  }

  void setStateDestroyed() {
    status.setStateDestroyed();
    circuitManager.removeActiveCircuit(this);
  }

  public void destroyCircuit() {
    io.destroyCircuit();
    circuitManager.removeActiveCircuit(this);
  }


  public void removeStream(StreamImpl stream) {
    io.removeStream(stream);
  }

  protected Stream processStreamOpenException(Exception e) throws InterruptedException, TimeoutException, StreamConnectFailedException {
    if(e instanceof InterruptedException) {
      throw (InterruptedException) e;
    } else if(e instanceof TimeoutException) {
      throw(TimeoutException) e;
    } else if(e instanceof StreamConnectFailedException) {
      throw(StreamConnectFailedException) e;
    } else {
      throw new IllegalStateException();
    }
  }
 
  protected abstract String getCircuitTypeLabel();
 
  public String toString() {
    return "  Circuit ("+ getCircuitTypeLabel() + ") id="+ getCircuitId() +" state=" + status.getStateAsString() +" "+ pathToString();
  }

 
  protected String pathToString() {
    final StringBuilder sb = new StringBuilder();
    sb.append("[");
    for(CircuitNode node: nodeList) {
      if(sb.length() > 1)
        sb.append(",");
      sb.append(node.toString());
    }
    sb.append("]");
    return sb.toString();
  }

  public List<Stream> getActiveStreams() {
    if(io == null) {
      return Collections.emptyList();
    } else {
      return io.getActiveStreams();
    }
  }

  public void dashboardRender(DashboardRenderer renderer, PrintWriter writer, int flags) throws IOException {
    if(io != null) {
      writer.println(toString());
      renderer.renderComponent(writer, flags, io);
    }
  } 
}
TOP

Related Classes of com.subgraph.orchid.circuits.CircuitImpl

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.