diff --git a/config/config.reuseaddr.c b/config/config.reuseaddr.c new file mode 100644 index 000000000..45b0d544b --- /dev/null +++ b/config/config.reuseaddr.c @@ -0,0 +1,87 @@ + +#if defined(__MINGW__) || defined(__MINGW32__) +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif /* __MINGW__ */ + +#include +#include +#include +#include + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +// Maximum data in single I/O operation +#define NETBUF_SIZE 4096 + +main() +{ + struct sockaddr_in sin; + int size = sizeof(sin); + int status = 1; + int port; + int net; + + memset(&sin, '\0', sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = 0; + + if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) + { + fprintf(stderr, "unable to create socket 1\n"); + return 2; + } + + setsockopt(net, SOL_SOCKET, SO_REUSEADDR, (char *)&status, sizeof(status)); + + if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0) + { + fprintf(stderr, "unable to bind socket 1\n"); + (void) close(net); + return 2; + } + + listen(net, 5); + + if (getsockname(net, (struct sockaddr*)&sin, &size) < 0) + { + fprintf(stderr, "unable to get socket 1 name\n"); + (void) close(net); + return 2; + } + + port = sin.sin_port; + memset(&sin, '\0', sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = port; + + if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) + { + fprintf(stderr, "unable to create socket 2\n"); + return 2; + } + + setsockopt(net, SOL_SOCKET, SO_REUSEADDR, (char *)&status, sizeof(status)); + + /* + * Now ... this bind should fail unless SO_REUSEADDR is broken. + */ + if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0) + { + return 0; + } + return 1; +} +