private long waitForNextTick() {
      long deadline = startTime + tickDuration * tick;

      for (; ; ) {
        final long currentTime = System.currentTimeMillis();
        long sleepTime = tickDuration * tick - (currentTime - startTime);

        // Check if we run on windows, as if thats the case we will need
        // to round the sleepTime as workaround for a bug that only affect
        // the JVM if it runs on windows.
        //
        // See https://github.com/netty/netty/issues/356
        if (DetectionUtil.isWindows()) {
          sleepTime = sleepTime / 10 * 10;
        }

        if (sleepTime <= 0) {
          break;
        }

        try {
          Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
          if (shutdown.get()) {
            return -1;
          }
        }
      }

      // Increase the tick.
      tick++;
      return deadline;
    }
示例#2
0
    @Override
    public final void bind(final SocketAddress localAddress, final ChannelFuture future) {
      if (eventLoop().inEventLoop()) {
        if (!ensureOpen(future)) {
          return;
        }

        try {
          boolean wasActive = isActive();

          // See: https://github.com/netty/netty/issues/576
          if (!DetectionUtil.isWindows()
              && !DetectionUtil.isRoot()
              && Boolean.TRUE.equals(config().getOption(ChannelOption.SO_BROADCAST))
              && localAddress instanceof InetSocketAddress
              && !((InetSocketAddress) localAddress).getAddress().isAnyLocalAddress()) {
            // Warn a user about the fact that a non-root user can't receive a
            // broadcast packet on *nix if the socket is bound on non-wildcard address.
            logger.warn(
                "A non-root user can't receive a broadcast packet if the socket "
                    + "is not bound to a wildcard address; binding to a non-wildcard "
                    + "address ("
                    + localAddress
                    + ") anyway as requested.");
          }

          doBind(localAddress);
          future.setSuccess();
          if (!wasActive && isActive()) {
            pipeline.fireChannelActive();
          }
        } catch (Throwable t) {
          future.setFailure(t);
          closeIfClosed();
        }
      } else {
        eventLoop()
            .execute(
                new Runnable() {
                  @Override
                  public void run() {
                    bind(localAddress, future);
                  }
                });
      }
    }
示例#3
0
  /**
   * Checks if the given {@link Throwable} can be ignore and just "swallowed"
   *
   * <p>When an ssl connection is closed a close_notify message is sent. After that the peer also
   * sends close_notify however, it's not mandatory to receive the close_notify. The party who sent
   * the initial close_notify can close the connection immediately then the peer will get connection
   * reset error.
   */
  private boolean ignoreException(Throwable t) {
    if (!(t instanceof SSLException) && t instanceof IOException && engine.isOutboundDone()) {
      String message = String.valueOf(t.getMessage()).toLowerCase();

      // first try to match connection reset / broke peer based on the regex. This is the fastest
      // way
      // but may fail on different jdk impls or OS's
      if (IGNORABLE_ERROR_MESSAGE.matcher(message).matches()) {
        return true;
      }

      // Inspect the StackTraceElements to see if it was a connection reset / broken pipe or not
      StackTraceElement[] elements = t.getStackTrace();
      for (StackTraceElement element : elements) {
        String classname = element.getClassName();
        String methodname = element.getMethodName();

        // skip all classes that belong to the io.netty package
        if (classname.startsWith("io.netty.")) {
          continue;
        }

        // check if the method name is read if not skip it
        if (!"read".equals(methodname)) {
          continue;
        }

        // This will also match against SocketInputStream which is used by openjdk 7 and maybe
        // also others
        if (IGNORABLE_CLASS_IN_STACK.matcher(classname).matches()) {
          return true;
        }

        try {
          // No match by now.. Try to load the class via classloader and inspect it.
          // This is mainly done as other JDK implementations may differ in name of
          // the impl.
          Class<?> clazz = getClass().getClassLoader().loadClass(classname);

          if (SocketChannel.class.isAssignableFrom(clazz)
              || DatagramChannel.class.isAssignableFrom(clazz)) {
            return true;
          }

          // also match against SctpChannel via String matching as it may not present.
          if (DetectionUtil.javaVersion() >= 7
              && "com.sun.nio.sctp.SctpChannel".equals(clazz.getSuperclass().getName())) {
            return true;
          }
        } catch (ClassNotFoundException e) {
          // This should not happen just ignore
        }
      }
    }

    return false;
  }
 private void setOption0(Object option, Object value) {
   if (DetectionUtil.javaVersion() < 7) {
     throw new UnsupportedOperationException();
   } else {
     try {
       SET_OPTION.invoke(javaChannel, option, value);
     } catch (Exception e) {
       throw new ChannelException(e);
     }
   }
 }
 private Object getOption0(Object option) {
   if (DetectionUtil.javaVersion() < 7) {
     throw new UnsupportedOperationException();
   } else {
     try {
       return GET_OPTION.invoke(javaChannel, option);
     } catch (Exception e) {
       throw new ChannelException(e);
     }
   }
 }
  @Override
  public void setBroadcast(boolean broadcast) {
    try {
      // See: https://github.com/netty/netty/issues/576
      if (broadcast
          && !DetectionUtil.isWindows()
          && !DetectionUtil.isRoot()
          && !socket.getLocalAddress().isAnyLocalAddress()) {
        // Warn a user about the fact that a non-root user can't receive a
        // broadcast packet on *nix if the socket is bound on non-wildcard address.
        logger.warn(
            "A non-root user can't receive a broadcast packet if the socket "
                + "is not bound to a wildcard address; setting the SO_BROADCAST flag "
                + "anyway as requested on the socket which is bound to "
                + socket.getLocalSocketAddress()
                + '.');
      }

      socket.setBroadcast(broadcast);
    } catch (SocketException e) {
      throw new ChannelException(e);
    }
  }
