Przeglądaj źródła

Added new flag to force IPv4 usage (MacOS).

Damian Kołakowski 10 lat temu
rodzic
commit
94692d9098
3 zmienionych plików z 39 dodań i 26 usunięć
  1. 2 2
      Sources/HttpServerIO.swift
  2. 36 23
      Sources/Socket.swift
  3. 1 1
      SwifterSampleOSX/main.swift

+ 2 - 2
Sources/HttpServerIO.swift

@@ -18,9 +18,9 @@ public class HttpServerIO {
     private var clientSockets: Set<Socket> = []
     private let clientSocketsLock = NSLock()
     
-    public func start(listenPort: in_port_t = 8080) throws {
+    public func start(listenPort: in_port_t = 8080, forceIPv4: Bool = false) throws {
         stop()
-        listenSocket = try Socket.tcpSocketForListen(listenPort)
+        listenSocket = try Socket.tcpSocketForListen(listenPort, forceIPv4: forceIPv4)
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
             while let socket = try? self.listenSocket.acceptClientSocket() {
                 self.lock(self.clientSocketsLock) {

+ 36 - 23
Sources/Socket.swift

@@ -28,12 +28,12 @@ public enum SocketError: ErrorType {
 
 public class Socket: Hashable, Equatable {
     
-    public class func tcpSocketForListen(port: in_port_t, maxPendingConnection: Int32 = SOMAXCONN) throws -> Socket {
+    public class func tcpSocketForListen(port: in_port_t, forceIPv4: Bool = false, maxPendingConnection: Int32 = SOMAXCONN) throws -> Socket {
         
         #if os(Linux)
             let socketFileDescriptor = socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0)
         #else
-            let socketFileDescriptor = socket(AF_INET6, SOCK_STREAM, 0)
+            let socketFileDescriptor = socket(forceIPv4 ? AF_INET : AF_INET6, SOCK_STREAM, 0)
         #endif
         
         if socketFileDescriptor == -1 {
@@ -49,30 +49,43 @@ public class Socket: Hashable, Equatable {
         Socket.setNoSigPipe(socketFileDescriptor)
         
         #if os(Linux)
-            var addr = sockaddr_in()
-            addr.sin_family = sa_family_t(AF_INET)
-            addr.sin_port = Socket.htonsPort(port)
-            addr.sin_addr = in_addr(s_addr: in_addr_t(0))
-            addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0)
+            var bindResult: Int32 = -1
+            if forceIPv4 {
+                var addr = sockaddr_in()
+                addr.sin_family = sa_family_t(AF_INET)
+                addr.sin_port = Socket.htonsPort(port)
+                addr.sin_addr = in_addr(s_addr: in_addr_t(0))
+                addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0)
+                
+                bindResult = withUnsafePointer(&addr) { bind(socketFileDescriptor, UnsafePointer<sockaddr>($0), socklen_t(sizeof(sockaddr_in))) }
+            } else {
+                
+            }
         #else
-          var addr = sockaddr_in6(
-            sin6_len: UInt8(strideof(sockaddr_in6)),
-            sin6_family: UInt8(AF_INET6),
-            sin6_port: Socket.htonsPort(port),
-            sin6_flowinfo: 0,
-            sin6_addr: in6addr_any,
-            sin6_scope_id: 0
-          )
+            var bindResult: Int32 = -1
+            if forceIPv4 {
+                var addr = sockaddr_in(
+                    sin_len: UInt8(strideof(sockaddr_in)),
+                    sin_family: UInt8(AF_INET),
+                    sin_port: Socket.htonsPort(port),
+                    sin_addr: in_addr(s_addr: in_addr_t(0)),
+                    sin_zero:(0, 0, 0, 0, 0, 0, 0, 0))
+             
+                bindResult = withUnsafePointer(&addr) { bind(socketFileDescriptor, UnsafePointer<sockaddr>($0), socklen_t(sizeof(sockaddr_in))) }
+            } else {
+                var addr = sockaddr_in6(sin6_len:
+                    UInt8(strideof(sockaddr_in6)),
+                    sin6_family: UInt8(AF_INET6),
+                    sin6_port: Socket.htonsPort(port),
+                    sin6_flowinfo: 0,
+                    sin6_addr: in6addr_any,
+                    sin6_scope_id: 0)
+                
+                bindResult = withUnsafePointer(&addr) { bind(socketFileDescriptor, UnsafePointer<sockaddr>($0), socklen_t(sizeof(sockaddr_in6))) }
+            }
         #endif
-        
-        var bind_addr = sockaddr_in6()
-        memcpy(&bind_addr, &addr, Int(sizeof(sockaddr_in6)))
-
-        let bind_result = withUnsafePointer(&bind_addr) { addr in
-          return bind(socketFileDescriptor, UnsafePointer<sockaddr>(addr), socklen_t(sizeof(sockaddr_in6)))
-        }
 
-        if bind_result == -1 {
+        if bindResult == -1 {
             let details = Socket.descriptionOfLastError()
             Socket.release(socketFileDescriptor)
             throw SocketError.BindFailed(details)

+ 1 - 1
SwifterSampleOSX/main.swift

@@ -22,7 +22,7 @@ do {
     server["/testAfterBaseRoute"] = { request in
         return .OK(.Html("ok !"))
     }
-    try server.start(9080)
+    try server.start(9080, forceIPv4: true)
     print("Server has started ( port = 9080 ). Try to connect now...")
     NSRunLoop.mainRunLoop().run()
 } catch {