|  | @@ -43,7 +43,7 @@
 | 
		
	
		
			
			| 43 | 43 |  #include <syslog.h>
 | 
		
	
		
			
			| 44 | 44 |  
 | 
		
	
		
			
			| 45 | 45 |  #ifndef VERSION
 | 
		
	
		
			
			| 46 |  | -#define VERSION "1.2"
 | 
		
	
		
			
			|  | 46 | +#define VERSION "1.3"
 | 
		
	
		
			
			| 47 | 47 |  #endif
 | 
		
	
		
			
			| 48 | 48 |  
 | 
		
	
		
			
			| 49 | 49 |  static char *self = NULL;
 | 
		
	
	
		
			
			|  | @@ -58,7 +58,7 @@ static int bind_service (const char *service, int family)
 | 
		
	
		
			
			| 58 | 58 |    memset (&hints, 0, sizeof(hints));
 | 
		
	
		
			
			| 59 | 59 |    hints.ai_family = family;
 | 
		
	
		
			
			| 60 | 60 |    hints.ai_socktype = SOCK_STREAM;
 | 
		
	
		
			
			| 61 |  | -  hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
 | 
		
	
		
			
			|  | 61 | +
 | 
		
	
		
			
			| 62 | 62 |    err = getaddrinfo(NULL, service, &hints, &addr);
 | 
		
	
		
			
			| 63 | 63 |    if (err != 0) {
 | 
		
	
		
			
			| 64 | 64 |      fprintf(stderr, "%s: bind_service(%s): %s\n", self, service, gai_strerror(err));
 | 
		
	
	
		
			
			|  | @@ -214,6 +214,7 @@ static void show_help ()
 | 
		
	
		
			
			| 214 | 214 |      "Options:\n"
 | 
		
	
		
			
			| 215 | 215 |      "   -s<file>       read secrets from file (required)\n"
 | 
		
	
		
			
			| 216 | 216 |      "   -d<domain>     set domain name for rewrite (required)\n"
 | 
		
	
		
			
			|  | 217 | +    "   -a<char>       set first separator character which can be one of: -=+ (default: =)\n"
 | 
		
	
		
			
			| 217 | 218 |      "   -f<port>       set port for the forward SRS lookup (default: 10001)\n"
 | 
		
	
		
			
			| 218 | 219 |      "   -r<port>       set port for the reverse SRS lookup (default: 10002)\n"
 | 
		
	
		
			
			| 219 | 220 |      "   -p<pidfile>    write process ID to pidfile (default: none)\n"
 | 
		
	
	
		
			
			|  | @@ -221,6 +222,7 @@ static void show_help ()
 | 
		
	
		
			
			| 221 | 222 |      "   -u<user>       switch user id after port bind (default: none)\n"
 | 
		
	
		
			
			| 222 | 223 |      "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
 | 
		
	
		
			
			| 223 | 224 |      "   -X<domain>     exclude additional domain from address rewriting\n"
 | 
		
	
		
			
			|  | 225 | +    "   -e             attempt to read above parameters from environment\n"
 | 
		
	
		
			
			| 224 | 226 |      "   -D             fork into background\n"
 | 
		
	
		
			
			| 225 | 227 |      "   -4             force IPv4 socket (default: any)\n"
 | 
		
	
		
			
			| 226 | 228 |      "   -6             force IPv6 socket (default: any)\n"
 | 
		
	
	
		
			
			|  | @@ -239,6 +241,7 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 239 | 241 |    int daemonize = FALSE;
 | 
		
	
		
			
			| 240 | 242 |    char *forward_service = NULL, *reverse_service = NULL,
 | 
		
	
		
			
			| 241 | 243 |         *user = NULL, *domain = NULL, *chroot_dir = NULL;
 | 
		
	
		
			
			|  | 244 | +  char separator = '=';
 | 
		
	
		
			
			| 242 | 245 |    int forward_sock, reverse_sock;
 | 
		
	
		
			
			| 243 | 246 |    char *secret_file = NULL, *pid_file = NULL;
 | 
		
	
		
			
			| 244 | 247 |    FILE *pf = NULL, *sf = NULL;
 | 
		
	
	
		
			
			|  | @@ -256,7 +259,7 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 256 | 259 |    tmp = strrchr(argv[0], '/');
 | 
		
	
		
			
			| 257 | 260 |    if (tmp) self = strdup(tmp + 1); else self = strdup(argv[0]);
 | 
		
	
		
			
			| 258 | 261 |  
 | 
		
	
		
			
			| 259 |  | -  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:X::Dhv")) != -1) {
 | 
		
	
		
			
			|  | 262 | +  while ((opt = getopt(argc, argv, "46d:a:f:r:s:u:t:p:c:X::Dhev")) != -1) {
 | 
		
	
		
			
			| 260 | 263 |      switch (opt) {
 | 
		
	
		
			
			| 261 | 264 |        case '?':
 | 
		
	
		
			
			| 262 | 265 |          return EXIT_FAILURE;
 | 
		
	
	
		
			
			|  | @@ -269,6 +272,9 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 269 | 272 |        case 'd':
 | 
		
	
		
			
			| 270 | 273 |          domain = strdup(optarg);
 | 
		
	
		
			
			| 271 | 274 |          break;
 | 
		
	
		
			
			|  | 275 | +      case 'a':
 | 
		
	
		
			
			|  | 276 | +        separator = *optarg;
 | 
		
	
		
			
			|  | 277 | +        break;
 | 
		
	
		
			
			| 272 | 278 |        case 'f':
 | 
		
	
		
			
			| 273 | 279 |          forward_service = strdup(optarg);
 | 
		
	
		
			
			| 274 | 280 |          break;
 | 
		
	
	
		
			
			|  | @@ -314,6 +320,42 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 314 | 320 |            excludes[s1] = NULL;
 | 
		
	
		
			
			| 315 | 321 |          }
 | 
		
	
		
			
			| 316 | 322 |          break;
 | 
		
	
		
			
			|  | 323 | +      case 'e':
 | 
		
	
		
			
			|  | 324 | +        if ( getenv("SRS_DOMAIN") != NULL )
 | 
		
	
		
			
			|  | 325 | +          domain = strdup(getenv("SRS_DOMAIN"));
 | 
		
	
		
			
			|  | 326 | +        if ( getenv("SRS_SEPARATOR") != NULL )
 | 
		
	
		
			
			|  | 327 | +          separator = *getenv("SRS_SEPARATOR");
 | 
		
	
		
			
			|  | 328 | +        if ( getenv("SRS_FORWARD_PORT") != NULL )
 | 
		
	
		
			
			|  | 329 | +          forward_service = strdup(getenv("SRS_FORWARD_PORT"));
 | 
		
	
		
			
			|  | 330 | +        if ( getenv("SRS_REVERSE_PORT") != NULL )
 | 
		
	
		
			
			|  | 331 | +          reverse_service = strdup(getenv("SRS_REVERSE_PORT"));
 | 
		
	
		
			
			|  | 332 | +        if ( getenv("SRS_TIMEOUT") != NULL )
 | 
		
	
		
			
			|  | 333 | +          timeout = atoi(getenv("SRS_TIMEOUT"));
 | 
		
	
		
			
			|  | 334 | +        if ( getenv("SRS_SECRET") != NULL )
 | 
		
	
		
			
			|  | 335 | +          secret_file = strdup(getenv("SRS_SECRET"));
 | 
		
	
		
			
			|  | 336 | +        if ( getenv("SRS_PID_FILE") != NULL )
 | 
		
	
		
			
			|  | 337 | +          pid_file = strdup(getenv("SRS_PID_FILE"));
 | 
		
	
		
			
			|  | 338 | +        if ( getenv("RUN_AS") != NULL )
 | 
		
	
		
			
			|  | 339 | +          user = strdup(getenv("RUN_AS"));
 | 
		
	
		
			
			|  | 340 | +        if ( getenv("CHROOT") != NULL )
 | 
		
	
		
			
			|  | 341 | +          chroot_dir = strdup(getenv("CHROOT"));
 | 
		
	
		
			
			|  | 342 | +        if (getenv("SRS_EXCLUDE_DOMAINS") != NULL) {
 | 
		
	
		
			
			|  | 343 | +          tmp = strtok(getenv("SRS_EXCLUDE_DOMAINS"), ",; \t\r\n");
 | 
		
	
		
			
			|  | 344 | +          while (tmp) {
 | 
		
	
		
			
			|  | 345 | +            if (s1 + 1 >= s2) {
 | 
		
	
		
			
			|  | 346 | +              s2 *= 2;
 | 
		
	
		
			
			|  | 347 | +              excludes = (const char **)realloc(excludes, s2 * sizeof(char*));
 | 
		
	
		
			
			|  | 348 | +              if (excludes == NULL) {
 | 
		
	
		
			
			|  | 349 | +                fprintf (stderr, "%s: Out of memory\n\n", self);
 | 
		
	
		
			
			|  | 350 | +                return EXIT_FAILURE;
 | 
		
	
		
			
			|  | 351 | +              }
 | 
		
	
		
			
			|  | 352 | +            }
 | 
		
	
		
			
			|  | 353 | +            excludes[s1++] = strdup(tmp);
 | 
		
	
		
			
			|  | 354 | +            tmp = strtok(NULL, ",; \t\r\n");
 | 
		
	
		
			
			|  | 355 | +          }
 | 
		
	
		
			
			|  | 356 | +          excludes[s1] = NULL;
 | 
		
	
		
			
			|  | 357 | +        }
 | 
		
	
		
			
			|  | 358 | +        break;
 | 
		
	
		
			
			| 317 | 359 |        case 'v':
 | 
		
	
		
			
			| 318 | 360 |          fprintf (stdout, "%s\n", VERSION);
 | 
		
	
		
			
			| 319 | 361 |          return EXIT_SUCCESS;
 | 
		
	
	
		
			
			|  | @@ -328,6 +370,11 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 328 | 370 |      return EXIT_FAILURE;
 | 
		
	
		
			
			| 329 | 371 |    }
 | 
		
	
		
			
			| 330 | 372 |  
 | 
		
	
		
			
			|  | 373 | +  if (separator != '=' && separator != '+' && separator != '-') {
 | 
		
	
		
			
			|  | 374 | +    fprintf (stderr, "%s: SRS separator character must be one of '=+-'\n", self);
 | 
		
	
		
			
			|  | 375 | +    return EXIT_FAILURE;
 | 
		
	
		
			
			|  | 376 | +  }
 | 
		
	
		
			
			|  | 377 | +
 | 
		
	
		
			
			| 331 | 378 |    /* The stuff we do first may not be possible from within chroot or without privileges */
 | 
		
	
		
			
			| 332 | 379 |  
 | 
		
	
		
			
			| 333 | 380 |    /* Open pid file for writing (the actual process ID is filled in later) */
 | 
		
	
	
		
			
			|  | @@ -420,7 +467,8 @@ int main (int argc, char **argv)
 | 
		
	
		
			
			| 420 | 467 |        srs_add_secret (srs, secret);
 | 
		
	
		
			
			| 421 | 468 |    }
 | 
		
	
		
			
			| 422 | 469 |    fclose (sf);
 | 
		
	
		
			
			| 423 |  | -  srs_set_separator (srs, '+');
 | 
		
	
		
			
			|  | 470 | +
 | 
		
	
		
			
			|  | 471 | +  srs_set_separator (srs, separator);
 | 
		
	
		
			
			| 424 | 472 |  
 | 
		
	
		
			
			| 425 | 473 |    fds[0].fd = forward_sock;
 | 
		
	
		
			
			| 426 | 474 |    fds[0].events = POLLIN;
 |