Update documentation with info on multithread protection.
[radsecproxy.git] / lib / include / radsec / radsec.h
index 1aef6bb..1d718a0 100644 (file)
@@ -1,16 +1,27 @@
 /** \file radsec.h
     \brief Public interface for libradsec.  */
 
-/* See the file COPYING for licensing information.  */
+/* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
+   See LICENSE for licensing information. */
 
 #ifndef _RADSEC_RADSEC_H_
 #define _RADSEC_RADSEC_H_ 1
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
+#ifdef HAVE_STDINT_H
 #include <stdint.h>
-
-#include <arpa/inet.h>
-#include <sys/time.h>
+#endif
 
 enum rs_error_code {
     RSE_OK = 0,
@@ -19,7 +30,6 @@ enum rs_error_code {
     RSE_INVALID_CTX = 3,
     RSE_INVALID_CONN = 4,
     RSE_CONN_TYPE_MISMATCH = 5,
-    RSE_FR = 6,
     RSE_BADADDR = 7,
     RSE_NOPEER = 8,
     RSE_EVENT = 9,             /* libevent error.  */
@@ -32,7 +42,7 @@ enum rs_error_code {
     RSE_TIMEOUT_CONN = 16,     /* Connection timeout.  */
     RSE_INVAL = 17,            /* Invalid argument.  */
     RSE_TIMEOUT_IO = 18,       /* I/O timeout.  */
-    RSE_TIMEOUT= 19,           /* High level timeout.  */
+    RSE_TIMEOUT = 19,          /* High level timeout.  */
     RSE_DISCO = 20,
     RSE_INUSE = 21,
     RSE_PACKET_TOO_SMALL = 22,
@@ -56,7 +66,9 @@ enum rs_error_code {
     RSE_INVALID_RESPONSE_SRC = 40,
     RSE_NO_PACKET_DATA = 41,
     RSE_VENDOR_UNKNOWN = 42,
-    RSE_MAX = RSE_VENDOR_UNKNOWN
+    RSE_CRED = 43,
+    RSE_CERT = 44,
+    RSE_MAX = RSE_CERT
 };
 
 enum rs_conn_type {
@@ -156,30 +168,21 @@ typedef const struct value_pair rs_const_avp;
     that the context must not be freed before all other libradsec
     objects have been freed.
 
+    If support for POSIX threads was detected at configure and build
+    time \a rs_context_create will use mutexes to protect multiple
+    threads from stomping on each other in OpenSSL.
+
     \a ctx Address of pointer to a struct rs_context.  This is the
     output of this function.
 
-    \return RSE_OK (0) on success or RSE_NOMEM on out of memory.  */
+    \return RSE_OK (0) on success, RSE_SSLERR on TLS library
+    initialisation error and RSE_NOMEM on out of memory.  */
 int rs_context_create(struct rs_context **ctx);
 
 /** Free a context.  Note that the context must not be freed before
     all other libradsec objects have been freed.  */
 void rs_context_destroy(struct rs_context *ctx);
 
-/** Initialize FreeRADIUS dictionary needed for creating packets.
-
-    \a ctx Context.
-
-    \a dict Optional string with full path to FreeRADIUS dictionary.
-    If \a dict is NULL the path to the dictionary file is taken from
-    the "dictionary" configuration directive.  Note that the
-    configuration file must be read prior to using this option (see \a
-    rs_context_read_config).
-
-    \return RSE_OK (0) on success, RSE_NOMEM on memory allocation
-    error and RSE_FR on FreeRADIUS error.  */
-int rs_context_init_freeradius_dict(struct rs_context *ctx, const char *dict);
-
 /** Set allocation scheme to use.  \a scheme is the allocation scheme
     to use, see \a rs_alloc_scheme.  \return On success, RSE_OK (0) is
     returned.  On error, !0 is returned and a struct \a rs_error is
@@ -298,16 +301,21 @@ int rs_packet_create(struct rs_connection *conn, struct rs_packet **pkt_out);
 /** Free all memory allocated for packet \a pkt.  */
 void rs_packet_destroy(struct rs_packet *pkt);
 
-/** Send packet \a pkt on the connection associated with \a pkt.  \a
-    user_data is sent to the \a rs_conn_packet_received_cb callback
-    registered with the connection.  If no callback is registered with
+/** Send packet \a pkt on the connection associated with \a pkt.
+    \a user_data is passed to the \a rs_conn_packet_received_cb callback
+    registered with the connection. If no callback is registered with
     the connection, the event loop is run by \a rs_packet_send and it
-    blocks until the packet has been succesfully sent.
-
-    \return On success, RSE_OK (0) is returned.  On error, !0 is
+    blocks until the full packet has been sent. Note that sending can
+    fail in several ways, f.ex. if the transmission protocol in use
+    is connection oriented (\a RS_CONN_TYPE_TCP and \a RS_CONN_TYPE_TLS)
+    and the connection can not be established. Also note that no
+    retransmission is done, something that is required for connectionless
+    transport protocols (\a RS_CONN_TYPE_UDP and \a RS_CONN_TYPE_DTLS).
+    The "request" API with \a rs_request_send can help with this.
+
+    \return On success, RSE_OK (0) is returned. On error, !0 is
     returned and a struct \a rs_error is pushed on the error stack for
-    the connection.  The error can be accessed using \a
-    rs_err_conn_pop.  */
+    the connection. The error can be accessed using \a rs_err_conn_pop. */
 int rs_packet_send(struct rs_packet *pkt, void *user_data);
 
 /** Create a RADIUS authentication request packet associated with
@@ -319,7 +327,17 @@ int rs_packet_create_authn_request(struct rs_connection *conn,
                                   const char *user_name,
                                   const char *user_pw);
 
-/*** Append \a tail to packet \a pkt.  */
+/** Add a new attribute-value pair to \a pkt. */
+int rs_packet_add_avp(struct rs_packet *pkt,
+                      unsigned int attr, unsigned int vendor,
+                      const void *data, size_t data_len);
+
+/** Append a new attribute to packet \a pkt. Note that this function
+    encodes the attribute and therefore might require the secret
+    shared with the thought recipient to be set in pkt->rpkt. Note
+    also that this function marks \a pkt as already encoded and can
+    not be used on packets with non-encoded value-pairs already
+    added. */
 int
 rs_packet_append_avp(struct rs_packet *pkt,
                     unsigned int attribute, unsigned int vendor,
@@ -411,121 +429,170 @@ int rs_err_code(struct rs_error *err, int dofree_flag);
  */
 #define RS_MAX_STRING_LEN         254
 
+/** Free the AVP list \a vps */
 void
 rs_avp_free(rs_avp **vps);
 
+/** Return the length of AVP \a vp in bytes */
 size_t
 rs_avp_length(rs_const_avp *vp);
 
+/** Return the type of \a vp */
 rs_attr_type_t
 rs_avp_typeof(rs_const_avp *vp);
 
+/** Retrieve the attribute and vendor ID of \a vp */
 void
 rs_avp_attrid(rs_const_avp *vp, unsigned int *attr, unsigned int *vendor);
 
-
+/** Add \a vp to the list pointed to by \a head */
 void
-rs_avp_append(rs_avp **head, rs_avp *tail);
+rs_avp_append(rs_avp **head, rs_avp *vp);
 
+/** Find an AVP in \a vp that matches \a attr and \a vendor */
 rs_avp *
 rs_avp_find(rs_avp *vp, unsigned int attr, unsigned int vendor);
 
+/** Find an AVP in \a vp that matches \a attr and \a vendor */
 rs_const_avp *
 rs_avp_find_const(rs_const_avp *vp, unsigned int attr, unsigned int vendor);
 
+/** Alloc a new AVP for \a attr and \a vendor */
 rs_avp *
 rs_avp_alloc(unsigned int attr, unsigned int vendor);
 
+/** Duplicate existing AVP \a vp */
 rs_avp *
 rs_avp_dup(rs_const_avp *vp);
 
+/** Remove matching AVP from list \a vps */
 int
-rs_avp_delete(rs_avp **first, unsigned int attr, unsigned int vendor);
+rs_avp_delete(rs_avp **vps, unsigned int attr, unsigned int vendor);
 
+/** Return next AVP in list */
 rs_avp *
-rs_avp_next(rs_avp *avp);
+rs_avp_next(rs_avp *vp);
 
+/** Return next AVP in list */
 rs_const_avp *
 rs_avp_next_const(rs_const_avp *avp);
 
+/** Return string value of \a vp */
 const char *
 rs_avp_string_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to string \a str */
 int
 rs_avp_string_set(rs_avp *vp, const char *str);
 
+/** Return integer value of \a vp */
 uint32_t
 rs_avp_integer_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to integer \a val */
 int
 rs_avp_integer_set(rs_avp *vp, uint32_t val);
 
+/** Return IPv4 value of \a vp */
 uint32_t
 rs_avp_ipaddr_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to IPv4 address \a in */
 int
 rs_avp_ipaddr_set(rs_avp *vp, struct in_addr in);
 
+/** Return POSIX time value of \a vp */
 time_t
 rs_avp_date_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to POSIX time \a date */
 int
 rs_avp_date_set(rs_avp *vp, time_t date);
 
+/** Return constant pointer to octets in \a vp */
 const unsigned char *
 rs_avp_octets_value_const_ptr(rs_const_avp *vp);
 
+/** Return pointer to octets in \a vp */
 unsigned char *
 rs_avp_octets_value_ptr(rs_avp *vp);
 
+/** Retrieve octet pointer \a p and length \a len from \a vp */
 int
 rs_avp_octets_value_byref(rs_avp *vp,
                          unsigned char **p,
                          size_t *len);
 
+/** Copy octets from \a vp into \a buf and \a len */
 int
 rs_avp_octets_value(rs_const_avp *vp,
                    unsigned char *buf,
                    size_t *len);
 
+/**
+ * Copy octets possibly fragmented across multiple VPs
+ * into \a buf and \a len
+ */
 int
 rs_avp_fragmented_value(rs_const_avp *vps,
                        unsigned char *buf,
                        size_t *len);
 
+/** Copy \a len octets in \a buf to AVP \a vp */
 int
 rs_avp_octets_set(rs_avp *vp,
                  const unsigned char *buf,
                  size_t len);
 
+/** Return IFID value of \a vp */
 int
 rs_avp_ifid_value(rs_const_avp *vp, uint8_t val[8]);
 
 int
 rs_avp_ifid_set(rs_avp *vp, const uint8_t val[8]);
 
+/** Return byte value of \a vp */
 uint8_t
 rs_avp_byte_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to byte \a val */
 int
 rs_avp_byte_set(rs_avp *vp, uint8_t val);
 
+/** Return short value of \a vp */
 uint16_t
 rs_avp_short_value(rs_const_avp *vp);
 
+/** Set AVP \a vp to short integer \a val */
 int
 rs_avp_short_set(rs_avp *vp, uint16_t val);
 
+/** Display possibly \a canonical attribute name into \a buffer */
+int
+rs_attr_display_name (unsigned int attr,
+                      unsigned int vendor,
+                      char *buffer,
+                      size_t bufsize,
+                      int canonical);
+
+/** Display AVP \a vp into \a buffer */
 size_t
 rs_avp_display_value(rs_const_avp *vp,
                      char *buffer,
                      size_t buflen);
 
 int
+rs_attr_parse_name (const char *name,
+                   unsigned int *attr,
+                   unsigned int *vendor);
+
+/** Lookup attribute \a name */
+int
 rs_attr_find(const char *name,
              unsigned int *attr,
              unsigned int *vendor);
 
+/** Return dictionary name for AVP \a vp */
 const char *
 rs_avp_name(rs_const_avp *vp);