int sk_addrtype(SockAddr addr);
void sk_addrcopy(SockAddr addr, char *buf);
void sk_addr_free(SockAddr addr);
+/* sk_addr_dup generates another SockAddr which contains the same data
+ * as the original one and can be freed independently. May not actually
+ * physically _duplicate_ it: incrementing a reference count so that
+ * one more free is required before it disappears is an acceptable
+ * implementation. */
+SockAddr sk_addr_dup(SockAddr addr);
/* NB, control of 'addr' is passed via sk_new, which takes responsibility
* for freeing it, as for new_connection() */
};
struct SockAddr_tag {
+ int refcount;
const char *error;
enum { UNRESOLVED, UNIX, IP } superfamily;
#ifndef NO_IPV6
ret->superfamily = UNRESOLVED;
*realhost = '\0';
ret->error = NULL;
+ ret->refcount = 1;
#ifndef NO_IPV6
hints.ai_flags = AI_CANONNAME;
#else
ret->addresses = NULL;
#endif
+ ret->refcount = 1;
return ret;
}
void sk_addr_free(SockAddr addr)
{
-
+ if (--addr->refcount > 0)
+ return;
#ifndef NO_IPV6
if (addr->ais != NULL)
freeaddrinfo(addr->ais);
sfree(addr);
}
+SockAddr sk_addr_dup(SockAddr addr)
+{
+ addr->refcount++;
+ return addr;
+}
+
static Plug sk_tcp_plug(Socket sock, Plug p)
{
Actual_Socket s = (Actual_Socket) sock;
ret->addresses = NULL;
ret->naddresses = 0;
#endif
+ ret->refcount = 1;
return ret;
}
};
struct SockAddr_tag {
+ int refcount;
char *error;
int resolved;
#ifndef NO_IPV6
#endif
ret->addresses = NULL;
ret->resolved = FALSE;
+ ret->refcount = 1;
*realhost = '\0';
if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
#endif
ret->addresses = NULL;
ret->naddresses = 0;
+ ret->refcount = 1;
strncpy(ret->hostname, host, lenof(ret->hostname));
ret->hostname[lenof(ret->hostname)-1] = '\0';
return ret;
void sk_addr_free(SockAddr addr)
{
+ if (--addr->refcount > 0)
+ return;
#ifndef NO_IPV6
if (addr->ais && p_freeaddrinfo)
p_freeaddrinfo(addr->ais);
sfree(addr);
}
+SockAddr sk_addr_dup(SockAddr addr)
+{
+ addr->refcount++;
+ return addr;
+}
+
static Plug sk_tcp_plug(Socket sock, Plug p)
{
Actual_Socket s = (Actual_Socket) sock;
SockAddr ret = snew(struct SockAddr_tag);
memset(ret, 0, sizeof(struct SockAddr_tag));
ret->error = "unix sockets not supported on this platform";
+ ret->refcount = 1;
return ret;
}