Question

A couple of days ago, I encountered a strange error related to struct sockaddr_un. More about that can be read here.

After some time, I also had found the solution to that error, which was simply memset'ing the entire variable. Now my question is, as already posed in one post on that side, why?

Why do I need to set the whole locally and not dynamically allocated variable to 0, even though I had set each member to a legal and correct value?

In other struct's (for example struct sockaddr_in) is a variable, which is used as padding in order to internally look the same as struct sockaddr. You have to fill (or maybe you don't have to? Please correct me) that variable with 0 in order to make the programm run correctly at any time.

Also, where can I view source code like the one of connect()? Could it be that the connect()-function isn't implemented neatly? Or am I missing some basics?

Thank you in advance.

Était-ce utile?

La solution

From reading the unix_stream_connect source code there doesn't seem to be any requirement to zero out the structure. I have written a test program that intentionally fills the structure with a value, where the client and server pass in different fill values, and they are able to connect to each other fine:

void init_addr (struct sockaddr_un *addr, const char *path, int I) {
    struct sockaddr_un tmp = { .sun_family = AF_UNIX };
    // fill sun_path
    memset(tmp.sun_path, I, UNIX_PATH_MAX);
    // copy path
    snprintf(tmp.sun_path, UNIX_PATH_MAX, "%s", path);
    *addr = tmp;
}

What might be causing the connection failure is a race condition, where the server has not yet finished its set up when the client attempts to connect.

Autres conseils

The answer depends on a couple of things.

First, if you are not using anonymous names (filename doesn't start with 0) then you do not need to clear out the structure.

If you are using anonymous names, it depends on whether you pass the "len" parameter to the various calls as "sizeof(sockaddr_un)" or as something like "len = strlen(local.sun_path+1) +1 + sizeof(local.sun_family); (This is ugly because it ignores possible structure-packing issues).

For anonymous names, the socket name includes all characters after the first 0, up to the end of the structure (as defined by len). So if you pass len as sizeof(sockaddr_un) (which is recommended) you need the entire sun_path to match between the two calls, and therefore zeroing out the structure (or setting the structures identically) is required.

For best results, readability and portability, you should use len = sizeof(sockaddr_un), and memset the sockaddr_un to 0 before initializing it.

This post should be helpful: Can not connect to Linux "abstract" unix socket

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top