Fix NULL pointer segfault in ast_sockaddr_parse()
[asterisk/asterisk.git] / include / asterisk / netsock2.h
index 24330d2..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()
@@ -233,6 +308,26 @@ static inline char *ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
  * \since 1.8
  *
  * \brief
+ * Splits a string into its host and port components
+ *
+ * \param str[in]   The string to parse. May be modified by writing a NUL at the end of
+ *                  the host part.
+ * \param host[out] Pointer to the host component within \a str.
+ * \param port[out] Pointer to the port component within \a str.
+ * \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 PARSE_PORT_REQUIRE,
+ *                  a port MUST be present. If set to PARSE_PORT_FORBID, a port MUST NOT
+ *                  be present.
+ *
+ * \retval 1 Success
+ * \retval 0 Failure
+ */
+int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags);
+
+/*!
+ * \since 1.8
+ *
+ * \brief
  * Parse an IPv4 or IPv6 address string.
  *
  * \details
@@ -248,7 +343,8 @@ static inline char *ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
  *
  * 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
@@ -287,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.
@@ -366,6 +462,34 @@ int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr);
 int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr);
 
 /*!
+ * \since 10.0
+ *
+ * \brief
+ * Determine if an IPv4 address is a multicast address
+ *
+ * \parm addr the address to check
+ *
+ * This function checks if an address is in the 224.0.0.0/4 network block.
+ *
+ * \return non-zero if this is a multicast address
+ */
+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