28
28
#define _GNU_SOURCE
29
29
#include <assert.h>
30
30
#include <errno.h>
31
+ #include <getopt.h>
31
32
#include <inttypes.h>
32
33
#include <netdb.h>
33
34
#include <netinet/in.h>
@@ -172,7 +173,7 @@ static bool proxy_client_process (struct proxy_connection *conn);
172
173
static void * proxy_client_work (void * ud );
173
174
174
175
/* proxy functions */
175
- static int proxy_init (struct proxy * proxy , int port );
176
+ static int proxy_init (struct proxy * proxy , const char * listen_address , const char * port );
176
177
static void proxy_free (struct proxy * proxy );
177
178
static void proxy_accept (struct proxy * proxy );
178
179
@@ -1212,9 +1213,11 @@ proxy_client_work (void *ud)
1212
1213
* connections.
1213
1214
*/
1214
1215
static int
1215
- proxy_init (struct proxy * proxy , int port )
1216
+ proxy_init (struct proxy * proxy , const char * listen_address , const char * port )
1216
1217
{
1217
- struct sockaddr_in6 addr ;
1218
+ struct addrinfo hints ;
1219
+ struct addrinfo * res = NULL ;
1220
+ int gai ;
1218
1221
1219
1222
proxy_log_init (& proxy -> log );
1220
1223
@@ -1237,12 +1240,26 @@ proxy_init (struct proxy *proxy, int port)
1237
1240
return -1 ;
1238
1241
}
1239
1242
1240
- proxy -> socket = socket (PF_INET6 , SOCK_STREAM , 0 );
1243
+ memset (& hints , 0 , sizeof (hints ));
1244
+ hints .ai_family = AF_UNSPEC ;
1245
+ hints .ai_socktype = SOCK_STREAM ;
1246
+
1247
+ gai = getaddrinfo (listen_address , port , & hints , & res );
1248
+
1249
+ if (gai != 0 )
1250
+ {
1251
+ fprintf (stderr , "getaddrinfo: %s\n" , gai_strerror (gai ));
1252
+
1253
+ return -1 ;
1254
+ }
1255
+
1256
+ proxy -> socket = socket (res -> ai_family , SOCK_STREAM , 0 );
1241
1257
1242
1258
if (proxy -> socket == -1 )
1243
1259
{
1244
1260
perror ("socket" );
1245
1261
1262
+ freeaddrinfo (res );
1246
1263
proxy_log_free (& proxy -> log );
1247
1264
1248
1265
if (pthread_attr_destroy (& proxy -> attr ) != 0 )
@@ -1259,6 +1276,7 @@ proxy_init (struct proxy *proxy, int port)
1259
1276
{
1260
1277
perror ("setsockopt" );
1261
1278
1279
+ freeaddrinfo (res );
1262
1280
proxy_log_free (& proxy -> log );
1263
1281
1264
1282
if (pthread_attr_destroy (& proxy -> attr ) != 0 )
@@ -1274,16 +1292,11 @@ proxy_init (struct proxy *proxy, int port)
1274
1292
return -1 ;
1275
1293
}
1276
1294
1277
- memset (& addr , 0 , sizeof (addr ));
1278
-
1279
- addr .sin6_family = AF_INET6 ;
1280
- addr .sin6_port = htons (port );
1281
- addr .sin6_addr = in6addr_any ;
1282
-
1283
- if (bind (proxy -> socket , (struct sockaddr * ) & addr , sizeof (addr )) == -1 )
1295
+ if (bind (proxy -> socket , res -> ai_addr , res -> ai_addrlen ) == -1 )
1284
1296
{
1285
1297
perror ("bind" );
1286
1298
1299
+ freeaddrinfo (res );
1287
1300
proxy_log_free (& proxy -> log );
1288
1301
1289
1302
if (pthread_attr_destroy (& proxy -> attr ) != 0 )
@@ -1299,6 +1312,8 @@ proxy_init (struct proxy *proxy, int port)
1299
1312
return -1 ;
1300
1313
}
1301
1314
1315
+ freeaddrinfo (res );
1316
+
1302
1317
if (listen (proxy -> socket , SOMAXCONN ) == -1 )
1303
1318
{
1304
1319
perror ("listen" );
@@ -1390,16 +1405,45 @@ proxy_accept (struct proxy *proxy)
1390
1405
int main (int argc , char * * argv )
1391
1406
{
1392
1407
struct proxy proxy ;
1408
+ const char * listen_address = "::" ;
1409
+ const char * listen_port = "8080" ;
1393
1410
1394
1411
/* Check arguments */
1395
- if ( argc != 2 )
1412
+ while ( 1 )
1396
1413
{
1397
- fprintf ( stderr , "Usage: %s <port number>\n" , argv [ 0 ]) ;
1414
+ int option_index = 0 ;
1398
1415
1399
- return EXIT_FAILURE ;
1416
+ static const struct option long_options [] = {
1417
+ { "listen" , required_argument , 0 , 'l' },
1418
+ { "port" , required_argument , 0 , 'p' },
1419
+ { "help" , no_argument , 0 , 'h' },
1420
+ { 0 , 0 , 0 , 0 }
1421
+ };
1422
+
1423
+ int c = getopt_long (argc , argv , "l:p:h" , long_options , & option_index );
1424
+
1425
+ if (c == -1 )
1426
+ break ;
1427
+
1428
+ switch (c )
1429
+ {
1430
+ case 'l' :
1431
+ listen_address = optarg ;
1432
+ break ;
1433
+ case 'p' :
1434
+ listen_port = optarg ;
1435
+ break ;
1436
+ default :
1437
+ printf ("Usage: %s [options]\n" , argv [0 ]);
1438
+ printf ("Options:\n" );
1439
+ printf ("\t-l, --listen Listen address (::)\n" );
1440
+ printf ("\t-p, --port Listen port (8080)\n" );
1441
+
1442
+ return EXIT_SUCCESS ;
1443
+ }
1400
1444
}
1401
1445
1402
- if (proxy_init (& proxy , atoi ( argv [ 1 ]) ) != 0 )
1446
+ if (proxy_init (& proxy , listen_address , listen_port ) != 0 )
1403
1447
{
1404
1448
return EXIT_FAILURE ;
1405
1449
}
0 commit comments