Fix NULL pointer segfault in ast_sockaddr_parse()
[asterisk/asterisk.git] / include / asterisk / netsock2.h
index 888861c..b14c1af 100644 (file)
@@ -43,12 +43,22 @@ enum {
 };
 
 /*!
- * Socket address structure. The first member is big enough to contain addresses
- * of any family. The second member contains the length (in bytes) used in the
- * first member.
+ * \brief Socket address structure.
  *
- * Some BSDs have the length embedded in sockaddr structs. We ignore them.
- * (This is the right thing to do.)
+ * \details
+ * The first member is big enough to contain addresses of any
+ * family. The second member contains the length (in bytes) used
+ * in the first member.
+ *
+ * \note
+ * Some BSDs have the length embedded in sockaddr structs. We
+ * ignore them. (This is the right thing to do.)
+ *
+ * \note
+ * It is important to always initialize ast_sockaddr before use
+ * -- even if they are passed to ast_sockaddr_copy() as the
+ * underlying storage could be bigger than what ends up being
+ * copied -- leaving part of the data unitialized.
  */
 struct ast_sockaddr {
        struct sockaddr_storage  ss;
@@ -142,8 +152,13 @@ int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockadd
 #define AST_SOCKADDR_STR_ADDR          (1 << 0)
 #define AST_SOCKADDR_STR_PORT          (1 << 1)
 #define AST_SOCKADDR_STR_BRACKETS      (1 << 2)
-#define AST_SOCKADDR_STR_HOST          AST_SOCKADDR_STR_ADDR | AST_SOCKADDR_STR_BRACKETS
-#define AST_SOCKADDR_STR_DEFAULT       AST_SOCKADDR_STR_ADDR | AST_SOCKADDR_STR_PORT
+#define AST_SOCKADDR_STR_REMOTE                (1 << 3)
+#define AST_SOCKADDR_STR_HOST          (AST_SOCKADDR_STR_ADDR | AST_SOCKADDR_STR_BRACKETS)
+#define AST_SOCKADDR_STR_DEFAULT       (AST_SOCKADDR_STR_ADDR | AST_SOCKADDR_STR_PORT)
+#define AST_SOCKADDR_STR_ADDR_REMOTE     (AST_SOCKADDR_STR_ADDR | AST_SOCKADDR_STR_REMOTE)
+#define AST_SOCKADDR_STR_HOST_REMOTE     (AST_SOCKADDR_STR_HOST | AST_SOCKADDR_STR_REMOTE)
+#define AST_SOCKADDR_STR_DEFAULT_REMOTE  (AST_SOCKADDR_STR_DEFAULT | AST_SOCKADDR_STR_REMOTE)
+#define AST_SOCKADDR_STR_FORMAT_MASK     (AST_SOCKADDR_STR_ADDR | AST_SOCKADDR_STR_PORT | AST_SOCKADDR_STR_BRACKETS)
 
 /*!
  * \since 1.8
@@ -170,6 +185,14 @@ int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockadd
  *    a.b.c.d for IPv4
  *    [a:b:c:...:d] for IPv6.
  * AST_SOCKADDR_STR_PORT: port only
+ *
+ * \note The string pointer returned by this function will point to a string that
+ * will be changed whenever any form of ast_sockaddr_stringify_fmt is called on that
+ * thread. Because of this, it is important that if you use this function, you use the
+ * string before another use of this function is made elsewhere in the same thread.
+ * The easiest way to accomplish this is by immediately copying the string to a buffer
+ * with something like ast_strdupa.
+ *
  * \retval "(null)" \a addr is null
  * \retval "" An error occurred during processing
  * \retval string The stringified form of the address
@@ -193,6 +216,23 @@ static inline char *ast_sockaddr_stringify(const struct ast_sockaddr *addr)
  * \since 1.8
  *
  * \brief
+ * Wrapper around ast_sockaddr_stringify_fmt() with default format
+ *
+ * \note This address will be suitable for passing to a remote machine via the
+ * application layer. For example, the scope-id on a link-local IPv6 address
+ * will be stripped.
+ *
+ * \return same as ast_sockaddr_stringify_fmt()
+ */
+static inline char *ast_sockaddr_stringify_remote(const struct ast_sockaddr *addr)
+{
+       return ast_sockaddr_stringify_fmt(addr, AST_SOCKADDR_STR_DEFAULT_REMOTE);
+}
+
+/*!
+ * \since 1.8
+ *
+ * \brief
  * Wrapper around ast_sockaddr_stringify_fmt() to return an address only
  *
  * \return same as ast_sockaddr_stringify_fmt()
@@ -206,6 +246,23 @@ static inline char *ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
  * \since 1.8
  *
  * \brief
+ * Wrapper around ast_sockaddr_stringify_fmt() to return an address only
+ *
+ * \note This address will be suitable for passing to a remote machine via the
+ * application layer. For example, the scope-id on a link-local IPv6 address
+ * will be stripped.
+ *
+ * \return same as ast_sockaddr_stringify_fmt()
+ */
+static inline char *ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
+{
+       return ast_sockaddr_stringify_fmt(addr, AST_SOCKADDR_STR_ADDR_REMOTE);
+}
+
+/*!
+ * \since 1.8
+ *
+ * \brief
  * Wrapper around ast_sockaddr_stringify_fmt() to return an address only,
  * suitable for a URL (with brackets for IPv6).
  *
@@ -220,6 +277,24 @@ static inline char *ast_sockaddr_stringify_host(const struct ast_sockaddr *addr)
  * \since 1.8
  *
  * \brief
+ * Wrapper around ast_sockaddr_stringify_fmt() to return an address only,
+ * suitable for a URL (with brackets for IPv6).
+ *
+ * \note This address will be suitable for passing to a remote machine via the
+ * application layer. For example, the scope-id on a link-local IPv6 address
+ * will be stripped.
+ *
+ * \return same as ast_sockaddr_stringify_fmt()
+ */
+static inline char *ast_sockaddr_stringify_host_remote(const struct ast_sockaddr *addr)
+{
+       return ast_sockaddr_stringify_fmt(addr, AST_SOCKADDR_STR_HOST_REMOTE);
+}
+
+/*!
+ * \since 1.8
+ *
+ * \brief
  * Wrapper around ast_sockaddr_stringify_fmt() to return a port only
  *
  * \return same as ast_sockaddr_stringify_fmt()
@@ -268,7 +343,8 @@ int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags);
  *
  * Host names are NOT allowed.
  *
- * \param[out] addr The resulting ast_sockaddr
+ * \param[out] addr The resulting ast_sockaddr. This MAY be NULL from 
+ * functions that are performing validity checks only, e.g. ast_parse_arg().
  * \param str The string to parse
  * \param flags If set to zero, a port MAY be present. If set to
  * PARSE_PORT_IGNORE, a port MAY be present but will be ignored. If set to
@@ -307,7 +383,7 @@ int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags);
  * port MUST NOT be present.
  *
  * \param family Only addresses of the given family will be returned. Use 0 or
- * AST_SOCKADDR_UNSPEC to get addresses of all families.
+ * AST_AF_UNSPEC to get addresses of all families.
  *
  * \retval 0 Failure
  * \retval non-zero The number of elements in addrs array.
@@ -386,7 +462,7 @@ int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr);
 int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr);
 
 /*!
- * \since 1.10
+ * \since 10.0
  *
  * \brief
  * Determine if an IPv4 address is a multicast address
@@ -403,6 +479,20 @@ int ast_sockaddr_is_ipv4_multicast(const struct ast_sockaddr *addr);
  * \since 1.8
  *
  * \brief
+ * Determine if this is a link-local IPv6 address
+ *
+ * \warning You should rarely need this function. Only use if you know what
+ * you're doing.
+ *
+ * \retval 1 This is a link-local IPv6 address.
+ * \retval 0 This is link-local IPv6 address.
+ */
+int ast_sockaddr_is_ipv6_link_local(const struct ast_sockaddr *addr);
+
+/*!
+ * \since 1.8
+ *
+ * \brief
  * Determine if this is an IPv6 address
  *
  * \warning You should rarely need this function. Only use if you know what