示例#1
0
 boolean initiateConnection(Connection conn_, Peer peer) {
   TCPConnection conn = (TCPConnection) conn_;
   try {
     SocketChannel channel = SocketChannel.open();
     InetSocketAddress localAddress = new InetSocketAddress(conn.host_id, 0);
     channel.socket().bind(localAddress);
     channel.configureBlocking(false);
     try {
       InetSocketAddress remoteAddress = new InetSocketAddress(peer.host(), peer.port());
       if (channel.connect(remoteAddress)) {
         // This only happens on Solaris when connecting locally
         logger.log(Level.FINEST, "Connected!");
         conn.state = Connection.State.connected_out;
         conn.channel = channel;
         selector.wakeup();
         channel.register(selector, SelectionKey.OP_READ, conn);
         initiateCER(conn);
         return true;
       }
     } catch (java.nio.channels.UnresolvedAddressException ex) {
       channel.close();
       return false;
     }
     conn.state = Connection.State.connecting;
     conn.channel = channel;
     selector.wakeup();
     channel.register(selector, SelectionKey.OP_CONNECT, conn);
   } catch (java.io.IOException ex) {
     logger.log(
         Level.WARNING,
         "java.io.IOException caught while initiating connection to '" + peer.host() + "'.",
         ex);
   }
   return true;
 }
示例#2
0
 private void handleWritable(Connection conn_) {
   TCPConnection conn = (TCPConnection) conn_;
   logger.log(Level.FINEST, "handleWritable():");
   ByteBuffer net_out_buffer = conn.connection_buffers.netOutBuffer();
   // int bytes = net_out_buffer.position();
   // net_out_buffer.rewind();
   // net_out_buffer.limit(bytes);
   net_out_buffer.flip();
   // logger.log(Level.FINEST,"                :bytes= " + bytes);
   int count;
   try {
     count = conn.channel.write(net_out_buffer);
     if (count < 0) {
       closeConnection(conn);
       return;
     }
     // conn.consumeNetOutBuffer(count);
     net_out_buffer.compact();
     conn.processAppOutBuffer();
     if (!conn.hasNetOutput()) conn.channel.register(selector, SelectionKey.OP_READ, conn);
   } catch (java.io.IOException ex) {
     closeConnection(conn);
     return;
   }
 }
示例#3
0
 private void handleReadable(TCPConnection conn) {
   logger.log(Level.FINEST, "handlereadable()...");
   conn.makeSpaceInNetInBuffer();
   ConnectionBuffers connection_buffers = conn.connection_buffers;
   logger.log(
       Level.FINEST,
       "pre: conn.in_buffer.position=" + connection_buffers.netInBuffer().position());
   int count;
   try {
     int loop_count = 0;
     while ((count = conn.channel.read(connection_buffers.netInBuffer())) > 0
         && loop_count++ < 3) {
       logger.log(
           Level.FINEST,
           "readloop: connection_buffers.netInBuffer().position="
               + connection_buffers.netInBuffer().position());
       conn.makeSpaceInNetInBuffer();
     }
   } catch (java.io.IOException ex) {
     logger.log(Level.FINE, "got IOException", ex);
     closeConnection(conn);
     return;
   }
   conn.processNetInBuffer();
   processInBuffer(conn);
   if (count < 0 && conn.state != Connection.State.closed) {
     logger.log(Level.FINE, "count<0");
     closeConnection(conn);
     return;
   }
 }
示例#4
0
 private void outputBecameAvailable(Connection conn_) {
   TCPConnection conn = (TCPConnection) conn_;
   handleWritable(conn);
   if (conn.hasNetOutput()) {
     try {
       conn.channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, conn);
     } catch (java.nio.channels.ClosedChannelException ex) {
     }
   }
 }
示例#5
0
  void sendMessage(TCPConnection conn, byte[] raw) {
    boolean was_empty = !conn.hasNetOutput();
    conn.makeSpaceInAppOutBuffer(raw.length);
    // System.out.println("sendMessage: A: position=" + out_buffer.position() + " limit=" +
    // conn.out_buffer.limit());
    conn.connection_buffers.appOutBuffer().put(raw);
    conn.connection_buffers.processAppOutBuffer();
    // System.out.println("sendMessage: B: position=" + out_buffer.position() + " limit=" +
    // conn.out_buffer.limit());

    if (was_empty) outputBecameAvailable(conn);
  }
