// Set nonblock
net_nonblock(newSocket);
+ int is_onion = 0;
+ {
+ struct sockaddr_storage sockname;
+ socklen_t socknamelen = sizeof(sockname);
+ if (getsockname(newSocket, (struct sockaddr *)&sockname, &socknamelen) == -1) {
+ net_perror("getsockname");
+ exit(EXIT_FAILURE);
+ }
+ if (sockname.ss_family == AF_INET) {
+ struct in_addr *ia = &((struct sockaddr_in *)&sockname)->sin_addr;
+ // onion if connecting to 127.0.0.2
+ if (ntohl(ia->s_addr) == 0x7F000002)
+ is_onion = 1;
+ }
+ }
+
char client_addr[100];
int port;
+ int is_local = 0;
if (addr.ss_family == AF_INET) {
- inet_ntop(AF_INET, &((struct sockaddr_in*)&addr)->sin_addr, client_addr, sizeof(client_addr));
+ struct in_addr *ia = &((struct sockaddr_in *)&addr)->sin_addr;
+ // local if connecting from 127.0.0.0/8
+ if ((ntohl(ia->s_addr) & 0xFF000000) == 0x7F000000)
+ is_local = 1;
+ inet_ntop(AF_INET, ia, client_addr, sizeof(client_addr));
port = ntohs(((struct sockaddr_in*)&addr)->sin_port);
} else if (addr.ss_family == AF_INET6) {
- inet_ntop(AF_INET6, &((struct sockaddr_in6*)&addr)->sin6_addr, client_addr, sizeof(client_addr));
+ struct in6_addr *ia = &((struct sockaddr_in6 *)&addr)->sin6_addr;
+ // local if connecting from ::1
+ if (!memcmp(ia->s6_addr, "\0\0\0\0""\0\0\0\0""\0\0\0\0""\0\0\0\1", 16))
+ is_local = 1;
+ inet_ntop(AF_INET6, ia, client_addr, sizeof(client_addr));
port = ntohs(((struct sockaddr_in6*)&addr)->sin6_port);
} else {
strcpy_lit(client_addr, "?");
if (cctx)
cl->umode |= UMODE_SECURE;
extern const char *hostname;
- if (!strcmp(cl->peername, "127.0.0.1")) {
- cl->hostname = mystrdup("localhost");
- cl->umode |= UMODE_SECURE;
- } else if (!strcmp(cl->peername, "127.0.0.2")) {
- cl->hostname = mystrdup("onion");
+ if (is_local) {
+ cl->hostname = mystrdup(is_onion ? "onion" : "localhost");
cl->umode |= UMODE_SECURE;
} else {
cl->hostname = mystrdup(hostname);