I'm using an abstract Unix socket for passing data between a C and Go program. The C program is creating the socket and the Go program connects to it. The issue is the Go program fails to connect to the socket, and I receive the following error message:
UDS connection failed: dial unixgram @uds-js: connect: connection refused
Here is the C program:
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
/* Buffer size for the receive socket */
#define BUFFER_SIZE 4096
/* The abstract Unix domain socket address name */
#define UDS_ADDRESS_NAME "#uds-js"
int main() {
int socket_fd;
int bytes_received;
char buffer[BUFFER_SIZE];
struct sockaddr_un server_address;
struct sockaddr_un client_address;
socklen_t address_length = sizeof(struct sockaddr_un);
/* Create local unix socket */
if ( ( socket_fd = socket ( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 ) {
printf ( "socket error\n" );
return 1;
}
/* Set an abstract socket address */
memset( &server_address, 0, sizeof(server_address) );
server_address.sun_family = AF_UNIX;
strcpy( server_address.sun_path, UDS_ADDRESS_NAME );
server_address.sun_path[0] = '\0';
/* Bind socket to address */
if ( bind ( socket_fd, (const struct sockaddr *) &server_address, address_length ) < 0 ) {
close ( socket_fd );
printf ( "socket bind error\n" );
return 1;
}
bytes_received =
recvfrom(
socket_fd,
&buffer,
BUFFER_SIZE,
0,
(struct sockaddr *) &client_address,
&address_length );
printf ( "Received: %s\n", buffer );
return 0;
}
And the Go program:
import (
"fmt"
"net"
"os"
)
func main() {
addr, _ := net.ResolveUnixAddr("unixgram", "@uds-js")
udsSock, err := net.DialUnix("unixgram", nil, addr)
if err != nil {
fmt.Printf("UDS connection failed: %v\n", err)
os.Exit(1)
}
defer udsSock.Close()
if _, err := udsSock.Write([]byte("{\"test\":100}")); err != nil {
fmt.Printf("Failed to send message on UDS: %v\n", err)
}
}
In the C program I set the first byte in the socket name to a null byte, as to spec. From what I've gathered in Go the name needs to start with a @.
Running netstat I can see the socket was created:
$ netstat -ax | grep DGRAM
unix 2 [ ] DGRAM 12411992 @uds-js@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Why does the Go program fail to connect to the socket?
EDIT:
Changing the name to a pathname, /tmp/uds-js, and this does work as expected.
EDIT2:
I created a server in Go and a client in C for the abstract socket and the two C programs and the two Go programs work okay together. The issue seem to be when going from C to Go using abstract sockets.
server_address.sun_path[0] = '\0';when you changed it to/tmp/uds-js, right?