I have two daemons (one client and one server) that communicate thru unix domain sockets (local sockets). The problem I encounter is that the first time a datagram is received in the server with the function recvfrom then the client address provided by the recvfrom function is empty. However the size of the client address provided seems to be correct. If i increase the address length (longer name) in the client daemon this will be reflected in increased size of the address size at the server. Also the data received is correct.
Note that I only have this problem the first time a datagram is received at the server. When the other datagrams are received the address field is correct.
Any expert out there that have an understanding of what could be wrong?
Server code:
static struct sockaddr_un myclient_address;
socklen_t address_length = 0;
int fd;
struct sockaddr_un addr;
struct my_device *dev = dev->device;
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0) {
f_warning("socket error");
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
memset(&myclient_address, 0, sizeof(myclient_address));
myclient_address.sun_family = AF_UNIX;
char *socket_path = "#myserver";
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
addr.sun_path[0] = '\0';
unlink(socket_path);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
f_warning("bind error");
}
dev->socket_fd = fd;
dev->socket_io_channel = g_io_channel_unix_new(fd);
dev->socket_io_src_id = g_io_add_watch(dev->socket_io_channel,
G_IO_IN,
socket_in_data_callback,
dev);
static gboolean
socket_in_data_callback(GIOChannel *source, GIOCondition cond, gpointer data)
{
struct my_device *dev = data;
gsize read_count = 0;
GIOStatus status;
guchar* data = g_malloc0(300);
read_count = recvfrom(dev->socket_fd, (char *) data, 300, 0,
(struct sockaddr *) &(myclient_address), &address_length);
return TRUE;
}
Client code:
int fd;
struct sockaddr_un mycli_addr;
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0) {
f_warning("socket error");
}
memset(&addr, 0, sizeof(addr));
memset(&mycli_addr, 0, sizeof(mycli_addr));
addr.sun_family = AF_UNIX;
mycli_addr.sun_family = AF_UNIX;
char *socket_path = "#myserver";
char *mycli_socket_path = "#myclient";
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
strncpy(mycli_addr.sun_path, mycli_socket_path, sizeof(mycli_addr.sun_path));
addr.sun_path[0] = '\0';
mycli_addr.sun_path[0] = '\0';
unlink(socket_path);
unlink(mycli_socket_path);
int er;
er = bind(fd, (struct sockaddr*)&mycli_addr, sizeof(mycli_addr));
if (er < 0) {
f_warning("bind error");
}
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
f_warning("connect error");
}
session->socket_io_channel = g_io_channel_unix_new(fd);
session->socket_io_src_id = g_io_add_watch(session->socket_io_channel,
G_IO_IN,
client_socket_in_data_callback,
session);
sendto(session->socket, (char *) mydata, data_length, 0,
(struct sockaddr *) &addr,
sizeof(struct sockaddr_un));