-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SocketAddr from UnixDatagram recv_from missing the last character #2230
Comments
I think the problem is the |
@zonyitoo I have not reproduced this using a Python client, but I don't think the issue here is in the linked code. Tokio To address that first, the path shortening is similar to std where OS path lengths are expected to be null-terminated. The path length subtraction is then needed to drop the null-terminator. What may be happening here is that the Python client is not doing what Maybe try making sure the client's bound path is null-terminated. Does that answer your question? I know there are a few links provided in this, but let me know if anything is not clear. |
More test with libstd's UnixDatagram: use std::os::unix::net::UnixDatagram;
fn main() {
let socket = UnixDatagram::bind("/tmp/shadowsocks-manager.sock").unwrap();
let mut buf = [0u8; 65536];
loop {
let (n, src_addr) = socket.recv_from(&mut buf).unwrap();
println!("size={} src={:?}", n, src_addr);
}
} Client is the same python script. And I got this result:
@kleimkuhler Could you try it on OS X? |
I think the problem is OS X's bound path is not null-terminated. I am doing test with C. |
Test program in C #include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
int ret = 0;
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0) {
perror("socket");
return EXIT_FAILURE;
}
struct sockaddr_un baddr;
memset(&baddr, 0, sizeof(baddr));
const char* BIND_PATH = "/tmp/shadowsocks-manager.sock";
baddr.sun_family = AF_UNIX;
strcpy(baddr.sun_path, BIND_PATH);
unlink(BIND_PATH);
if ((ret = bind(fd, (struct sockaddr*)&baddr, sizeof(baddr))) < 0) {
perror("bind");
close(fd);
return EXIT_FAILURE;
}
char buf[65536];
for (;;) {
struct sockaddr_un caddr;
memset(&caddr, 0, sizeof(caddr));
socklen_t caddr_len = sizeof(caddr);
ssize_t rcount = 0;
if ((rcount = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&caddr, &caddr_len)) < 0) {
perror("recvfrom");
close(fd);
return EXIT_FAILURE;
}
printf("recvfrom ret=%zd caddr_len=%u sun_len=%u sun_family=%d path=%s\n",
rcount,
caddr_len,
caddr.sun_len,
caddr.sun_family,
caddr.sun_path);
}
return 0;
} And test with the same Python client:
NOTE: the length of |
Ok, I found the problem. In OS X, /*
* [XSI] Definitions for UNIX IPC domain.
*/
struct sockaddr_un {
unsigned char sun_len; /* sockaddr len including null */
sa_family_t sun_family; /* [XSI] AF_UNIX */
char sun_path[104]; /* [XSI] path name (gag) */
}; but Linux defines /* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */
struct sockaddr_un
{
__SOCKADDR_COMMON (sun_);
char sun_path[108]; /* Path name. */
}; and #define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family So OS X has one more byte ( |
Should be closed this one 🖖 |
Version
0.2.11
Platform
Subcrates
net
Description
Server:
Client (in Python):
Server receives 4 bytes sent from client, and print:
Where is that missing
k
?The text was updated successfully, but these errors were encountered: