Пример #1
0
  /**
   * get a socket option
   *
   * @param socket socket descriptor
   * @param option_name
   * @throws IOException on error
   */
  public int getSockOpt(int socket, int option_name) throws IOException {
    IntByReference value = new IntByReference(0);
    IntByReference opt_len = new IntByReference(4);
    if (DEBUG) {
      System.out.println("getsockopt(" + socket + ", " + option_name + ")");
    }

    int err = sockets.getsockopt(socket, Socket.SOL_SOCKET, option_name, value, opt_len);
    int result = value.getValue();
    value.free();
    if (false) Assert.that(opt_len.getValue() == 4);
    opt_len.free();
    LibCUtil.errCheckNeg(err);
    return result;
  }
Пример #2
0
  /**
   * set a socket option
   *
   * @param socket socket descriptor
   * @param level Socket.SOL_SOCKET, etc.
   * @param option_name
   * @param option_value new value
   * @throws IOException on error
   */
  public void setSockOpt(int socket, int level, int option_name, int option_value)
      throws IOException {
    IntByReference value = new IntByReference(option_value);
    if (false) Assert.that(option_value == value.getValue());
    if (DEBUG) {
      System.out.println(
          "setSockOpt(" + socket + ", " + level + ", " + option_name + ", " + option_value + ")");
    }
    int err = sockets.setsockopt(socket, level, option_name, value, 4);

    if (false) Assert.that(option_value == value.getValue());
    value.free();
    LibCUtil.errCheckNeg(err);

    if (DEBUG) {
      int newValue = getSockOpt(socket, level, option_name);
      if (option_value != newValue) {
        System.out.println(
            "FAILED: setSockOpt("
                + socket
                + ", "
                + level
                + ", "
                + option_name
                + ", "
                + option_value
                + ")");
        System.err.println("   Ended with: " + newValue);
      }
    }
  }
Пример #3
0
  /**
   * Opens a server TCP connection to clients. Creates, binds, and listens
   *
   * @param port local TCP port to listen on
   * @param backlog listen backlog.
   * @return a native handle to the network connection.
   * @throws IOException
   */
  public int openServer(int port, int backlog) throws IOException {
    int fd = -1;

    fd = Socket.INSTANCE.socket(Socket.AF_INET, Socket.SOCK_STREAM, 0);
    if (fd < 0) {
      throw newError(fd, "socket create");
    }

    set_blocking_flags(fd, /*is_blocking*/ false);

    IntByReference option_val = new IntByReference(1);
    if (sockets.setsockopt(fd, Socket.SOL_SOCKET, Socket.SO_REUSEADDR, option_val, 4) < 0) {
      throw newError(fd, "setSockOpt");
    }
    option_val.free();

    Socket.sockaddr_in local_sin = new Socket.sockaddr_in();
    local_sin.sin_family = Socket.AF_INET;
    local_sin.sin_port = Inet.htons((short) port);
    local_sin.sin_addr = Socket.INADDR_ANY;
    if (sockets.bind(fd, local_sin) < 0) {
      throw newError(fd, "bind");
    }

    if (sockets.listen(fd, backlog) < 0) {
      throw newError(fd, "listen");
    }

    return fd;
  }
Пример #4
0
 /**
  * Takes an IPv4 Internet address and returns string representing the address in `.' notation
  *
  * @param in the opaque bytes of an IPv4 "struct in_addr"
  * @return String
  */
 public String inet_ntop(int in) {
   Pointer charBuf = new Pointer(Socket.INET_ADDRSTRLEN);
   IntByReference addrBuf = new IntByReference(in); // the addr is passed by value (to handle IPv6)
   String result = sockets.inet_ntop(Socket.AF_INET, addrBuf, charBuf, Socket.INET_ADDRSTRLEN);
   addrBuf.free();
   charBuf.free();
   return result;
 }
