-void dump_conn_list(void)
-{
- conn_list_t *p;
-cp
- syslog(LOG_DEBUG, _("Connection list:"));
-
- for(p = conn_list; p != NULL; p = p->next)
- {
- syslog(LOG_DEBUG, " " IP_ADDR_S "/" IP_ADDR_S ": %04x (%d|%d)",
- IP_ADDR_V(p->vpn_ip), IP_ADDR_V(p->vpn_mask), p->status,
- p->socket, p->meta_socket);
- }
-cp
+void sockaddrfree(sockaddr_t *a) {
+ if(a->sa.sa_family == AF_UNKNOWN) {
+ free(a->unknown.address);
+ free(a->unknown.port);
+ }
+}
+
+void sockaddrunmap(sockaddr_t *sa) {
+ if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr)) {
+ sa->in.sin_addr.s_addr = ((uint32_t *) & sa->in6.sin6_addr)[3];
+ sa->in.sin_family = AF_INET;
+ }
+}
+
+void sockaddr_setport(sockaddr_t *sa, const char *port) {
+ uint16_t portnum = htons(atoi(port));
+
+ if(!portnum) {
+ return;
+ }
+
+ switch(sa->sa.sa_family) {
+ case AF_INET:
+ sa->in.sin_port = portnum;
+ break;
+
+ case AF_INET6:
+ sa->in6.sin6_port = portnum;
+ break;
+
+ case AF_UNKNOWN:
+ free(sa->unknown.port);
+ sa->unknown.port = xstrdup(port);
+
+ default:
+ return;
+ }
+}
+
+uint16_t get_bound_port(int sockfd) {
+ sockaddr_t sa;
+ socklen_t salen = sizeof(sa);
+
+ if(getsockname(sockfd, (struct sockaddr *) &sa, &salen)) {
+ return 0;
+ }
+
+ if(sa.sa.sa_family == AF_INET) {
+ return ntohs(sa.in.sin_port);
+ } else if(sa.sa.sa_family == AF_INET6) {
+ return ntohs(sa.in6.sin6_port);
+ } else {
+ return 0;
+ }