示例#7
0
  private static DatagramChannel newSocket(InternetProtocolFamily ipFamily) {
    if (ipFamily == null) {
      return newSocket();
    }

    if (DetectionUtil.javaVersion() < 7) {
      throw new UnsupportedOperationException();
    }

    try {
      return DatagramChannel.open(ProtocolFamilyConverter.convert(ipFamily));
    } catch (IOException e) {
      throw new ChannelException("Failed to open a socket.", e);
    }
  }
 @Override
 public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
   if (DetectionUtil.javaVersion() < 7) {
     // XXX Gathering write is not supported because of a known issue.
     //     See http://bugs.sun.com/view_bug.do?bug_id=6210541
     return out.write(copiedNioBuffer(index, length));
   } else {
     long writtenBytes = out.write(nioBuffers(index, length));
     if (writtenBytes > Integer.MAX_VALUE) {
       return Integer.MAX_VALUE;
     } else {
       return (int) writtenBytes;
     }
   }
 }
示例#9
0
  @Override
  public ChannelFuture leaveGroup(
      InetAddress multicastAddress,
      NetworkInterface networkInterface,
      InetAddress source,
      ChannelPromise promise) {
    if (DetectionUtil.javaVersion() < 7) {
      throw new UnsupportedOperationException();
    }
    if (multicastAddress == null) {
      throw new NullPointerException("multicastAddress");
    }
    if (networkInterface == null) {
      throw new NullPointerException("networkInterface");
    }

    synchronized (this) {
      if (memberships != null) {
        List<MembershipKey> keys = memberships.get(multicastAddress);
        if (keys != null) {
          Iterator<MembershipKey> keyIt = keys.iterator();

          while (keyIt.hasNext()) {
            MembershipKey key = keyIt.next();
            if (networkInterface.equals(key.networkInterface())) {
              if (source == null && key.sourceAddress() == null
                  || source != null && source.equals(key.sourceAddress())) {
                key.drop();
                keyIt.remove();
              }
            }
          }
          if (keys.isEmpty()) {
            memberships.remove(multicastAddress);
          }
        }
      }
    }

    promise.setSuccess();
    return promise;
  }
示例#10
0
  @Override
  public ChannelFuture joinGroup(
      InetAddress multicastAddress,
      NetworkInterface networkInterface,
      InetAddress source,
      ChannelPromise promise) {
    if (DetectionUtil.javaVersion() >= 7) {
      if (multicastAddress == null) {
        throw new NullPointerException("multicastAddress");
      }

      if (networkInterface == null) {
        throw new NullPointerException("networkInterface");
      }

      try {
        MembershipKey key;
        if (source == null) {
          key = javaChannel().join(multicastAddress, networkInterface);
        } else {
          key = javaChannel().join(multicastAddress, networkInterface, source);
        }

        synchronized (this) {
          List<MembershipKey> keys = memberships.get(multicastAddress);
          if (keys == null) {
            keys = new ArrayList<MembershipKey>();
            memberships.put(multicastAddress, keys);
          }
          keys.add(key);
        }

        promise.setSuccess();
      } catch (Throwable e) {
        promise.setFailure(e);
      }
    } else {
      throw new UnsupportedOperationException();
    }
    return promise;
  }
示例#11
0
  /**
   * Block the given sourceToBlock address for the given multicastAddress on the given
   * networkInterface
   */
  @Override
  public ChannelFuture block(
      InetAddress multicastAddress,
      NetworkInterface networkInterface,
      InetAddress sourceToBlock,
      ChannelPromise promise) {
    if (DetectionUtil.javaVersion() < 7) {
      throw new UnsupportedOperationException();
    } else {
      if (multicastAddress == null) {
        throw new NullPointerException("multicastAddress");
      }
      if (sourceToBlock == null) {
        throw new NullPointerException("sourceToBlock");
      }

      if (networkInterface == null) {
        throw new NullPointerException("networkInterface");
      }
      synchronized (this) {
        if (memberships != null) {
          List<MembershipKey> keys = memberships.get(multicastAddress);
          for (MembershipKey key : keys) {
            if (networkInterface.equals(key.networkInterface())) {
              try {
                key.block(sourceToBlock);
              } catch (IOException e) {
                promise.setFailure(e);
              }
            }
          }
        }
      }
      promise.setSuccess();
      return promise;
    }
  }