Kitura / BlueSocket

Socket framework for Swift using the Swift Package Manager. Works on iOS, macOS, and Linux.
Apache License 2.0
1.41k stars 197 forks source link

Error code: -9993(0x-2709), Invalid argument #208

Open kkharji opened 2 years ago

kkharji commented 2 years ago

I'm having an odd issue that I can't seem to be able to solve.

In my program I have a main unix socket that accept message and within the same program I have cli that create a socket and write to the main socket. The connection to main has no issues, it's when I write, the main socket error out with Error code: -9993(0x-2709), Invalid argument

Main Socket:

  func attach() async {
    do {
      try socket.listen(on: socketPath)
      log.info("Listening on \(socketPath)")
      while true {
        let socket = try Socket.create(family: .unix, type: .stream, proto: .unix) 
        let conn = try socket.acceptClientConnection()
        let msg = try conn.readString()?.trimmingCharacters(in: .whitespacesAndNewlines)
        conn.close()
       // await .......
      }
    } catch { log.error("Socket error: \(error)")  }
  }

CLI socket write:


do {
  let socket = try Socket.create(family: .unix, type: .stream, proto: .unix)
  try socket.connect(to: socketPath)
  try socket.write(from: "-d restart")
  return
} catch { ... }
dannys42 commented 2 years ago

I think the "Socket.create" line may not be needed in your attach() call? It's certainly overriding your socket.listen().

kkharji commented 2 years ago

🤔 indeed must copied here by mistake.

as a workaround I opt out to nc

    let pipe = Pipe()
    let echo = Process()
    echo.launchPath = "/usr/bin/env"
    echo.arguments = ["echo"] + args.components(separatedBy: " ")
    echo.standardOutput = pipe

    let task = Process()
    task.launchPath = "/usr/bin/env"
    task.arguments = ["nc", "-U", socketPath]
    task.standardInput = pipe
    echo.launch()
    task.launch()

    task.waitUntilExit()

    if task.terminationStatus != 0 {
      throw Error.processFailed(args)
    }

My attach function is now

func attach() async {
    do {
      let socket = try Socket.create(family: .unix, type: .stream, proto: .unix)
      try socket.listen(on: socketPath)
      log.info("Listening on \(socketPath)")

      while true {
        let conn = try socket.acceptClientConnection()
        let msg = try conn.readString()?.trimmingCharacters(in: .whitespacesAndNewlines)
        conn.close()
        await processMessage(msg)
        if stop || restart {
          log.info("No longer accepting connection to \(socketPath)")
          break
        }
      }
    } catch {
      log.error("Socket error: \(error)")
    }

    if restart {
      restart = false
      await attach()
    }
  }
Kirow commented 2 years ago

I had same error but in different context.

do {
   let socket = try Socket.create(family: .inet, type: .datagram, proto: .udp)
   let destination = Socket.createAddress(for: "localhost", on: 50000)
   _ = try socket.write(from: Data("Message".utf8), to: destination!)
   print("Sent message to 50000")
} catch {
   print("Failed to send message to 50000 - \(error)")
}

It worked few days ago, but now its not and that makes me crazy... the problem in localhost...if I change it to 127.0.0.1 it start working again. But Im pretty sure it worked with localhost before. Any ideas why it stop working?

dannys42 commented 2 years ago

If you're on macOS, I think localhost is defined for both ipv4 and ipv6, which I think can sometimes cause confusion. Is it more reliable if you use 127.0.0.1? Also how is your listening side declared?

Kirow commented 2 years ago

@dannys42 yes, im on macOS. no listener in this example. it just works w/o error if I change to 127.0.0.1. But I'm very curious about the reason why localhost stopped working (because it worked few days ago and I have not change source code). So it more likely the issue with my host machine. /etc/hosts does have 127.0.0.1 localhost and ping localhost in terminal works...

Kirow commented 2 years ago

/etc/hosts also has ::1 localhost. After I removed it - socket start working again. So yes, it were related to ipv4/ipv6. Not sure why it were recognised as AF_INET before and now as AF_INET6, but yes - it will be more reliable to use 127.0.0.1