示例#6
0
 private void processInBuffer(TCPConnection conn) {
   ByteBuffer app_in_buffer = conn.connection_buffers.appInBuffer();
   logger.log(Level.FINEST, "pre: app_in_buffer.position=" + app_in_buffer.position());
   int raw_bytes = app_in_buffer.position();
   byte[] raw = new byte[raw_bytes];
   app_in_buffer.position(0);
   app_in_buffer.get(raw);
   app_in_buffer.position(raw_bytes);
   int offset = 0;
   // System.out.println("processInBuffer():looping");
   while (offset < raw.length) {
     // System.out.println("processInBuffer(): inside loop offset=" + offset);
     int bytes_left = raw.length - offset;
     if (bytes_left < 4) break;
     int msg_size = Message.decodeSize(raw, offset);
     if (bytes_left < msg_size) break;
     Message msg = new Message();
     Message.decode_status status = msg.decode(raw, offset, msg_size);
     // System.out.println("processInBuffer():decoded, status=" + status);
     switch (status) {
       case decoded:
         {
           logRawDecodedPacket(raw, offset, msg_size);
           offset += msg_size;
           boolean b = handleMessage(msg, conn);
           if (!b) {
             logger.log(Level.FINER, "handle error");
             closeConnection(conn);
             return;
           }
           break;
         }
       case not_enough:
         break;
       case garbage:
         logGarbagePacket(conn, raw, offset, msg_size);
         closeConnection(conn, true);
         return;
     }
     if (status == Message.decode_status.not_enough) break;
   }
   conn.consumeAppInBuffer(offset);
   // System.out.println("processInBuffer(): the end");
 }
示例#7
0
    private void run_() throws java.io.IOException {
      if (serverChannel != null) {
        // set non-blocking mode for the listening socket
        serverChannel.configureBlocking(false);

        // register the ServerSocketChannel with the Selector
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
      }

      for (; ; ) {
        if (please_stop) {
          if (System.currentTimeMillis() >= shutdown_deadline) break;
          if (!anyOpenConnections()) break;
        }
        long timeout = calcNextTimeout();
        int n;
        // System.out.println("selecting...");
        if (timeout != -1) {
          long now = System.currentTimeMillis();
          if (timeout > now) n = selector.select(timeout - now);
          else n = selector.selectNow();
        } else n = selector.select();
        // System.out.println("Woke up from select()");

        // get an iterator over the set of selected keys
        Iterator it = selector.selectedKeys().iterator();
        // look at each key in the selected set
        while (it.hasNext()) {
          SelectionKey key = (SelectionKey) it.next();

          if (key.isAcceptable()) {
            logger.log(Level.FINE, "Got an inbound connection (key is acceptable)");
            ServerSocketChannel server = (ServerSocketChannel) key.channel();
            SocketChannel channel = server.accept();

            InetSocketAddress address =
                (InetSocketAddress) channel.socket().getRemoteSocketAddress();
            logger.log(Level.INFO, "Got an inbound connection from " + address.toString());
            if (!please_stop) {
              TCPConnection conn =
                  new TCPConnection(
                      TCPNode.this, settings.watchdogInterval(), settings.idleTimeout());
              conn.host_id = address.getAddress().getHostAddress();
              conn.state = Connection.State.connected_in;
              conn.channel = channel;
              channel.configureBlocking(false);
              channel.register(selector, SelectionKey.OP_READ, conn);

              registerInboundConnection(conn);

              // Devoteam Configure the CER/CEA sending
              boolean autoCERCEAEnable =
                  Config.getConfigByName("diameter.properties")
                      .getBoolean("capability.AUTO_CER_CEA_ENABLE", true);
              if (!autoCERCEAEnable) {
                getNode().sendCER(conn);
              }

            } else {
              // We don't want to add the connection if were are shutting down.
              channel.close();
            }
          } else if (key.isConnectable()) {
            logger.log(Level.FINE, "An outbound connection is ready (key is connectable)");
            SocketChannel channel = (SocketChannel) key.channel();
            TCPConnection conn = (TCPConnection) key.attachment();
            try {
              if (channel.finishConnect()) {
                logger.log(Level.FINEST, "Connected!");
                conn.state = Connection.State.connected_out;
                channel.register(selector, SelectionKey.OP_READ, conn);
                initiateCER(conn);
              }
            } catch (java.io.IOException ex) {
              logger.log(Level.WARNING, "Connection to '" + conn.host_id + "' failed", ex);
              try {
                channel.register(selector, 0);
                channel.close();
              } catch (java.io.IOException ex2) {
              }
              unregisterConnection(conn);
            }
          } else if (key.isReadable()) {
            logger.log(Level.FINEST, "Key is readable");
            // System.out.println("key is readable");
            SocketChannel channel = (SocketChannel) key.channel();
            TCPConnection conn = (TCPConnection) key.attachment();
            handleReadable(conn);
            if (conn.state != Connection.State.closed && conn.hasNetOutput())
              channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, conn);
          } else if (key.isWritable()) {
            logger.log(Level.FINEST, "Key is writable");
            SocketChannel channel = (SocketChannel) key.channel();
            TCPConnection conn = (TCPConnection) key.attachment();
            synchronized (getLockObject()) {
              handleWritable(conn);
              if (conn.state != Connection.State.closed && conn.hasNetOutput())
                channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, conn);
            }
          }

          // remove key from selected set, it's been handled
          it.remove();
        }

        runTimers();
      }

      // Remaining connections are close by Node instance

      // selector is closed in stop()
    }