Package com.subgraph.orchid.directory.consensus

Source Code of com.subgraph.orchid.directory.consensus.RouterStatusSectionParser

package com.subgraph.orchid.directory.consensus;

import com.subgraph.orchid.ConsensusDocument.ConsensusFlavor;
import com.subgraph.orchid.TorParsingException;
import com.subgraph.orchid.crypto.TorMessageDigest;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.directory.consensus.ConsensusDocumentParser.DocumentSection;
import com.subgraph.orchid.directory.parsing.DocumentFieldParser;

public class RouterStatusSectionParser extends ConsensusDocumentSectionParser {

  private RouterStatusImpl currentEntry = null;
 
  RouterStatusSectionParser(DocumentFieldParser parser, ConsensusDocumentImpl document) {
    super(parser, document);
  }
 
  @Override
  void parseLine(DocumentKeyword keyword) {
    if(!keyword.equals(DocumentKeyword.R))
      assertCurrentEntry();
    switch(keyword) {
    case R:
      parseFirstLine();
      break;
    case S:
      parseFlags();
      break;
    case V:
      parseVersion();
      break;
    case W:
      parseBandwidth();
      break;
    case P:
      parsePortList();
      break;
    case M:
      parseMicrodescriptorHash();
      break;
    default:
      break;
    }
  }

  private void assertCurrentEntry() {
    if(currentEntry == null)
      throw new TorParsingException("Router status entry must begin with an 'r' line");
  }
 
  private void addCurrentEntry() {
    assertCurrentEntry();
    document.addRouterStatusEntry(currentEntry);
    currentEntry = null;
  }
 
  private void parseFirstLine() {
    if(currentEntry != null)
      throw new TorParsingException("Unterminated router status entry.");
    currentEntry = new RouterStatusImpl();
    currentEntry.setNickname(fieldParser.parseNickname());
    currentEntry.setIdentity(parseBase64Digest());
    if(document.getFlavor() != ConsensusFlavor.MICRODESC) {
      currentEntry.setDigest(parseBase64Digest());
    }
    currentEntry.setPublicationTime(fieldParser.parseTimestamp());
    currentEntry.setAddress(fieldParser.parseAddress());
    currentEntry.setRouterPort(fieldParser.parsePort());
    currentEntry.setDirectoryPort(fieldParser.parsePort());
  }
 
  private HexDigest parseBase64Digest() {
    return HexDigest.createFromDigestBytes(fieldParser.parseBase64Data());
  }
 
  private void parseFlags() {
    while(fieldParser.argumentsRemaining() > 0)
      currentEntry.addFlag(fieldParser.parseString());
  }
 
  private void parseVersion() {
    currentEntry.setVersion(fieldParser.parseConcatenatedString());
  }
 
  private void parseBandwidth() {
    while(fieldParser.argumentsRemaining() > 0) {
      final String[] parts = fieldParser.parseString().split("=");
      if(parts.length == 2)
        parseBandwidthItem(parts[0], fieldParser.parseInteger(parts[1]));
    }
    if(document.getFlavor() == ConsensusFlavor.MICRODESC) {
      addCurrentEntry();
    }
  }
 
  private void parseBandwidthItem(String key, int value) {
    if(key.equals("Bandwidth"))
      currentEntry.setEstimatedBandwidth(value);
    else if(key.equals("Measured"))
      currentEntry.setMeasuredBandwidth(value);
  }
 
  private void parsePortList() {
    if(document.getFlavor() == ConsensusFlavor.MICRODESC) {
      throw new TorParsingException("'p' line does not appear in consensus flavor 'microdesc'");
    }
    final String arg = fieldParser.parseString();
    if(arg.equals("accept")) {
      currentEntry.setAcceptedPorts(fieldParser.parseString());
    } else if(arg.equals("reject")) {
      currentEntry.setRejectedPorts(fieldParser.parseString());
    }
    addCurrentEntry();
  }
 
  private void parseMicrodescriptorHash() {
    if(document.getFlavor() != ConsensusFlavor.MICRODESC) {
      throw new TorParsingException("'m' line is invalid unless consensus flavor is microdesc");
    }
    final byte[] hashBytes = fieldParser.parseBase64Data();
    if(hashBytes.length != TorMessageDigest.TOR_DIGEST256_SIZE) {
      throw new TorParsingException("'m' line has incorrect digest size "+ hashBytes.length +" != "+ TorMessageDigest.TOR_DIGEST256_SIZE);
    }
    currentEntry.setMicrodescriptorDigest(HexDigest.createFromDigestBytes(hashBytes));
  }

  @Override
  String getNextStateKeyword() {
    return "directory-footer";
  }

  @Override
  DocumentSection getSection() {
    return DocumentSection.ROUTER_STATUS;
  }
 
  DocumentSection nextSection() {
    return DocumentSection.FOOTER;
  }

}
TOP

Related Classes of com.subgraph.orchid.directory.consensus.RouterStatusSectionParser

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.