Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
1cd3d23
Initial wip using builder pattern
mpilquist Apr 8, 2025
5e5b39e
Generalize NeedAddress
mpilquist Apr 8, 2025
5e27b71
Dump builder pattern
mpilquist Apr 8, 2025
a86b18d
wip
mpilquist Apr 8, 2025
c06e969
wip
mpilquist Apr 9, 2025
eff4b58
wip
mpilquist Apr 9, 2025
89362b0
wip
mpilquist Apr 10, 2025
fcd9233
wip
mpilquist Apr 10, 2025
5e912ab
Drop JVM socket group implementations
mpilquist Apr 10, 2025
7081b7a
Unix socket tests
mpilquist Apr 10, 2025
dedda55
Unix socket tests
mpilquist Apr 10, 2025
17ade5c
Cleanup Bind
mpilquist Apr 10, 2025
e2fafad
s/Bind/ServerSocket/
mpilquist Apr 10, 2025
fad0e04
Push old localAddress back down to Socket
mpilquist Apr 10, 2025
598d3ed
Native
mpilquist Apr 11, 2025
b649d00
JS tests passing
mpilquist Apr 16, 2025
4a00566
JS duplication reduction
mpilquist Apr 16, 2025
e22041b
Scalafmt
mpilquist Apr 16, 2025
906d8d5
Fix compilation errors
mpilquist Apr 17, 2025
058e616
Implement getLocalAddressGen on JVM
mpilquist Apr 17, 2025
7648b71
Cleanup
mpilquist Apr 18, 2025
01322d5
Progress on fixing addresses
mpilquist Apr 18, 2025
42773ce
Fixed addresses
mpilquist Apr 18, 2025
6de7fbe
Scalafmt
mpilquist Apr 18, 2025
4399a1a
Test unix socket addresses
mpilquist Apr 18, 2025
18eb5d2
IP address tests
mpilquist Apr 18, 2025
1e9703e
Socket option cleanup
mpilquist Apr 18, 2025
f27f191
Socket option cleanup
mpilquist Apr 18, 2025
5285acb
Socket option cleanup
mpilquist Apr 18, 2025
78bc8cc
Deprecate old socket group methods
mpilquist Apr 18, 2025
a0ab96b
Address cleanup
mpilquist Apr 19, 2025
8c28c69
Add address and peerAddress, deprecate localAddress and remoteAddress
mpilquist Apr 20, 2025
6533318
Deprecate Socket#isOpen
mpilquist Apr 21, 2025
e7ca920
Remove some unnecesssary changes from net facade
mpilquist Apr 21, 2025
f4bc9c8
Cleanup in selecting ip sockets provider
mpilquist Apr 21, 2025
896738a
Unify Network implementations
mpilquist Apr 21, 2025
e47817c
Fix 2.12 compilation
mpilquist Apr 21, 2025
f3c5f70
Update to ip4s 3.7.0
mpilquist Apr 21, 2025
0ee5c57
Fix JS 2.12 compilation
mpilquist Apr 21, 2025
0807afb
Mima fixes
mpilquist Apr 21, 2025
91c25f6
Fix native 2.12 warnings
mpilquist Apr 21, 2025
861f7ea
Fix selecting socket address NPE
mpilquist Apr 21, 2025
7395a77
Fix JVM unix sockets test
mpilquist Apr 21, 2025
8a0df13
Fix site docs
mpilquist Apr 21, 2025
47815b2
Deprecate old UnixSockets
mpilquist Apr 21, 2025
5af859e
Set client socket options on JVM Unix
mpilquist Apr 22, 2025
e09f425
Remove explicit DNS lookups from JS IP socket connect & bind
mpilquist Apr 23, 2025
c063029
Scalafmt
mpilquist Apr 23, 2025
6c7f330
Make SO_REUSEPORT lazy loaded
mpilquist May 5, 2025
21af914
Merge branch 'main' into topic/net2
mpilquist May 9, 2025
3df2f3d
Revamped datagram support
mpilquist Jun 4, 2025
9ef0cf7
Remove accidentally added PeerCredentials
mpilquist Jun 4, 2025
72b1197
Fix test compilation
mpilquist Jun 4, 2025
7a83700
Fix mima warnings
mpilquist Jun 4, 2025
4248d68
Scalafmt
mpilquist Jun 4, 2025
e6aeb4d
Fix warnings
mpilquist Jun 4, 2025
e0d78b7
Fix warnings
mpilquist Jun 4, 2025
8542919
Add temp debug to UnixDatagramSuite
mpilquist Jun 5, 2025
dac60c1
Scalafmt
mpilquist Jun 5, 2025
d963953
Debug
mpilquist Jun 5, 2025
73f640d
Debug
mpilquist Jun 5, 2025
e02d9e5
Exclude UnixDatagramSuite from Linux due to bug in jnr-unixsocket
mpilquist Jun 5, 2025
8488321
Bridge deprecated datagram soccket options
mpilquist Jun 6, 2025
645f93f
Docs
mpilquist Jun 9, 2025
4d2924c
Scalafmt
mpilquist Jun 9, 2025
855070e
Scalafmt
mpilquist Jun 9, 2025
c4c9ee3
Add support for ip4s NetworkInterface
mpilquist Jun 22, 2025
562cbc5
Mima
mpilquist Jun 22, 2025
e8721b0
Bump to ip4s 3.8.0-RC1
mpilquist Jun 26, 2025
05e5e99
Bump to ip4s 3.8.0-RC1
mpilquist Jun 26, 2025
e6a8728
Merge branch 'main' into topic/net2
mpilquist Jun 26, 2025
426ceaa
Merge branch 'main' into topic/net2
mpilquist Jul 11, 2025
80642f9
Merge branch 'main' into topic/net2
mpilquist Aug 4, 2025
0bf4faf
Merge branch 'main' into topic/net2
mpilquist Aug 25, 2025
1153afa
Merge branch 'main' into topic/net2
mpilquist Aug 25, 2025
6e49f13
Scalafmt
mpilquist Aug 25, 2025
02d73e5
Downgrade GHA runner for macos to fix multicast tests
mpilquist Aug 25, 2025
b05bd18
Merge branch 'main' into topic/net2
mpilquist Aug 26, 2025
de6e955
Address deprecation warnings
mpilquist Aug 26, 2025
cf74c2d
Merge branch 'main' into topic/net2
mpilquist Sep 1, 2025
fe722ce
Update fromKeyStoreFile to take a Path and improve error message from…
mpilquist Sep 2, 2025
17f6852
Fix 2.12 compilation
mpilquist Sep 2, 2025
01f139d
Fix spinloop bug in TLSEngine
mpilquist Sep 3, 2025
57ab186
Drop .only tag
mpilquist Sep 3, 2025
ea03a6e
Change byte limit in test
mpilquist Sep 3, 2025
1d91556
Change explicit intercept to attempt to handle behavior differences o…
mpilquist Sep 3, 2025
fad230e
Rewrote test to be an example of a client that only sends partial han…
mpilquist Sep 4, 2025
39f1318
Merge pull request #3599 from typelevel/topic/fix-spinloop-in-tlsengine
mpilquist Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ lazy val io = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.settings(
name := "fs2-io",
tlVersionIntroduced ~= { _.updated("3", "3.1.0") },
libraryDependencies += "com.comcast" %%% "ip4s-core" % "3.6.0",
libraryDependencies += "com.comcast" %%% "ip4s-core" % "3.6.0-91-51bd018-SNAPSHOT",
tlJdkRelease := None
)
.jvmSettings(
Expand Down
25 changes: 19 additions & 6 deletions io/jvm/src/main/scala/fs2/io/net/NetworkPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import cats.effect.LiftIO
import cats.effect.Selector
import cats.effect.kernel.{Async, Resource}

import com.comcast.ip4s.{Dns, Host, IpAddress, Port, SocketAddress}
import com.comcast.ip4s.{Dns, GenSocketAddress, Host, IpAddress, Port, SocketAddress, UnixSocketAddress}

import fs2.internal.ThreadFactories
import fs2.io.net.tls.TLSContext
Expand Down Expand Up @@ -80,7 +80,7 @@ private[net] trait NetworkCompanionPlatform extends NetworkLowPriority { self: N
def forIO: Network[IO] = forLiftIO

implicit def forLiftIO[F[_]: Async: LiftIO]: Network[F] =
new UnsealedNetwork[F] {
new AsyncNetwork[F] {
private lazy val fallback = forAsync[F]

private def tryGetSelector =
Expand Down Expand Up @@ -132,15 +132,13 @@ private[net] trait NetworkCompanionPlatform extends NetworkLowPriority { self: N
protocolFamily: Option[ProtocolFamily]
): Resource[F, DatagramSocket[F]] =
fallback.openDatagramSocket(address, port, options, protocolFamily)

def tlsContext: TLSContext.Builder[F] = TLSContext.Builder.forAsync[F]
}

def forAsync[F[_]](implicit F: Async[F]): Network[F] =
forAsyncAndDns(F, Dns.forAsync(F))

def forAsyncAndDns[F[_]](implicit F: Async[F], dns: Dns[F]): Network[F] =
new UnsealedNetwork[F] {
new AsyncNetwork[F] {
private lazy val globalSocketGroup = SocketGroup.unsafe[F](globalAcg)
private lazy val globalDatagramSocketGroup = DatagramSocketGroup.unsafe[F](globalAdsg)

Expand Down Expand Up @@ -185,8 +183,23 @@ private[net] trait NetworkCompanionPlatform extends NetworkLowPriority { self: N
protocolFamily: Option[ProtocolFamily]
): Resource[F, DatagramSocket[F]] =
globalDatagramSocketGroup.openDatagramSocket(address, port, options, protocolFamily)
}


private abstract class AsyncNetwork[F[_]](implicit F: Async[F]) extends UnsealedNetwork[F] {

def tlsContext: TLSContext.Builder[F] = TLSContext.Builder.forAsync[F]
def tlsContext: TLSContext.Builder[F] = TLSContext.Builder.forAsync[F]

private def unixSockets = fs2.io.net.unixsocket.UnixSockets.forAsync[F]

def tcp: TcpBuilder.NeedAddress[F] = new TcpBuilder.UnsealedNeedAddress[F] {
def mkClient(address: GenSocketAddress, options: List[SocketOption]) =
address match {
case sa: SocketAddress[_] => client(sa, options)
case ua: UnixSocketAddress => unixSockets.client(fs2.io.net.unixsocket.UnixSocketAddress(ua.path))
case _ => ???
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ package fs2
package io
package net

import fs2.io.net.tls.TLSContext

sealed trait Network[F[_]] extends NetworkPlatform[F] with SocketGroup[F] {
def tlsContext: TLSContext.Builder[F]
trait DatagramSocketGroup[F[_]] {
}

object Network extends NetworkCompanionPlatform {
private[fs2] trait UnsealedNetwork[F[_]] extends Network[F]

def apply[F[_]](implicit F: Network[F]): F.type = F
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ sealed trait Network[F[_]]
with SocketGroup[F]
with DatagramSocketGroup[F] {

def tcp: TcpBuilder.NeedAddress[F]

/** Returns a builder for `TLSContext[F]` values.
*
* For example, `Network[IO].tlsContext.system` returns a `F[TLSContext[F]]`.
Expand All @@ -63,3 +65,68 @@ object Network extends NetworkCompanionPlatform {

def apply[F[_]](implicit F: Network[F]): F.type = F
}

import cats.effect.Resource
import com.comcast.ip4s.*

sealed trait BoundServer[F[_]] {
def serverSocket: Socket[F]
def clients: Stream[F, Socket[F]]
}
private[net] trait UnsealedBoundServer[F[_]] extends BoundServer[F]


sealed trait TcpBuilder[F[_]] {
def withAddress(address: GenSocketAddress): TcpBuilder[F]
def withSocketOptions(options: List[SocketOption]): TcpBuilder[F]
def connect: Resource[F, Socket[F]]
def bind: Resource[F, BoundServer[F]]
def bindAndServe: Stream[F, Socket[F]]
}

object TcpBuilder {
sealed trait NeedAddress[F[_]] {
protected def mkClient(address: GenSocketAddress, options: List[SocketOption]): Resource[F, Socket[F]]

def address(address: GenSocketAddress): TcpBuilder[F] =
TcpBuilder[F](mkClient, address, Nil)

def hostAndPort(host: Host, port: Port): TcpBuilder[F] =
address(SocketAddress(host, port))

def port(port: Port): TcpBuilder[F] =
hostAndPort(Ipv4Address.Wildcard, port)

def port(p: Int): TcpBuilder[F] =
Port.fromInt(p) match {
case Some(pp) => port(pp)
case None => ??? // TODO
}

def hostAndEphemeralPort(host: Host): TcpBuilder[F] =
hostAndPort(host, Port.Wildcard)

def ephemeralPort: TcpBuilder[F] =
address(SocketAddress.Wildcard)

def unixSocket(path: fs2.io.file.Path): TcpBuilder[F] =
address(UnixSocketAddress(path.toString))
}

private[net] trait UnsealedNeedAddress[F[_]] extends NeedAddress[F]

private[net] def apply[F[_]](
mkClient: (GenSocketAddress, List[SocketOption]) => Resource[F, Socket[F]],
address: GenSocketAddress,
options: List[SocketOption]
): TcpBuilder[F] = new TcpBuilder[F] {
private def copy(address: GenSocketAddress = address, options: List[SocketOption] = options): TcpBuilder[F] =
apply[F](mkClient, address, options)
def withSocketOptions(options: List[SocketOption]) = copy(options = options)
def withAddress(address: GenSocketAddress) = copy(address = address)
def connect: Resource[F, Socket[F]] = mkClient(address, options)
def bind: Resource[F, BoundServer[F]]= ???
def bindAndServe: Stream[F, Socket[F]] = ??? //Stream.resource(bind).flatMap(_.clients)
}

}
Loading