ported some hard-to-merge cherries back to trunk :-/
[strongswan.git] / src / libstrongswan / utils / host.c
index cfcb873..8c79f71 100644 (file)
@@ -504,38 +504,56 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port)
  */
 host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
 {
-       private_host_t *this = host_create_empty();
+       private_host_t *this;
        
-       this->address.sa_family = family;
        switch (family)
        {
                case AF_INET:
-               {
-                       if (address.len != IPV4_LEN)
+                       if (address.len < IPV4_LEN)
                        {
-                               break;
+                               return NULL;
                        }
-                       memcpy(&(this->address4.sin_addr.s_addr), address.ptr, IPV4_LEN);
-                       this->address4.sin_port = htons(port);
-                       this->socklen = sizeof(struct sockaddr_in);
-                       return &(this->public);
-               }
+                       address.len = IPV4_LEN;
+                       break;
                case AF_INET6:
-               {
-                       if (address.len != IPV6_LEN)
+                       if (address.len < IPV6_LEN)
                        {
-                               break;
+                               return NULL;
                        }
-                       memcpy(&(this->address6.sin6_addr.s6_addr), address.ptr, IPV6_LEN);
+                       address.len = IPV6_LEN;
+                       break;
+               case AF_UNSPEC:
+                       switch (address.len)
+                       {
+                               case IPV4_LEN:
+                                       family = AF_INET;
+                                       break;
+                               case IPV6_LEN:
+                                       family = AF_INET6;
+                                       break;
+                               default:
+                                       return NULL;
+                       }
+                       break;
+               default:
+                       return NULL;
+       }
+       this = host_create_empty();
+       this->address.sa_family = family;
+       switch (family)
+       {
+               case AF_INET:
+                       memcpy(&this->address4.sin_addr.s_addr, address.ptr, address.len);
+                       this->address4.sin_port = htons(port);
+                       this->socklen = sizeof(struct sockaddr_in);
+                       break;
+               case AF_INET6:
+                       memcpy(&this->address6.sin6_addr.s6_addr, address.ptr, address.len);
                        this->address6.sin6_port = htons(port);
                        this->socklen = sizeof(struct sockaddr_in6);
-                       return &this->public;
-               }
-               default:
                        break;
        }
-       free(this);
-       return NULL;
+       return &this->public;
 }
 
 /*