some code improvemetns, more efficiently removing outstanding requests when removing...
[radsecproxy.git] / util.c
diff --git a/util.c b/util.c
index 3ba212c..d9e2709 100644 (file)
--- a/util.c
+++ b/util.c
@@ -150,3 +150,49 @@ int connectport(int type, char *host, char *port) {
     freeaddrinfo(res0);
     return s;
 }
+
+int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
+    int s, on = 1;
+    struct addrinfo *res;
+
+    for (res = addrinfo; res; res = res->ai_next) {
+       if (family != AF_UNSPEC && family != res->ai_family)
+           continue;
+       s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+       if (s < 0) {
+           debug(DBG_WARN, "bindtoaddr: socket failed");
+           continue;
+       }
+       if (reuse)
+           setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+       #ifdef IPV6_V6ONLY
+       if (v6only)
+           setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+       #endif
+       if (!bind(s, res->ai_addr, res->ai_addrlen))
+           return s;
+       debug(DBG_WARN, "bindtoaddr: bind failed");
+       close(s);
+    }
+    return -1;
+}
+
+int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src) {
+    int s;
+    struct addrinfo *res;
+
+    s = -1;
+    for (res = addrinfo; res; res = res->ai_next) {
+       s = bindtoaddr(src, res->ai_family, 1, 1);
+       if (s < 0) {
+           debug(DBG_WARN, "connecttoserver: socket failed");
+           continue;
+       }
+       if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
+           break;
+       debug(DBG_WARN, "connecttoserver: connect failed");
+       close(s);
+       s = -1;
+    }
+    return s;
+}