Home > Software engineering >  Is there any valid method to duplicate sockaddr?
Is there any valid method to duplicate sockaddr?

Time:02-11

Lets assume that I have used getaddrinfo and resolved an address successfully:

//...
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0)
    return -1;

if (result != nullptr) {
    // ....
}

freeaddrinfo(result);

in this case, result->ai_addr and result->ai_addrlen refer to a sockaddr structure and its size(which is based on its type). Now assume that we want to duplicate this sockaddr in C . What is the best valid approach to do so? I wrote this code, but I'm not sure if it is UB-free:

auto deleter = [](void* buf) { if (buf) free(buf); };

auto buf = malloc(result->ai_addrlen); 
if (buf) {
    memcpy(buf, result->ai_addr, result->ai_addrlen);
}

std::unique_ptr<sockaddr, decltype(deleter)> myptr(static_cast<sockaddr*>(buf), deleter);

Is this a valid C code?

CodePudding user response:

It seems valid to me. If you want to avoid dynamic allocations, you could also limit yourself to a union of all supported address families. Something like this:

union NetworkAddress
{
    sockaddr addr;
    sockaddr_in in4;
    sockaddr_in6 in6;

    static NetworkAddress from_addrinfo(const addrinfo* addr)
    {
        NetworkAddress rtrn;
        if(addr->ai_addrlen <= sizeof(rtrn))
            std::memcpy(&rtrn, addr->ai_addr, addr->ai_addrlen);
        else
            throw std::runtime_error("Unsupported network address");
        return rtrn;
    }
};

CodePudding user response:

Why reinvent the wheel? Use boost::asio (and use vcpkg to install it).

// create address from string
auto someaddress=boost::asio::make_address("127.0.0.1");

// make a copy
boost::asio::ip::address copy=someaddress;
  •  Tags:  
  • c
  • Related