Пример #5
0
  /**
   * Accept client connections on server socket fd. Blocks until a client connects.
   *
   * @param fd open server socket. See {@link #openServer}.
   * @return a native handle to the network connection.
   * @throws IOException
   */
  public int accept(int fd) throws IOException {
    VMThread.getSystemEvents().waitForReadEvent(fd);

    Socket.sockaddr_in remote_sin = new Socket.sockaddr_in();
    IntByReference address_len = new IntByReference(4);
    int newSocket = sockets.accept(fd, remote_sin, address_len);
    if (newSocket < 0) {
      throw newError(fd, "accept");
    }
    address_len.free();
    set_blocking_flags(newSocket, /*is_blocking*/ false);
    // we could read info about client from remote_sin, but don't need to.

    return newSocket;
  }
Пример #6
0
  private void set_blocking_flags(int fd, boolean is_blocking) throws IOException {
    if (tryFcntl) {
      int flags = libc.fcntl(fd, LibC.F_GETFL, 0);
      if (DEBUG) {
        System.out.println("set_blocking_flags: fcntl F_GETFL = " + flags);
      }

      if (flags >= 0) {
        if (is_blocking == true) {
          flags &= ~LibC.O_NONBLOCK;
        } else {
          flags |= LibC.O_NONBLOCK;
        }
        if (DEBUG) {
          System.out.println("set_blocking_flags: calling fcntl F_SETFL flags: " + flags);
        }
        int res = libc.fcntl(fd, LibC.F_SETFL, flags);
        if (res != -1) {
          return;
        }
      } else if (LibCUtil.errno() == LibC.EOPNOTSUPP) {
        tryFcntl = false; // once this fails, don't try again
      }
    }

    if (!tryFcntl) {
      if (DEBUG) {
        System.out.println("set_blocking_flags: calling ioctl FIONBIO = " + !is_blocking);
      }
      IntByReference setting =
          new IntByReference(is_blocking ? 0 : 1); /* if "is_blocking"==true, NBIO = FALSE */
      int res = ioctl.ioctl(fd, Ioctl.FIONBIO, setting);
      setting.free();
      if (DEBUG) {
        System.out.println("set_blocking_flags: ioctl returned: " + res);
      }
      if (res >= 0) {
        return;
      }
    }
    throw newError(fd, "set_blocking_flags");
  }
Пример #7
0
  /**
   * Accept client connections on server socket fd. Blocks until a client connects.
   *
   * @param fd open server socket. See {@link #openServer}.
   * @return a native handle to the network connection.
   * @throws IOException
   */
  public int accept(int fd) throws IOException {
    Socket.sockaddr_in remote_sin = new Socket.sockaddr_in();
    IntByReference address_len = new IntByReference(4);
    int newSocket;

    try {
      if (DEBUG) {
        System.err.println("Socket.accept(" + fd + ", " + remote_sin + ")...");
      }

      newSocket = sockets.accept(fd, remote_sin, address_len);

      if (newSocket < 0) {
        if (DEBUG) {
          System.err.println("Need to block for accept...");
        }

        int err_code = LibCUtil.errno();
        if (err_code == LibC.EAGAIN || err_code == LibC.EWOULDBLOCK) {
          VMThread.getSystemEvents().waitForReadEvent(fd);
          newSocket = sockets.accept(fd, remote_sin, address_len);
          if (newSocket < 0) {
            throw newError(fd, "accept");
          }
        } else {
          // BUG!
          throw newError(fd, "accept");
        }
      }
    } finally {
      address_len.free();
    }

    set_blocking_flags(newSocket, /*is_blocking*/ false);
    // we could read info about client from remote_sin, but don't need to.

    if (DEBUG) {
      System.err.println("    Socket.accept(...) = " + newSocket);
    }
    return newSocket;
  }
Пример #8
0
 /**
  * set a socket option
  *
  * @param socket socket descriptor
  * @param option_name
  * @param option_value new value
  * @throws IOException on error
  */
 public void setSockOpt(int socket, int option_name, int option_value) throws IOException {
   IntByReference value = new IntByReference(option_value);
   int err = sockets.setsockopt(socket, Socket.SOL_SOCKET, option_name, value, 4);
   value.free();
   LibCUtil.errCheckNeg(err);
 }