server.c revision 30715
1/* 2 * $Id: $ 3 */ 4 5#include <sys/param.h> 6#include <sys/socket.h> 7#include <netinet/in.h> 8#include <arpa/inet.h> 9#include <netinet/in_systm.h> 10#include <netinet/ip.h> 11 12#include <errno.h> 13#include <stdio.h> 14#include <string.h> 15#include <sys/stat.h> 16#include <sys/un.h> 17#include <unistd.h> 18 19#include "mbuf.h" 20#include "log.h" 21#include "loadalias.h" 22#include "command.h" 23#include "vars.h" 24#include "server.h" 25#include "log.h" 26#include "defs.h" 27 28int server = -2; 29 30static struct sockaddr_un ifsun; 31static char *rm; 32 33int 34ServerLocalOpen(const char *name, mode_t mask) 35{ 36 int s; 37 38 if (VarLocalAuth == LOCAL_DENY) { 39 LogPrintf(LogERROR, "Local: Can't open socket %s: No password " 40 "in ppp.secret\n", name); 41 return 1; 42 } 43 44 if (!(mode&(MODE_AUTO|MODE_DEDICATED|MODE_DIRECT))) { 45 LogPrintf(LogERROR, "Local: Can't open socket in interactive mode\n"); 46 return 1; 47 } 48 49 ifsun.sun_len = strlen(name); 50 if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { 51 LogPrintf(LogERROR, "Local: %s: Path too long\n", name); 52 return 2; 53 } 54 ifsun.sun_family = AF_LOCAL; 55 strcpy(ifsun.sun_path, name); 56 57 s = socket(PF_LOCAL, SOCK_STREAM, 0); 58 if (s < 0) { 59 LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno)); 60 return 3; 61 } 62 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 63 mask = umask(mask); 64 if (bind(s, (struct sockaddr *) & ifsun, sizeof(ifsun)) < 0) { 65 umask(mask); 66 LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno)); 67 if (errno == EADDRINUSE && VarTerm) 68 fprintf(VarTerm, "Wait for a while, then try again.\n"); 69 close(s); 70 unlink(name); 71 return 4; 72 } 73 umask(mask); 74 if (listen(s, 5) != 0) { 75 LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n"); 76 close(s); 77 unlink(name); 78 return 5; 79 } 80 ServerClose(); 81 server = s; 82 rm = ifsun.sun_path; 83 LogPrintf(LogPHASE, "Listening at local socket %s.\n", name); 84 return 0; 85} 86 87int 88ServerTcpOpen(int port) 89{ 90 struct sockaddr_in ifsin; 91 int s; 92 93 if (VarLocalAuth == LOCAL_DENY) { 94 LogPrintf(LogERROR, "Tcp: Can't open socket %d: No password " 95 "in ppp.secret\n", port); 96 return 6; 97 } 98 99 if (!(mode&(MODE_AUTO|MODE_DEDICATED|MODE_DIRECT))) { 100 LogPrintf(LogERROR, "Tcp: Can't open socket in interactive mode\n"); 101 return 6; 102 } 103 104 s = socket(PF_INET, SOCK_STREAM, 0); 105 if (s < 0) { 106 LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno)); 107 return 7; 108 } 109 ifsin.sin_family = AF_INET; 110 ifsin.sin_addr.s_addr = INADDR_ANY; 111 ifsin.sin_port = htons(port); 112 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 113 if (bind(s, (struct sockaddr *) & ifsin, sizeof(ifsin)) < 0) { 114 LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno)); 115 if (errno == EADDRINUSE && VarTerm) 116 fprintf(VarTerm, "Wait for a while, then try again.\n"); 117 close(s); 118 return 8; 119 } 120 if (listen(s, 5) != 0) { 121 LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n"); 122 close(s); 123 return 9; 124 } 125 ServerClose(); 126 server = s; 127 LogPrintf(LogPHASE, "Listening at port %d.\n", port); 128 return 0; 129} 130 131void 132ServerClose() 133{ 134 if (server >= 0) { 135 close(server); 136 if (rm) { 137 unlink(rm); 138 rm = 0; 139 } 140 } 141 server = -1; 142} 143