public DatagramChannel connect(SocketAddress sa) throws IOException {
    int localPort = 0;

    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          ensureOpenAndUnconnected();
          InetSocketAddress isa = Net.checkAddress(sa);
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
          int n = Net.connect(family, fd, isa.getAddress(), isa.getPort());
          if (n <= 0) throw new Error(); // Can't happen

          // Connection succeeded; disallow further invocation
          state = ST_CONNECTED;
          remoteAddress = sa;
          sender = isa;
          cachedSenderInetAddress = isa.getAddress();
          cachedSenderPort = isa.getPort();

          // set or refresh local address
          localAddress = Net.localAddress(fd);
        }
      }
    }
    return this;
  }
  @Override
  public DatagramChannel bind(SocketAddress local) throws IOException {
    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          ensureOpen();
          if (localAddress != null) throw new AlreadyBoundException();
          InetSocketAddress isa;
          if (local == null) {
            // only Inet4Address allowed with IPv4 socket
            if (family == StandardProtocolFamily.INET) {
              isa = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0);
            } else {
              isa = new InetSocketAddress(0);
            }
          } else {
            isa = Net.checkAddress(local);

            // only Inet4Address allowed with IPv4 socket
            if (family == StandardProtocolFamily.INET) {
              InetAddress addr = isa.getAddress();
              if (!(addr instanceof Inet4Address)) throw new UnsupportedAddressTypeException();
            }
          }
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) {
            sm.checkListen(isa.getPort());
          }
          Net.bind(family, fd, isa.getAddress(), isa.getPort());
          localAddress = Net.localAddress(fd);
        }
      }
    }
    return this;
  }
  public boolean connect(SocketAddress sa) throws IOException {
    int trafficClass = 0; // ## Pick up from options
    int localPort = 0;

    synchronized (readLock) {
      synchronized (writeLock) {
        ensureOpenAndUnconnected();
        InetSocketAddress isa = Net.checkAddress(sa);
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
        synchronized (blockingLock()) {
          int n = 0;
          try {
            try {
              begin();
              synchronized (stateLock) {
                if (!isOpen()) {
                  return false;
                }
                readerThread = NativeThread.current();
              }
              for (; ; ) {
                InetAddress ia = isa.getAddress();
                if (ia.isAnyLocalAddress()) ia = InetAddress.getLocalHost();
                n = connectImpl(ia, isa.getPort(), trafficClass);
                if ((n == IOStatus.INTERRUPTED) && isOpen()) continue;
                break;
              }
            } finally {
              readerCleanup();
              end((n > 0) || (n == IOStatus.UNAVAILABLE));
              assert IOStatus.check(n);
            }
          } catch (IOException x) {
            // If an exception was thrown, close the channel after
            // invoking end() so as to avoid bogus
            // AsynchronousCloseExceptions
            close();
            throw x;
          }
          synchronized (stateLock) {
            remoteAddress = isa;
            if (n > 0) {

              // Connection succeeded; disallow further
              // invocation
              state = ST_CONNECTED;
              return true;
            }
            // If nonblocking and no exception then connection
            // pending; disallow another invocation
            if (!isBlocking()) state = ST_PENDING;
            else assert false;
          }
        }
        return false;
      }
    }
  }
  public int send(ByteBuffer src, SocketAddress target) throws IOException {
    if (src == null) throw new NullPointerException();

    synchronized (writeLock) {
      ensureOpen();
      InetSocketAddress isa = (InetSocketAddress) target;
      InetAddress ia = isa.getAddress();
      if (ia == null) throw new IOException("Target address not resolved");
      synchronized (stateLock) {
        if (!isConnected()) {
          if (target == null) throw new NullPointerException();
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) {
            if (ia.isMulticastAddress()) {
              sm.checkMulticast(isa.getAddress());
            } else {
              sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
            }
          }
        } else { // Connected case; Check address then write
          if (!target.equals(remoteAddress)) {
            throw new IllegalArgumentException("Connected address not equal to target address");
          }
          return write(src);
        }
      }

      int n = 0;
      try {
        begin();
        if (!isOpen()) return 0;
        writerThread = NativeThread.current();
        do {
          n = send(fd, src, target);
        } while ((n == IOStatus.INTERRUPTED) && isOpen());

        synchronized (stateLock) {
          if (isOpen() && (localAddress == null)) {
            localAddress = Net.localAddress(fd);
          }
        }
        return IOStatus.normalize(n);
      } finally {
        writerThread = 0;
        end((n > 0) || (n == IOStatus.UNAVAILABLE));
        assert IOStatus.check(n);
      }
    }
  }
  @Override
  public DatagramChannel connect(SocketAddress sa) throws IOException {
    int localPort = 0;

    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          ensureOpenAndUnconnected();
          InetSocketAddress isa = Net.checkAddress(sa);
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
          int n = Net.connect(family, fd, isa.getAddress(), isa.getPort());
          if (n <= 0) throw new Error(); // Can't happen

          // Connection succeeded; disallow further invocation
          state = ST_CONNECTED;
          remoteAddress = isa;
          sender = isa;
          cachedSenderInetAddress = isa.getAddress();
          cachedSenderPort = isa.getPort();

          // set or refresh local address
          localAddress = Net.localAddress(fd);

          // flush any packets already received.
          boolean blocking = false;
          synchronized (blockingLock()) {
            try {
              blocking = isBlocking();
              // remainder of each packet thrown away
              ByteBuffer tmpBuf = ByteBuffer.allocate(1);
              if (blocking) {
                configureBlocking(false);
              }
              do {
                tmpBuf.clear();
              } while (receive(tmpBuf) != null);
            } finally {
              if (blocking) {
                configureBlocking(true);
              }
            }
          }
        }
      }
    }
    return this;
  }
  private DatagramChannel connectClient() throws IOException {
    final DatagramChannel client =
        address.isMulticastAddress()
            ? DatagramChannel.open(address.getAddress().length == 4 ? INET : INET6)
            : DatagramChannel.open();

    final InetSocketAddress hostAddress = new InetSocketAddress(port);
    client.configureBlocking(false);
    if (address.isMulticastAddress()) {
      client.setOption(SO_REUSEADDR, true);
      client.bind(hostAddress);
      if (networkInterface != null) {
        // This is probably not needed, because client socket doesn't send datagrams,
        // but since EVERYBODY on the internet configures this for any channels, and
        // I don't see any harm this config could make, I leave it here
        client.setOption(IP_MULTICAST_IF, networkInterface);
        client.join(address, networkInterface);
      } else {
        client.join(address, NetworkInterface.getByInetAddress(hostAddress.getAddress()));
      }
      if (LOG.isDebugEnabled()) LOG.debug("Connecting via multicast, group=" + address);
    } else {
      client.bind(hostAddress);
    }

    if (LOG.isDebugEnabled()) LOG.debug("Listening on port " + port);
    closeables.add(client);
    return client;
  }
  private int sendFromManagedBuffer(FileDescriptor fd, ByteBuffer bb, InetSocketAddress target)
      throws IOException {
    int pos = bb.position();
    int lim = bb.limit();
    assert (pos <= lim);
    int rem = (pos <= lim ? lim - pos : 0);

    boolean preferIPv6 = (family != StandardProtocolFamily.INET);
    int written;
    try {
      written =
          send0(
              preferIPv6,
              fd,
              bb.array(),
              bb.arrayOffset() + pos,
              rem,
              target.getAddress(),
              target.getPort());
    } catch (PortUnreachableException pue) {
      if (isConnected()) throw pue;
      written = rem;
    }
    if (written > 0) bb.position(pos + written);
    return written;
  }
  @Override
  <A> Future<Void> implConnect(
      SocketAddress remote, A attachment, CompletionHandler<Void, ? super A> handler) {
    if (!isOpen()) {
      Throwable exc = new ClosedChannelException();
      if (handler == null) return CompletedFuture.withFailure(exc);
      Invoker.invoke(this, handler, attachment, null, exc);
      return null;
    }

    InetSocketAddress isa = Net.checkAddress(remote);

    // permission check
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());

    // check and update state
    // ConnectEx requires the socket to be bound to a local address
    IOException bindException = null;
    synchronized (stateLock) {
      if (state == ST_CONNECTED) throw new AlreadyConnectedException();
      if (state == ST_PENDING) throw new ConnectionPendingException();
      if (localAddress == null) {
        try {
          bind(new InetSocketAddress(0));
        } catch (IOException x) {
          bindException = x;
        }
      }
      if (bindException == null) state = ST_PENDING;
    }

    // handle bind failure
    if (bindException != null) {
      try {
        close();
      } catch (IOException ignore) {
      }
      if (handler == null) return CompletedFuture.withFailure(bindException);
      Invoker.invoke(this, handler, attachment, null, bindException);
      return null;
    }

    // setup task
    PendingFuture<Void, A> result = new PendingFuture<Void, A>(this, handler, attachment);
    ConnectTask task = new ConnectTask<A>(isa, result);
    result.setContext(task);

    // initiate I/O
    if (Iocp.supportsThreadAgnosticIo()) {
      task.run();
    } else {
      Invoker.invokeOnThreadInThreadPool(this, task);
    }
    return result;
  }
 public void bind(SocketAddress local) throws IOException {
   synchronized (readLock) {
     synchronized (writeLock) {
       synchronized (stateLock) {
         ensureOpenAndUnconnected();
         if (localAddress != null) throw new AlreadyBoundException();
         InetSocketAddress isa = Net.checkAddress(local);
         Net.bind(fd, isa.getAddress(), isa.getPort());
         localAddress = Net.localAddress(fd);
       }
     }
   }
 }
 public SocketAddress receive(ByteBuffer dst) throws IOException {
   if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer");
   if (dst == null) throw new NullPointerException();
   synchronized (readLock) {
     ensureOpen();
     // Socket was not bound before attempting receive
     if (localAddress() == null) bind(null);
     int n = 0;
     ByteBuffer bb = null;
     try {
       begin();
       if (!isOpen()) return null;
       SecurityManager security = System.getSecurityManager();
       readerThread = NativeThread.current();
       if (isConnected() || (security == null)) {
         do {
           n = receive(fd, dst);
         } while ((n == IOStatus.INTERRUPTED) && isOpen());
         if (n == IOStatus.UNAVAILABLE) return null;
       } else {
         bb = Util.getTemporaryDirectBuffer(dst.remaining());
         for (; ; ) {
           do {
             n = receive(fd, bb);
           } while ((n == IOStatus.INTERRUPTED) && isOpen());
           if (n == IOStatus.UNAVAILABLE) return null;
           InetSocketAddress isa = (InetSocketAddress) sender;
           try {
             security.checkAccept(isa.getAddress().getHostAddress(), isa.getPort());
           } catch (SecurityException se) {
             // Ignore packet
             bb.clear();
             n = 0;
             continue;
           }
           bb.flip();
           dst.put(bb);
           break;
         }
       }
       return sender;
     } finally {
       if (bb != null) Util.releaseTemporaryDirectBuffer(bb);
       readerThread = 0;
       end((n > 0) || (n == IOStatus.UNAVAILABLE));
       assert IOStatus.check(n);
     }
   }
 }
  public DatagramChannel disconnect() throws IOException {
    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          if (!isConnected() || !isOpen()) return this;
          InetSocketAddress isa = (InetSocketAddress) remoteAddress;
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
          disconnect0(fd);
          remoteAddress = null;
          state = ST_UNCONNECTED;

          // refresh local address
          localAddress = Net.localAddress(fd);
        }
      }
    }
    return this;
  }
 protected synchronized Message receiveMessage() throws IOException {
   if (messageBuffer.size() > 0) {
     Message m = (Message) messageBuffer.get(0);
     messageBuffer.remove(0);
     return m;
   }
   try {
     InetSocketAddress remoteAddress = (InetSocketAddress) channel.receive(receiveBuffer);
     if (remoteAddress != null) {
       int len = receiveBuffer.position();
       receiveBuffer.rewind();
       receiveBuffer.get(buf, 0, len);
       try {
         IP address = IP.fromInetAddress(remoteAddress.getAddress());
         int port = remoteAddress.getPort();
         extractor.appendData(buf, 0, len, new SocketDescriptor(address, port));
         receiveBuffer.clear();
         extractor.updateAvailableMessages();
         return extractor.nextMessage();
       } catch (EOFException exc) {
         exc.printStackTrace();
         System.err.println(buf.length + ", " + len);
       } catch (InvocationTargetException exc) {
         exc.printStackTrace();
       } catch (IllegalAccessException exc) {
         exc.printStackTrace();
       } catch (InstantiationException exc) {
         exc.printStackTrace();
       } catch (IllegalArgumentException e) {
         e.printStackTrace();
       } catch (InvalidCompressionMethodException e) {
         e.printStackTrace();
       }
     }
   } catch (ClosedChannelException exc) {
     if (isKeepAlive()) {
       throw exc;
     }
   }
   return null;
 }
    /** Task to initiate a connection. */
    @Override
    public void run() {
      long overlapped = 0L;
      Throwable exc = null;
      try {
        begin();

        // synchronize on result to allow this thread handle the case
        // where the connection is established immediately.
        synchronized (result) {
          overlapped = ioCache.add(result);
          // initiate the connection
          int n =
              connect0(
                  handle, Net.isIPv6Available(), remote.getAddress(), remote.getPort(), overlapped);
          if (n == IOStatus.UNAVAILABLE) {
            // connection is pending
            return;
          }

          // connection established immediately
          afterConnect();
          result.setResult(null);
        }
      } catch (Throwable x) {
        if (overlapped != 0L) ioCache.remove(overlapped);
        exc = x;
      } finally {
        end();
      }

      if (exc != null) {
        closeChannel();
        result.setFailure(toIOException(exc));
      }
      Invoker.invoke(result);
    }
  /** reads in an rdp packet from the datagram channel - blocking call */
  static RDPPacket receivePacket(DatagramChannel dc) throws ClosedChannelException {
    try {
      if (dc == null) {
        throw new MVRuntimeException("RDPServer.receivePacket: datagramChannel is null");
      }

      // get a packet from the reader
      staticMVBuff.rewind();
      InetSocketAddress addr = (InetSocketAddress) dc.receive(staticMVBuff.getNioBuf());
      if (addr == null) {
        return null;
      }

      RDPPacket packet = new RDPPacket();
      packet.setPort(addr.getPort());
      packet.setInetAddress(addr.getAddress());
      packet.parse(staticMVBuff);
      return packet;
    } catch (ClosedChannelException ex) {
      throw ex;
    } catch (Exception e) {
      throw new MVRuntimeException("error", e);
    }
  }
 public UDPMessageServer(InetSocketAddress address) throws IOException {
   this(IP.fromInetAddress(address.getAddress()), address.getPort());
 }
Beispiel #16
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()
    }