Ejemplo n.º 1
0
  /* Parse and execute a SESSION message */
  protected boolean execSessionMessage(String opcode, Properties props) {

    String dest = "BUG!";

    try {
      if (opcode.equals("CREATE")) {
        if ((getRawSession() != null)
            || (getDatagramSession() != null)
            || (getStreamSession() != null)) {
          if (_log.shouldLog(Log.DEBUG))
            _log.debug("Trying to create a session, but one still exists");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Session already exists\"\n");
        }
        if (props.isEmpty()) {
          if (_log.shouldLog(Log.DEBUG))
            _log.debug("No parameters specified in SESSION CREATE message");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"No parameters for SESSION CREATE\"\n");
        }

        dest = props.getProperty("DESTINATION");
        if (dest == null) {
          if (_log.shouldLog(Log.DEBUG)) _log.debug("SESSION DESTINATION parameter not specified");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"DESTINATION not specified\"\n");
        }
        props.remove("DESTINATION");

        String destKeystream = null;

        if (dest.equals("TRANSIENT")) {
          _log.debug("TRANSIENT destination requested");
          ByteArrayOutputStream priv = new ByteArrayOutputStream(640);
          SAMUtils.genRandomKey(priv, null);

          destKeystream = Base64.encode(priv.toByteArray());
        } else {
          destKeystream = bridge.getKeystream(dest);
          if (destKeystream == null) {
            if (_log.shouldLog(Log.DEBUG))
              _log.debug(
                  "Custom destination specified ["
                      + dest
                      + "] but it isn't known, creating a new one");
            ByteArrayOutputStream baos = new ByteArrayOutputStream(640);
            SAMUtils.genRandomKey(baos, null);
            destKeystream = Base64.encode(baos.toByteArray());
            bridge.addKeystream(dest, destKeystream);
          } else {
            if (_log.shouldLog(Log.DEBUG))
              _log.debug("Custom destination specified [" + dest + "] and it is already known");
          }
        }

        String style = props.getProperty("STYLE");
        if (style == null) {
          if (_log.shouldLog(Log.DEBUG)) _log.debug("SESSION STYLE parameter not specified");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"No SESSION STYLE specified\"\n");
        }
        props.remove("STYLE");

        // Unconditionally override what the client may have set
        // (iMule sets BestEffort) as None is more efficient
        // and the client has no way to access delivery notifications
        props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);

        if (style.equals("RAW")) {
          rawSession = new SAMRawSession(destKeystream, props, this);
        } else if (style.equals("DATAGRAM")) {
          datagramSession = new SAMDatagramSession(destKeystream, props, this);
        } else if (style.equals("STREAM")) {
          String dir = props.getProperty("DIRECTION");
          if (dir == null) {
            if (_log.shouldLog(Log.DEBUG))
              _log.debug("No DIRECTION parameter in STREAM session, defaulting to BOTH");
            dir = "BOTH";
          } else if (!dir.equals("CREATE") && !dir.equals("RECEIVE") && !dir.equals("BOTH")) {
            if (_log.shouldLog(Log.DEBUG))
              _log.debug("Unknown DIRECTION parameter value: [" + dir + "]");
            return writeString(
                "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Unknown DIRECTION parameter\"\n");
          } else {
            props.remove("DIRECTION");
          }

          streamSession = newSAMStreamSession(destKeystream, dir, props);
        } else {
          if (_log.shouldLog(Log.DEBUG))
            _log.debug("Unrecognized SESSION STYLE: \"" + style + "\"");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Unrecognized SESSION STYLE\"\n");
        }
        return writeString("SESSION STATUS RESULT=OK DESTINATION=" + dest + "\n");
      } else {
        if (_log.shouldLog(Log.DEBUG))
          _log.debug("Unrecognized SESSION message opcode: \"" + opcode + "\"");
        return writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Unrecognized opcode\"\n");
      }
    } catch (DataFormatException e) {
      if (_log.shouldLog(Log.DEBUG)) _log.debug("Invalid destination specified");
      return writeString(
          "SESSION STATUS RESULT=INVALID_KEY DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } catch (I2PSessionException e) {
      if (_log.shouldLog(Log.DEBUG)) _log.debug("I2P error when instantiating session", e);
      return writeString(
          "SESSION STATUS RESULT=I2P_ERROR DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } catch (SAMException e) {
      _log.error("Unexpected SAM error", e);
      return writeString(
          "SESSION STATUS RESULT=I2P_ERROR DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } catch (IOException e) {
      _log.error("Unexpected IOException", e);
      return writeString(
          "SESSION STATUS RESULT=I2P_ERROR DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    }
  }
Ejemplo n.º 2
0
  /* Parse and execute a SESSION message */
  @Override
  protected boolean execSessionMessage(String opcode, Properties props) {

    String dest = "BUG!";
    String nick = null;
    boolean ok = false;

    try {
      if (opcode.equals("CREATE")) {
        if ((this.getRawSession() != null)
            || (this.getDatagramSession() != null)
            || (this.getStreamSession() != null)) {
          _log.debug("Trying to create a session, but one still exists");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Session already exists\"\n");
        }
        if (props == null) {
          _log.debug("No parameters specified in SESSION CREATE message");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"No parameters for SESSION CREATE\"\n");
        }

        dest = props.getProperty("DESTINATION");
        if (dest == null) {
          _log.debug("SESSION DESTINATION parameter not specified");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"DESTINATION not specified\"\n");
        }
        props.remove("DESTINATION");

        if (dest.equals("TRANSIENT")) {
          _log.debug("TRANSIENT destination requested");
          ByteArrayOutputStream priv = new ByteArrayOutputStream(640);
          SAMUtils.genRandomKey(priv, null);

          dest = Base64.encode(priv.toByteArray());
        } else {
          _log.debug("Custom destination specified [" + dest + "]");
        }

        try {
          SAMUtils.checkPrivateDestination(dest);
        } catch (SAMUtils.InvalidDestination e) {
          return writeString("SESSION STATUS RESULT=INVALID_KEY\n");
        }

        nick = props.getProperty("ID");
        if (nick == null) {
          _log.debug("SESSION ID parameter not specified");
          return writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"ID not specified\"\n");
        }
        props.remove("ID");

        String style = props.getProperty("STYLE");
        if (style == null) {
          _log.debug("SESSION STYLE parameter not specified");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"No SESSION STYLE specified\"\n");
        }
        props.remove("STYLE");

        // Unconditionally override what the client may have set
        // (iMule sets BestEffort) as None is more efficient
        // and the client has no way to access delivery notifications
        i2cpProps.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);

        // Record the session in the database sSessionsHash
        Properties allProps = new Properties();
        allProps.putAll(i2cpProps);
        allProps.putAll(props);

        try {
          sSessionsHash.put(nick, new SessionRecord(dest, allProps, this));
        } catch (SessionsDB.ExistingId e) {
          _log.debug("SESSION ID parameter already in use");
          return writeString("SESSION STATUS RESULT=DUPLICATED_ID\n");
        } catch (SessionsDB.ExistingDest e) {
          return writeString("SESSION STATUS RESULT=DUPLICATED_DEST\n");
        }

        // Create the session

        if (style.equals("RAW")) {
          DatagramServer.getInstance(i2cpProps);
          rawSession = newSAMRawSession(nick);
          this.session = rawSession;
        } else if (style.equals("DATAGRAM")) {
          DatagramServer.getInstance(i2cpProps);
          datagramSession = newSAMDatagramSession(nick);
          this.session = datagramSession;
        } else if (style.equals("STREAM")) {
          streamSession = newSAMStreamSession(nick);
          this.session = streamSession;
        } else {
          _log.debug("Unrecognized SESSION STYLE: \"" + style + "\"");
          return writeString(
              "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Unrecognized SESSION STYLE\"\n");
        }
        ok = true;
        return writeString("SESSION STATUS RESULT=OK DESTINATION=" + dest + "\n");
      } else {
        _log.debug("Unrecognized SESSION message opcode: \"" + opcode + "\"");
        return writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Unrecognized opcode\"\n");
      }
    } catch (DataFormatException e) {
      _log.debug("Invalid destination specified");
      return writeString(
          "SESSION STATUS RESULT=INVALID_KEY DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } catch (I2PSessionException e) {
      _log.debug("I2P error when instantiating session", e);
      return writeString(
          "SESSION STATUS RESULT=I2P_ERROR DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } catch (SAMException e) {
      _log.info("Funny SAM error", e);
      return writeString(
          "SESSION STATUS RESULT=I2P_ERROR DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } catch (IOException e) {
      _log.error("Unexpected IOException", e);
      return writeString(
          "SESSION STATUS RESULT=I2P_ERROR DESTINATION="
              + dest
              + " MESSAGE=\""
              + e.getMessage()
              + "\"\n");
    } finally {
      // unregister the session if it has not been created
      if (!ok && nick != null) {
        sSessionsHash.del(nick);
        session = null;
      }
    }
  }