summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pjlib-util/src/pjlib-util/dns_dump.c4
-rw-r--r--pjlib/include/pj/sock.h39
-rw-r--r--pjlib/src/pj/ip_helper_generic.c3
-rw-r--r--pjlib/src/pj/sock_common.c94
4 files changed, 134 insertions, 6 deletions
diff --git a/pjlib-util/src/pjlib-util/dns_dump.c b/pjlib-util/src/pjlib-util/dns_dump.c
index 6bb5cdc2..324f0569 100644
--- a/pjlib-util/src/pjlib-util/dns_dump.c
+++ b/pjlib-util/src/pjlib-util/dns_dump.c
@@ -120,8 +120,8 @@ static void dump_answer(unsigned index, const pj_dns_parsed_rr *rr)
} else if (rr->type == PJ_DNS_TYPE_AAAA) {
char addr[PJ_INET6_ADDRSTRLEN];
PJ_LOG(3,(THIS_FILE, " IPv6 address: %s",
- pj_inet_ntop(pj_AF_INET6(), &rr->rdata.aaaa.ip_addr,
- addr, sizeof(addr))));
+ pj_inet_ntop2(pj_AF_INET6(), &rr->rdata.aaaa.ip_addr,
+ addr, sizeof(addr))));
}
}
diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h
index 4adfbd65..4f54dbf0 100644
--- a/pjlib/include/pj/sock.h
+++ b/pjlib/include/pj/sock.h
@@ -595,7 +595,8 @@ PJ_DECL(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst);
/**
* This function converts a numeric address into a text string suitable
* for presentation. It supports both IPv4 and IPv6 address
- * conversion.
+ * conversion.
+ * @see pj_sockaddr_print()
*
* @param af Specify the family of the address. This can be PJ_AF_INET
* or PJ_AF_INET6.
@@ -615,6 +616,7 @@ PJ_DECL(pj_status_t) pj_inet_ntop(int af, const void *src,
/**
* Converts numeric address into its text string representation.
+ * @see pj_sockaddr_print()
*
* @param af Specify the family of the address. This can be PJ_AF_INET
* or PJ_AF_INET6.
@@ -632,6 +634,21 @@ PJ_DECL(pj_status_t) pj_inet_ntop(int af, const void *src,
PJ_DECL(char*) pj_inet_ntop2(int af, const void *src,
char *dst, int size);
+/**
+ * Print socket address.
+ *
+ * @param addr The socket address.
+ * @param buf Text buffer.
+ * @param size Size of buffer.
+ * @param flags Bitmask combination of these value:
+ * - 1: port number is included.
+ * - 2: square bracket is included for IPv6 address.
+ *
+ * @return The address string.
+ */
+PJ_DECL(char*) pj_sockaddr_print(const pj_sockaddr_t *addr,
+ char *buf, int size,
+ unsigned flags);
/**
* Convert address string with numbers and dots to binary IP address.
@@ -702,6 +719,18 @@ PJ_DECL(pj_status_t) pj_sockaddr_init(int af,
pj_uint16_t port);
/**
+ * Compare two socket addresses.
+ *
+ * @param addr1 First address.
+ * @param addr2 Second address.
+ *
+ * @return Zero on equal, -1 if addr1 is less than addr2,
+ * and +1 if addr1 is more than addr2.
+ */
+PJ_DECL(int) pj_sockaddr_cmp(const pj_sockaddr_t *addr1,
+ const pj_sockaddr_t *addr2);
+
+/**
* Get pointer to the address part of a socket address.
*
* @param addr Socket address.
@@ -742,6 +771,14 @@ PJ_DECL(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr);
*/
PJ_DECL(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr);
+/**
+ * Copy only the address part (sin_addr/sin6_addr) of a socket address.
+ *
+ * @param dst Destination socket address.
+ * @param src Source socket address.
+ */
+PJ_DECL(void) pj_sockaddr_copy_addr(pj_sockaddr *dst,
+ const pj_sockaddr *src);
/**
* Get the IP address of an IPv4 socket address.
* The address is returned as 32bit value in host byte order.
diff --git a/pjlib/src/pj/ip_helper_generic.c b/pjlib/src/pj/ip_helper_generic.c
index 3e1d8323..7d4c6fc9 100644
--- a/pjlib/src/pj/ip_helper_generic.c
+++ b/pjlib/src/pj/ip_helper_generic.c
@@ -273,9 +273,6 @@ static pj_status_t if_enum_by_af(int af,
PJ_ASSERT_RETURN(p_cnt && *p_cnt > 0 && ifs, PJ_EINVAL);
- PJ_UNUSED_ARG(&get_addr);
- PJ_UNUSED_ARG(&get_os_errmsg);
-
pj_bzero(ifs, sizeof(ifs[0]) * (*p_cnt));
/* Just get one default route */
diff --git a/pjlib/src/pj/sock_common.c b/pjlib/src/pj/sock_common.c
index 1c108336..5bf19d0c 100644
--- a/pjlib/src/pj/sock_common.c
+++ b/pjlib/src/pj/sock_common.c
@@ -59,6 +59,48 @@ PJ_DEF(char*) pj_inet_ntop2( int af, const void *src,
}
/*
+ * Print socket address.
+ */
+PJ_DEF(char*) pj_sockaddr_print( const pj_sockaddr_t *addr,
+ char *buf, int size,
+ unsigned flags)
+{
+ enum {
+ WITH_PORT = 1,
+ WITH_BRACKETS = 2
+ };
+
+ char txt[PJ_INET6_ADDRSTRLEN];
+ char port[32];
+ const pj_addr_hdr *h = (const pj_addr_hdr*)addr;
+ char *bquote, *equote;
+ pj_status_t status;
+
+ status = pj_inet_ntop(h->sa_family, pj_sockaddr_get_addr(addr),
+ txt, sizeof(txt));
+ if (status != PJ_SUCCESS)
+ return "";
+
+ if (h->sa_family != PJ_AF_INET6 || (flags & WITH_BRACKETS)==0) {
+ bquote = ""; equote = "";
+ } else {
+ bquote = "["; equote = "]";
+ }
+
+ if (flags & WITH_PORT) {
+ pj_ansi_snprintf(port, sizeof(port), ":%d",
+ pj_sockaddr_get_port(addr));
+ } else {
+ port[0] = '\0';
+ }
+
+ pj_ansi_snprintf(buf, size, "%s%s%s%s",
+ bquote, txt, equote, port);
+
+ return buf;
+}
+
+/*
* Set the IP address of an IP socket address from string address,
* with resolving the host if necessary. The string address may be in a
* standard numbers and dots notation or may be a hostname. If hostname
@@ -184,6 +226,47 @@ PJ_DEF(pj_status_t) pj_sockaddr_init(int af,
}
/*
+ * Compare two socket addresses.
+ */
+PJ_DEF(int) pj_sockaddr_cmp( const pj_sockaddr_t *addr1,
+ const pj_sockaddr_t *addr2)
+{
+ const pj_sockaddr *a1 = (const pj_sockaddr*) addr1;
+ const pj_sockaddr *a2 = (const pj_sockaddr*) addr2;
+ int port1, port2;
+ int result;
+
+ /* Compare address family */
+ if (a1->addr.sa_family < a2->addr.sa_family)
+ return -1;
+ else if (a1->addr.sa_family > a2->addr.sa_family)
+ return 1;
+
+ /* Compare addresses */
+ result = pj_memcmp(pj_sockaddr_get_addr(a1),
+ pj_sockaddr_get_addr(a2),
+ pj_sockaddr_get_addr_len(a1));
+ if (result != 0)
+ return result;
+
+ /* Compare port number */
+ port1 = pj_sockaddr_get_port(a1);
+ port2 = pj_sockaddr_get_port(a2);
+
+ if (port1 < port2)
+ return -1;
+ else if (port1 > port2)
+ return 1;
+
+ /* TODO:
+ * Do we need to compare flow label and scope id in IPv6?
+ */
+
+ /* Looks equal */
+ return 0;
+}
+
+/*
* Get first IP address associated with the hostname.
*/
PJ_DEF(pj_in_addr) pj_gethostaddr(void)
@@ -277,6 +360,17 @@ PJ_DEF(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr)
}
/*
+ * Copy only the address part (sin_addr/sin6_addr) of a socket address.
+ */
+PJ_DEF(void) pj_sockaddr_copy_addr( pj_sockaddr *dst,
+ const pj_sockaddr *src)
+{
+ pj_memcpy(pj_sockaddr_get_addr(dst),
+ pj_sockaddr_get_addr(src),
+ pj_sockaddr_get_addr_len(src));
+}
+
+/*
* Set port number of pj_sockaddr_in
*/
PJ_DEF(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr,