Skip to content
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

Add unix socket support #67

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions server.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#include "server.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <unistd.h>
#include <sys/un.h>

int resolve(const char *host, unsigned short port, struct addrinfo** addr) {
struct addrinfo hints = {
Expand Down Expand Up @@ -62,3 +66,40 @@ int server_setup(struct server *server, const char* listenip, unsigned short por
server->fd = listenfd;
return 0;
}

int server_setup_unix(struct server *server, const char* path) {
socklen_t addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(path) + 1;
if(addrlen < strlen(path)) { // not possible in practice
errno = ENAMETOOLONG;
return -1;
}

struct sockaddr_un *addr = calloc(1, addrlen);
if(!addr) {
return -1;
}
addr->sun_family = AF_UNIX;
strcpy(addr->sun_path, path);

int listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (listenfd < 0) {
free(addr);
return -2;
}

// note: binding to "" lets the kernel choose a random address, just like IP port 0
if(bind(listenfd, (struct sockaddr*)addr, addrlen) < 0) {
close(listenfd);
free(addr);
return -2;
}
free(addr);

if(listen(listenfd, SOMAXCONN) < 0) {
close(listenfd);
return -3;
}

server->fd = listenfd;
return 0;
}
1 change: 1 addition & 0 deletions server.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ int bindtoip(int fd, union sockaddr_union *bindaddr);

int server_waitclient(struct server *server, struct client* client);
int server_setup(struct server *server, const char* listenip, unsigned short port);
int server_setup_unix(struct server *server, const char* unixpath);

#endif

41 changes: 34 additions & 7 deletions sockssrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ static int connect_socks_target(unsigned char *buf, size_t n, struct client *cli
char clientname[256];
af = SOCKADDR_UNION_AF(&client->addr);
void *ipdata = SOCKADDR_UNION_ADDRESS(&client->addr);
inet_ntop(af, ipdata, clientname, sizeof clientname);
if(!inet_ntop(af, ipdata, clientname, sizeof clientname))
strcpy(clientname, "");
dolog("client[%d] %s: connected to %s:%d\n", client->fd, clientname, namebuf, port);
}
return fd;
Expand Down Expand Up @@ -391,6 +392,7 @@ static int usage(void) {
"this is handy for programs like firefox that don't support\n"
"user/pass auth. for it to work you'd basically make one connection\n"
"with another program that supports it, and then you can use firefox too.\n"
"for unix socket server use -U path and do not use -1 -i -p.\n"
);
return 1;
}
Expand All @@ -403,9 +405,10 @@ static void zero_arg(char *s) {

int main(int argc, char** argv) {
int ch;
const char *listenip = "0.0.0.0";
unsigned port = 1080;
while((ch = getopt(argc, argv, ":1qb:i:p:u:P:")) != -1) {
const char *listenip = NULL;
int port = -1;
const char *unixpath = NULL;
while((ch = getopt(argc, argv, ":1qb:i:p:u:P:U:")) != -1) {
switch(ch) {
case '1':
auth_ips = sblist_new(sizeof(union sockaddr_union), 8);
Expand All @@ -430,6 +433,9 @@ int main(int argc, char** argv) {
case 'p':
port = atoi(optarg);
break;
case 'U':
unixpath = optarg;
break;
case ':':
dprintf(2, "error: option -%c requires an operand\n", optopt);
/* fall through */
Expand All @@ -445,12 +451,33 @@ int main(int argc, char** argv) {
dprintf(2, "error: auth-once option must be used together with user/pass\n");
return 1;
}
if(unixpath) {
if(auth_ips) {
dprintf(2, "error: auth-once option cannot be used with unix sockets\n");
return 1;
}
if(listenip || port != -1) {
dprintf(2, "error: address/port and unix path cannot be used together\n");
return 1;
}
}
signal(SIGPIPE, SIG_IGN);
struct server s;
sblist *threads = sblist_new(sizeof (struct thread*), 8);
if(server_setup(&s, listenip, port)) {
perror("server_setup");
return 1;
if(unixpath) {
if(server_setup_unix(&s, unixpath)) {
perror("server_setup_unix");
return 1;
}
} else {
if(!listenip)
listenip = "0.0.0.0";
if(port == -1)
port = 1080;
if(server_setup(&s, listenip, port)) {
perror("server_setup");
return 1;
}
}
server = &s;

Expand Down