diff --git a/core/src/main/scala/epollcat/internal/ch/EpollAsyncServerSocketChannel.scala b/core/src/main/scala/epollcat/internal/ch/EpollAsyncServerSocketChannel.scala index b6491de..ef0f506 100644 --- a/core/src/main/scala/epollcat/internal/ch/EpollAsyncServerSocketChannel.scala +++ b/core/src/main/scala/epollcat/internal/ch/EpollAsyncServerSocketChannel.scala @@ -29,7 +29,6 @@ import java.net.StandardSocketOptions import java.nio.channels.AsynchronousServerSocketChannel import java.nio.channels.AsynchronousSocketChannel import java.nio.channels.CompletionHandler -import java.nio.channels.UnsupportedAddressTypeException import java.util.concurrent.Future import scala.scalanative.annotation.stub import scala.scalanative.libc.errno @@ -71,36 +70,13 @@ final class EpollAsyncServerSocketChannel private (fd: Int) def getOption[T](name: SocketOption[T]): T = ??? def bind(local: SocketAddress, backlog: Int): AsynchronousServerSocketChannel = { - val addrinfo = stackalloc[Ptr[posix.netdb.addrinfo]]() - Zone { implicit z => - val addr = local.asInstanceOf[InetSocketAddress] - val hints = stackalloc[posix.netdb.addrinfo]() - hints.ai_family = posix.sys.socket.AF_INET - hints.ai_flags = posix.netdb.AI_NUMERICHOST | posix.netdb.AI_NUMERICSERV - hints.ai_socktype = posix.sys.socket.SOCK_STREAM - val rtn = posix - .netdb - .getaddrinfo( - toCString(addr.getAddress().getHostAddress()), - toCString(addr.getPort.toString), - hints, - addrinfo - ) - - if (rtn != 0) { - val ex = if (rtn == posix.netdb.EAI_FAMILY) { - new UnsupportedAddressTypeException() - } else { - val msg = s"getaddrinfo: ${SocketHelpers.getGaiErrorMessage(rtn)}" - new IOException(msg) - } - - throw ex - } + val addrinfo = SocketHelpers.toAddrinfo(local.asInstanceOf[InetSocketAddress]) match { + case Left(ex) => throw ex + case Right(addrinfo) => addrinfo } - val bindRet = posix.sys.socket.bind(fd, (!addrinfo).ai_addr, (!addrinfo).ai_addrlen) - posix.netdb.freeaddrinfo(!addrinfo) + val bindRet = posix.sys.socket.bind(fd, addrinfo.ai_addr, addrinfo.ai_addrlen) + posix.netdb.freeaddrinfo(addrinfo) // posix.errno.EADDRNOTAVAIL becomes available in Scala Native 0.5.0 val EADDRNOTAVAIL = diff --git a/core/src/main/scala/epollcat/internal/ch/EpollAsyncSocketChannel.scala b/core/src/main/scala/epollcat/internal/ch/EpollAsyncSocketChannel.scala index 5f11862..7d35c21 100644 --- a/core/src/main/scala/epollcat/internal/ch/EpollAsyncSocketChannel.scala +++ b/core/src/main/scala/epollcat/internal/ch/EpollAsyncSocketChannel.scala @@ -30,7 +30,6 @@ import java.nio.ByteBuffer import java.nio.channels.AsynchronousSocketChannel import java.nio.channels.ClosedChannelException import java.nio.channels.CompletionHandler -import java.nio.channels.UnsupportedAddressTypeException import java.util.concurrent.Future import java.util.concurrent.TimeUnit import scala.annotation.tailrec @@ -165,41 +164,15 @@ final class EpollAsyncSocketChannel private ( attachment: A, handler: CompletionHandler[Void, _ >: A] ): Unit = { - val addrinfo = stackalloc[Ptr[posix.netdb.addrinfo]]() - - val continue = Zone { implicit z => - val addr = remote.asInstanceOf[InetSocketAddress] - val hints = stackalloc[posix.netdb.addrinfo]() - hints.ai_family = posix.sys.socket.AF_INET - hints.ai_flags = posix.netdb.AI_NUMERICHOST | posix.netdb.AI_NUMERICSERV - hints.ai_socktype = posix.sys.socket.SOCK_STREAM - val rtn = posix - .netdb - .getaddrinfo( - toCString(addr.getAddress().getHostAddress()), - toCString(addr.getPort.toString), - hints, - addrinfo - ) - if (rtn == 0) { - true - } else { - val ex = if (rtn == posix.netdb.EAI_FAMILY) { - new UnsupportedAddressTypeException() - } else { - val msg = s"getaddrinfo: ${SocketHelpers.getGaiErrorMessage(rtn)}" - new IOException(msg) - } - handler.failed(ex, attachment) - false - } + val addrinfo = SocketHelpers.toAddrinfo(remote.asInstanceOf[InetSocketAddress]) match { + case Left(ex) => + return handler.failed(ex, attachment) + case Right(addrinfo) => addrinfo } - if (!continue) - return () + val conRet = posix.sys.socket.connect(fd, addrinfo.ai_addr, addrinfo.ai_addrlen) + posix.netdb.freeaddrinfo(addrinfo) - val conRet = posix.sys.socket.connect(fd, (!addrinfo).ai_addr, (!addrinfo).ai_addrlen) - posix.netdb.freeaddrinfo(!addrinfo) if (conRet == -1 && errno.errno != posix.errno.EINPROGRESS) { val ex = errno.errno match { case e if e == posix.errno.ECONNREFUSED => diff --git a/core/src/main/scala/epollcat/internal/ch/SocketHelpers.scala b/core/src/main/scala/epollcat/internal/ch/SocketHelpers.scala index 13d555c..2628642 100644 --- a/core/src/main/scala/epollcat/internal/ch/SocketHelpers.scala +++ b/core/src/main/scala/epollcat/internal/ch/SocketHelpers.scala @@ -20,9 +20,11 @@ import java.io.IOException import java.net.InetAddress import java.net.InetSocketAddress import java.net.SocketAddress +import java.nio.channels.UnsupportedAddressTypeException import scala.scalanative.libc.errno import scala.scalanative.meta.LinktimeInfo import scala.scalanative.posix +import scala.scalanative.posix.netdbOps._ import scala.scalanative.posix.netinet.inOps._ import scala.scalanative.unsafe._ @@ -120,6 +122,34 @@ private[ch] object SocketHelpers { new InetSocketAddress(inetAddr, port) } + def toAddrinfo(addr: InetSocketAddress): Either[Throwable, Ptr[posix.netdb.addrinfo]] = Zone { + implicit z => + val addrinfo = stackalloc[Ptr[posix.netdb.addrinfo]]() + val hints = stackalloc[posix.netdb.addrinfo]() + hints.ai_family = posix.sys.socket.AF_INET + hints.ai_flags = posix.netdb.AI_NUMERICHOST | posix.netdb.AI_NUMERICSERV + hints.ai_socktype = posix.sys.socket.SOCK_STREAM + val rtn = posix + .netdb + .getaddrinfo( + toCString(addr.getAddress().getHostAddress()), + toCString(addr.getPort.toString), + hints, + addrinfo + ) + if (rtn == 0) { + Right(!addrinfo) + } else { + val ex = if (rtn == posix.netdb.EAI_FAMILY) { + new UnsupportedAddressTypeException() + } else { + val msg = s"getaddrinfo: ${SocketHelpers.getGaiErrorMessage(rtn)}" + new IOException(msg) + } + Left(ex) + } + } + // Return text translation of getaddrinfo (gai) error code. def getGaiErrorMessage(gaiErrorCode: CInt): String = { fromCString(posix.netdb.gai_strerror(gaiErrorCode))