swift-lambda-app icon indicating copy to clipboard operation
swift-lambda-app copied to clipboard

Networking issue when using all libraries provided by ldd command

Open nikola-mladenovic opened this issue 6 years ago • 5 comments

When creating a Swift executable that is using networking, (e.g to communicate with other AWS components, or any other internet resource), the host name cannot be found.

After looking a bit deeper, it turns out the issue is with some of the libraries copied from Ubuntu container used to compile Swift executable (i.e libcurl.so.4 and its dependents).

After manually removing libcurl.so.4, the executable started using /usr/lib64/libcurl.so.4 provided by the AWS Lambda OS, the host names were successfully resolved.

Hopefully this information will be useful for anyone trying to perform any network related actions inside Swift executables running on Lambda, and perhaps open a discussion whether copying all libraries provided by the ldd is sufficient / good enough.

nikola-mladenovic avatar Jul 31 '17 10:07 nikola-mladenovic

Possibly AWS Lambda image has changed but talking 6 months back, I was doing network calls used the carried over libcurl and didn't face any issues with DNS resolving.

Is the issue reproducible on other DNS addresses? Can you supply a sample code please?

maximveksler avatar Jul 31 '17 18:07 maximveksler

This is the code from main.swift:

import Foundation
import Dispatch

let request = URLRequest(url: URL(string: "https://raw.githubusercontent.com/nikola-mladenovic/AwsSwiftSign/master/README.md")!)
let session = URLSession(configuration: .default)
let semaphore = DispatchSemaphore(value: 0)
session.dataTask(with: request, completionHandler: { data, response, error in
    if let statusCode = (response as? HTTPURLResponse)?.statusCode {
        print("status code: \(statusCode)")
    }
    if let error = error {
        print("error code: \(error._code)")
        print("error domain: \(error._domain)")
        print("error desc: \(error.localizedDescription)")
    }
    if let data = data {
        print(String(data: data, encoding: .utf8)!)
    }
    semaphore.signal()
}).resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)

I tried to avoid AWS URLs for this example.

Using ibmcom/swift-ubuntu:3.1.1 docker image for compilation and libraries cp.

To make this a bit easier to test, here're the two zip files, one with libcurl.so.4 included, and the second one without.

libcurl.so.4 included: lambda_w_libcurl.zip

libcurl.so.4 not included: lambda_w_o_libcurl.zip

Another useful information is that removing libcurl.so.4 works if you compiled using ubuntu 14.04. However if you try compiling using Swift for ubuntu 16.04 and cping those libraries, removing libcurl.so.4 won't do the trick - the networking still won't work.

nikola-mladenovic avatar Aug 01 '17 22:08 nikola-mladenovic

Thanks – will have a look

choefele avatar Aug 02 '17 09:08 choefele

Hi , I Have the same problem, did anyone find a solution ?

ingouackaz avatar Mar 25 '19 09:03 ingouackaz

You now also have to exclude libresolv.so.2 (along with libcurl.so.4) in order for networking to work.

nikola-mladenovic avatar Mar 25 '19 11:03 nikola-mladenovic