Skip to content

Commit

Permalink
Merge pull request #49 from armanbilge/pr/refactor-toaddrinfo
Browse files Browse the repository at this point in the history
Factor out `toAddrinfo` helper
  • Loading branch information
armanbilge authored Sep 13, 2022
2 parents cadf46c + 2f6577f commit 212d44e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 =>
Expand Down
30 changes: 30 additions & 0 deletions core/src/main/scala/epollcat/internal/ch/SocketHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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._

Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 212d44e

Please sign in to comment.