14ef16f24SBrian Somers #include <sys/types.h> 24ef16f24SBrian Somers #include <sys/socket.h> 34ef16f24SBrian Somers #include <netinet/in.h> 44ef16f24SBrian Somers #include <sys/un.h> 54ef16f24SBrian Somers #include <arpa/inet.h> 64ef16f24SBrian Somers #include <netinet/in_systm.h> 74ef16f24SBrian Somers #include <netinet/ip.h> 84ef16f24SBrian Somers #include <string.h> 94ef16f24SBrian Somers #include <stdio.h> 104ef16f24SBrian Somers #include <errno.h> 114ef16f24SBrian Somers #include <unistd.h> 124ef16f24SBrian Somers #include "mbuf.h" 134ef16f24SBrian Somers #include "log.h" 144ef16f24SBrian Somers #include "loadalias.h" 154ef16f24SBrian Somers #include "vars.h" 164ef16f24SBrian Somers #include "server.h" 174ef16f24SBrian Somers 184ef16f24SBrian Somers int server = UNKNOWN_SERVER; 194ef16f24SBrian Somers static struct sockaddr_un ifsun; 204ef16f24SBrian Somers static char *rm; 214ef16f24SBrian Somers 224ef16f24SBrian Somers int 234ef16f24SBrian Somers ServerLocalOpen(const char *name) 244ef16f24SBrian Somers { 254ef16f24SBrian Somers int s; 264ef16f24SBrian Somers 274ef16f24SBrian Somers ifsun.sun_len = strlen(name); 284ef16f24SBrian Somers if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { 294ef16f24SBrian Somers LogPrintf(LogERROR, "Local: %s: Path too long\n", name); 304ef16f24SBrian Somers return 1; 314ef16f24SBrian Somers } 324ef16f24SBrian Somers ifsun.sun_family = AF_LOCAL; 334ef16f24SBrian Somers strcpy(ifsun.sun_path, name); 344ef16f24SBrian Somers 354ef16f24SBrian Somers s = socket(PF_LOCAL, SOCK_STREAM, 0); 364ef16f24SBrian Somers if (s < 0) { 374ef16f24SBrian Somers LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno)); 384ef16f24SBrian Somers return 2; 394ef16f24SBrian Somers } 404ef16f24SBrian Somers 414ef16f24SBrian Somers setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 424ef16f24SBrian Somers if (bind(s, (struct sockaddr *) &ifsun, sizeof(ifsun)) < 0) { 434ef16f24SBrian Somers LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno)); 444ef16f24SBrian Somers if (errno == EADDRINUSE && VarTerm) 454ef16f24SBrian Somers fprintf(VarTerm, "Wait for a while, then try again.\n"); 464ef16f24SBrian Somers close(s); 474ef16f24SBrian Somers unlink(name); 484ef16f24SBrian Somers return 3; 494ef16f24SBrian Somers } 504ef16f24SBrian Somers if (listen(s, 5) != 0) { 514ef16f24SBrian Somers LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n"); 524ef16f24SBrian Somers close(s); 534ef16f24SBrian Somers unlink(name); 544ef16f24SBrian Somers return 4; 554ef16f24SBrian Somers } 564ef16f24SBrian Somers ServerClose(); 574ef16f24SBrian Somers server = s; 584ef16f24SBrian Somers rm = ifsun.sun_path; 594ef16f24SBrian Somers LogPrintf(LogPHASE, "Listening at local socket %s.\n", name); 604ef16f24SBrian Somers return 0; 614ef16f24SBrian Somers } 624ef16f24SBrian Somers 634ef16f24SBrian Somers int 644ef16f24SBrian Somers ServerTcpOpen(int port) 654ef16f24SBrian Somers { 664ef16f24SBrian Somers struct sockaddr_in ifsin; 674ef16f24SBrian Somers int s; 684ef16f24SBrian Somers 694ef16f24SBrian Somers s = socket(PF_INET, SOCK_STREAM, 0); 704ef16f24SBrian Somers if (s < 0) { 714ef16f24SBrian Somers LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno)); 724ef16f24SBrian Somers return 5; 734ef16f24SBrian Somers } 744ef16f24SBrian Somers ifsin.sin_family = AF_INET; 754ef16f24SBrian Somers ifsin.sin_addr.s_addr = INADDR_ANY; 764ef16f24SBrian Somers ifsin.sin_port = htons(port); 774ef16f24SBrian Somers setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 784ef16f24SBrian Somers if (bind(s, (struct sockaddr *) &ifsin, sizeof(ifsin)) < 0) { 794ef16f24SBrian Somers LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno)); 804ef16f24SBrian Somers if (errno == EADDRINUSE && VarTerm) 814ef16f24SBrian Somers fprintf(VarTerm, "Wait for a while, then try again.\n"); 824ef16f24SBrian Somers close(s); 834ef16f24SBrian Somers return 6; 844ef16f24SBrian Somers } 854ef16f24SBrian Somers if (listen(s, 5) != 0) { 864ef16f24SBrian Somers LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n"); 874ef16f24SBrian Somers close(s); 884ef16f24SBrian Somers return 7; 894ef16f24SBrian Somers } 904ef16f24SBrian Somers ServerClose(); 914ef16f24SBrian Somers server = s; 924ef16f24SBrian Somers LogPrintf(LogPHASE, "Listening at port %d.\n", port); 934ef16f24SBrian Somers return 0; 944ef16f24SBrian Somers } 954ef16f24SBrian Somers 964ef16f24SBrian Somers void 974ef16f24SBrian Somers ServerClose() 984ef16f24SBrian Somers { 994ef16f24SBrian Somers if (server >= 0) { 1004ef16f24SBrian Somers close(server); 1014ef16f24SBrian Somers if (rm) { 1024ef16f24SBrian Somers unlink(rm); 1034ef16f24SBrian Somers rm = 0; 1044ef16f24SBrian Somers } 1054ef16f24SBrian Somers } 1064ef16f24SBrian Somers server = -1; 1074ef16f24SBrian Somers } 1084ef16f24SBrian Somers 1094ef16f24SBrian Somers int 1104ef16f24SBrian Somers ServerType() 1114ef16f24SBrian Somers { 1124ef16f24SBrian Somers if (server == UNKNOWN_SERVER) 1134ef16f24SBrian Somers return UNKNOWN_SERVER; 1144ef16f24SBrian Somers else if (server == NO_SERVER) 1154ef16f24SBrian Somers return NO_SERVER; 1164ef16f24SBrian Somers else if (rm) 1174ef16f24SBrian Somers return LOCAL_SERVER; 1184ef16f24SBrian Somers else 1194ef16f24SBrian Somers return INET_SERVER; 1204ef16f24SBrian Somers } 121