--- sa.c 2001/10/11 15:20:30 1.33
+++ sa.c 2001/10/24 11:23:17 1.34
@@ -426,6 +426,7 @@
#ifdef AF_INET6
struct sockaddr_in6 sa6;
#endif
+ int bIPv6;
struct hostent *he;
struct servent *se;
int bNumeric;
@@ -487,12 +488,36 @@
sf = AF_LOCAL;
}
else if (strncmp(uri, "inet://", 7) == 0) {
- /* parse URI */
+ /* parse URI into host, port and protocol parts */
cpHost = (char *)(uri+7);
- if ((cp = strrchr(cpHost, ':')) == NULL)
+ bIPv6 = FALSE;
+ if (cpHost[0] == '[') {
+ /* IPv6 address (see RFC2732) */
+#ifndef AF_INET6
return SA_ERR_ARG;
- *cp++ = '\0';
+#else
+ bIPv6 = TRUE;
+ cpHost++;
+ if ((cp = strchr(cpHost, ']')) == NULL)
+ return SA_ERR_ARG;
+ *cp++ = '\0';
+ if (*cp != ':')
+ return SA_ERR_ARG;
+ cp++;
+#endif
+ }
+ else {
+ /* IPv4 address or hostname */
+ if ((cp = strrchr(cpHost, ':')) == NULL)
+ return SA_ERR_ARG;
+ *cp++ = '\0';
+ }
cpPort = cp;
+ cpProto = "tcp";
+ if ((cp = strchr(cpPort, '#')) != NULL) {
+ *cp++ = '\0';
+ cpProto = cp;
+ }
/* resolve port */
nPort = 0;
@@ -506,11 +531,6 @@
if (bNumeric)
nPort = atoi(cpPort);
else {
- cpProto = "tcp";
- if ((cp = strchr(cpPort, '#')) != NULL) {
- *cp++ = '\0';
- cpProto = cp;
- }
if ((se = getservbyname(cpPort, cpProto)) == NULL)
return SA_ERR_SYS;
nPort = ntohs(se->s_port);
@@ -522,9 +542,9 @@
memset(&sa6, 0, sizeof(sa6));
#endif
- /* resolve host by trying to parse it as either directly a IPv4 or
- IPv6 address or by resolving it to either a IPv4 or IPv6 address */
- if (sa_inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
+ /* resolve host by trying to parse it as either directly an IPv4 or
+ IPv6 address or by resolving it to either an IPv4 or IPv6 address */
+ if (!bIPv6 && sa_inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
sa4.sin_family = AF_INET;
sa4.sin_port = htons(nPort);
sa = (struct sockaddr *)&sa4;
@@ -532,7 +552,7 @@
sf = AF_INET;
}
#ifdef AF_INET6
- else if (sa_inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
+ else if (bIPv6 && sa_inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
sa6.sin6_family = AF_INET6;
sa6.sin6_port = htons(nPort);
sa = (struct sockaddr *)&sa6;
@@ -633,25 +653,20 @@
else
sa_msnprintf(uribuf, sizeof(uribuf), "unix:%s", un->sun_path);
}
-#ifdef AF_INET6
- else if (saa->nFamily == AF_INET || saa->nFamily == AF_INET6) {
-#else
else if (saa->nFamily == AF_INET) {
-#endif
- if (saa->nFamily == AF_INET) {
- sa4 = (struct sockaddr_in *)((void *)saa->saBuf);
- sa_inet_ntop(AF_INET, &sa4->sin_addr.s_addr, caHost, sizeof(caHost));
- nPort = ntohs(sa4->sin_port);
- }
-#ifdef AF_INET6
- else {
- sa6 = (struct sockaddr_in6 *)((void *)saa->saBuf);
- sa_inet_ntop(AF_INET6, &sa6->sin6_addr.s6_addr, caHost, sizeof(caHost));
- nPort = ntohs(sa6->sin6_port);
- }
-#endif
+ sa4 = (struct sockaddr_in *)((void *)saa->saBuf);
+ sa_inet_ntop(AF_INET, &sa4->sin_addr.s_addr, caHost, sizeof(caHost));
+ nPort = ntohs(sa4->sin_port);
sa_msnprintf(uribuf, sizeof(uribuf), "inet://%s:%d", caHost, nPort);
}
+#ifdef AF_INET6
+ else if (saa->nFamily == AF_INET6) {
+ sa6 = (struct sockaddr_in6 *)((void *)saa->saBuf);
+ sa_inet_ntop(AF_INET6, &sa6->sin6_addr.s6_addr, caHost, sizeof(caHost));
+ nPort = ntohs(sa6->sin6_port);
+ sa_msnprintf(uribuf, sizeof(uribuf), "inet://[%s]:%d", caHost, nPort);
+ }
+#endif
else
return SA_ERR_INT;
|