Squashed 'third_party/rawrtc/rew/' content from commit 24c91fd83

Change-Id: Ica2fcc790472ecd5b195d20da982c4e84139cbdd
git-subtree-dir: third_party/rawrtc/rew
git-subtree-split: 24c91fd839b40b11f727c902fa46d20874da33fb
diff --git a/include/re_pcp.h b/include/re_pcp.h
new file mode 100644
index 0000000..a98d5d4
--- /dev/null
+++ b/include/re_pcp.h
@@ -0,0 +1,200 @@
+/**
+ * @file re_pcp.h  PCP - Port Control Protocol (RFC 6887)
+ *
+ * Copyright (C) 2010 - 2014 Creytiv.com
+ */
+
+
+/*
+ * The following specifications are implemented:
+ *
+ *   RFC 6887
+ *   draft-ietf-pcp-description-option-02
+ *   draft-cheshire-pcp-unsupp-family
+ *
+ */
+
+
+/** PCP Version numbers */
+enum {
+	PCP_VERSION = 2,
+};
+
+/* PCP port numbers */
+enum {
+	PCP_PORT_CLI   = 5350,  /* for ANNOUNCE notifications */
+	PCP_PORT_SRV   = 5351,
+};
+
+/** PCP Protocol sizes */
+enum {
+	PCP_HDR_SZ   = 24,
+	PCP_NONCE_SZ = 12,
+	PCP_MAP_SZ   = 36,
+	PCP_PEER_SZ  = 56,
+
+	PCP_MIN_PACKET =   24,
+	PCP_MAX_PACKET = 1100
+};
+
+enum pcp_opcode {
+	PCP_ANNOUNCE = 0,
+	PCP_MAP      = 1,
+	PCP_PEER     = 2,
+};
+
+enum pcp_result {
+	PCP_SUCCESS                 =  0,
+	PCP_UNSUPP_VERSION          =  1,
+	PCP_NOT_AUTHORIZED          =  2,
+	PCP_MALFORMED_REQUEST       =  3,
+	PCP_UNSUPP_OPCODE           =  4,
+	PCP_UNSUPP_OPTION           =  5,
+	PCP_MALFORMED_OPTION        =  6,
+	PCP_NETWORK_FAILURE         =  7,
+	PCP_NO_RESOURCES            =  8,
+	PCP_UNSUPP_PROTOCOL         =  9,
+	PCP_USER_EX_QUOTA           = 10,
+	PCP_CANNOT_PROVIDE_EXTERNAL = 11,
+	PCP_ADDRESS_MISMATCH        = 12,
+	PCP_EXCESSIVE_REMOTE_PEERS  = 13,
+	PCP_UNSUPP_FAMILY           = 14  /*draft-cheshire-pcp-unsupp-family*/
+};
+
+enum pcp_option_code {
+	PCP_OPTION_THIRD_PARTY    =   1,
+	PCP_OPTION_PREFER_FAILURE =   2,
+	PCP_OPTION_FILTER         =   3,
+	PCP_OPTION_DESCRIPTION    = 128,  /* RFC 7220 */
+};
+
+/* forward declarations */
+struct udp_sock;
+
+/** Defines a PCP option */
+struct pcp_option {
+	struct le le;
+	enum pcp_option_code code;
+	union {
+		struct sa third_party;          /* Internal IP-address */
+		struct pcp_option_filter {
+			uint8_t prefix_length;
+			struct sa remote_peer;
+		} filter;
+		char *description;
+	} u;
+};
+
+/**
+ * Defines a complete and decoded PCP request/response.
+ *
+ * A PCP message consist of a header, and optional payload and options:
+ *
+ *     [      Header    ]
+ *     ( Opcode Payload )
+ *     (   PCP Options  )
+ *
+ */
+struct pcp_msg {
+
+	/** PCP Common Header */
+	struct pcp_hdr {
+		uint8_t version;        /**< PCP Protocol version 2        */
+		unsigned resp:1;        /**< R-bit; 0=Request, 1=Response  */
+		uint8_t opcode;         /**< A 7-bit opcode                */
+		uint32_t lifetime;      /**< Lifetime in [seconds]         */
+
+		/* request: */
+		struct sa cli_addr;     /**< Client's IP Address (SA_ADDR) */
+
+		/* response: */
+		enum pcp_result result; /**< Result code for this response */
+		uint32_t epoch;         /**< Server's Epoch Time [seconds] */
+	} hdr;
+
+	/** PCP Opcode-specific payload */
+	union pcp_payload {
+		struct pcp_map {
+			uint8_t nonce[PCP_NONCE_SZ]; /**< Mapping Nonce    */
+			uint8_t proto;               /**< IANA protocol    */
+			uint16_t int_port;           /**< Internal Port    */
+			struct sa ext_addr;          /**< External Address */
+		} map;
+		struct pcp_peer {
+			struct pcp_map map;          /**< Common with MAP  */
+			struct sa remote_addr;       /**< Remote address   */
+		} peer;
+	} pld;
+
+	/** List of PCP Options (struct pcp_option) */
+	struct list optionl;
+};
+
+/** PCP request configuration */
+struct pcp_conf {
+	uint32_t irt;  /**< Initial retransmission time [seconds]     */
+	uint32_t mrc;  /**< Maximum retransmission count              */
+	uint32_t mrt;  /**< Maximum retransmission time [seconds]     */
+	uint32_t mrd;  /**< Maximum retransmission duration [seconds] */
+};
+
+
+/* request */
+
+struct pcp_request;
+
+typedef void (pcp_resp_h)(int err, struct pcp_msg *msg, void *arg);
+
+int pcp_request(struct pcp_request **reqp, const struct pcp_conf *conf,
+		const struct sa *pcp_server, enum pcp_opcode opcode,
+		uint32_t lifetime, const void *payload,
+		pcp_resp_h *resph, void *arg, uint32_t optionc, ...);
+void pcp_force_refresh(struct pcp_request *req);
+
+
+/* reply */
+
+int pcp_reply(struct udp_sock *us, const struct sa *dst, struct mbuf *req,
+	      enum pcp_opcode opcode, enum pcp_result result,
+	      uint32_t lifetime, uint32_t epoch_time, const void *payload);
+
+
+/* msg */
+
+typedef bool (pcp_option_h)(const struct pcp_option *opt, void *arg);
+
+int pcp_msg_decode(struct pcp_msg **msgp, struct mbuf *mb);
+int pcp_msg_printhdr(struct re_printf *pf, const struct pcp_msg *msg);
+int pcp_msg_print(struct re_printf *pf, const struct pcp_msg *msg);
+struct pcp_option *pcp_msg_option(const struct pcp_msg *msg,
+				  enum pcp_option_code code);
+struct pcp_option *pcp_msg_option_apply(const struct pcp_msg *msg,
+					pcp_option_h *h, void *arg);
+const void *pcp_msg_payload(const struct pcp_msg *msg);
+
+
+/* option */
+
+int pcp_option_encode(struct mbuf *mb, enum pcp_option_code code,
+		      const void *v);
+int pcp_option_decode(struct pcp_option **optp, struct mbuf *mb);
+int pcp_option_print(struct re_printf *pf, const struct pcp_option *opt);
+
+
+/* encode */
+
+int pcp_msg_req_vencode(struct mbuf *mb, enum pcp_opcode opcode,
+			uint32_t lifetime, const struct sa *cli_addr,
+			const void *payload, uint32_t optionc, va_list ap);
+int pcp_msg_req_encode(struct mbuf *mb, enum pcp_opcode opcode,
+		       uint32_t lifetime, const struct sa *cli_addr,
+		       const void *payload, uint32_t optionc, ...);
+
+
+/* pcp */
+
+int pcp_ipaddr_encode(struct mbuf *mb, const struct sa *sa);
+int pcp_ipaddr_decode(struct mbuf *mb, struct sa *sa);
+const char *pcp_result_name(enum pcp_result result);
+const char *pcp_opcode_name(enum pcp_opcode opcode);
+const char *pcp_proto_name(int proto);
diff --git a/include/re_shim.h b/include/re_shim.h
new file mode 100644
index 0000000..f5966a6
--- /dev/null
+++ b/include/re_shim.h
@@ -0,0 +1,15 @@
+
+
+/* RFC 4571 */
+
+
+enum { SHIM_HDR_SIZE = 2 };
+
+struct shim;
+
+typedef bool (shim_frame_h)(struct mbuf *mb, void *arg);
+
+
+int shim_insert(struct shim **shimp, struct tcp_conn *tc, int layer,
+		shim_frame_h *frameh, void *arg);
+int shim_debug(struct re_printf *pf, const struct shim *shim);
diff --git a/include/re_trice.h b/include/re_trice.h
new file mode 100644
index 0000000..9eba6c7
--- /dev/null
+++ b/include/re_trice.h
@@ -0,0 +1,167 @@
+/**
+ * @file re_ice.h  Interface to Interactive Connectivity Establishment (ICE)
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+
+
+/** ICE Configuration */
+struct trice_conf {
+	enum ice_nomination nom;       /**< Nomination algorithm             */
+	bool debug;                    /**< Enable ICE debugging             */
+	bool trace;                    /**< Enable tracing of Connectivity
+					    checks                           */
+	bool ansi;                     /**< Enable ANSI colors for debug
+					   output                            */
+	bool enable_prflx;             /**< Enable Peer-Reflexive candidates */
+	bool optimize_loopback_pairing;/**< Reduce candidate pairs when
+					    using loopback addresses         */
+};
+
+struct trice;
+struct ice_lcand;
+struct ice_candpair;
+struct stun_conf;
+
+
+typedef bool (ice_cand_recv_h)(struct ice_lcand *lcand,
+			       int proto, void *sock, const struct sa *src,
+			       struct mbuf *mb, void *arg);
+
+
+/** Local candidate */
+struct ice_lcand {
+	struct ice_cand_attr attr;   /**< Base class (inheritance)           */
+	struct le le;                /**< List element                       */
+
+	/* Base-address only set for SRFLX, PRFLX, RELAY */
+	struct sa base_addr;    /* IP-address of "base" candidate (optional) */
+
+	struct udp_sock *us;
+	struct udp_helper *uh;
+	struct tcp_sock *ts;    /* TCP for simultaneous-open or passive. */
+	char ifname[32];        /**< Network interface, for diagnostics */
+	int layer;
+	ice_cand_recv_h *recvh;
+	void *arg;
+
+	// todo: remove
+	struct trice *icem;           /* parent */
+
+	struct {
+		size_t n_tx;
+		size_t n_rx;
+	} stats;
+};
+
+/** Remote candidate */
+struct ice_rcand {
+	struct ice_cand_attr attr;   /**< Base class (inheritance)           */
+	struct le le;                /**< List element                       */
+};
+
+
+/** Defines a candidate pair */
+struct ice_candpair {
+	struct le le;                /**< List element                       */
+	struct ice_lcand *lcand;     /**< Local candidate                    */
+	struct ice_rcand *rcand;     /**< Remote candidate                   */
+	enum ice_candpair_state state;/**< Candidate pair state              */
+	uint64_t pprio;              /**< Pair priority                      */
+      //bool def;                    /**< Default flag                       */
+	bool valid;                  /**< Valid flag                         */
+	bool nominated;              /**< Nominated flag                     */
+	bool estab;
+	bool trigged;
+	int err;                     /**< Saved error code, if failed        */
+	uint16_t scode;              /**< Saved STUN code, if failed         */
+
+	struct tcp_conn *tc;
+
+	struct ice_tcpconn *conn;    /* the TCP-connection used */
+};
+
+
+typedef void (trice_estab_h)(struct ice_candpair *pair,
+			     const struct stun_msg *msg, void *arg);
+
+
+typedef void (trice_failed_h)(int err, uint16_t scode,
+			    struct ice_candpair *pair, void *arg);
+
+
+int  trice_alloc(struct trice **icemp, const struct trice_conf *conf,
+		 enum ice_role role, const char *lufrag, const char *lpwd);
+int  trice_set_remote_ufrag(struct trice *icem, const char *rufrag);
+int  trice_set_remote_pwd(struct trice *icem, const char *rpwd);
+int  trice_set_software(struct trice *icem, const char *sw);
+int  trice_set_role(struct trice *trice, enum ice_role role);
+enum ice_role trice_local_role(const struct trice *icem);
+int  trice_debug(struct re_printf *pf, const struct trice *icem);
+struct trice_conf *trice_conf(struct trice *icem);
+
+
+/* Candidates (common) */
+int  trice_cand_print(struct re_printf *pf, const struct ice_cand_attr *cand);
+enum ice_tcptype   ice_tcptype_reverse(enum ice_tcptype type);
+const char        *ice_tcptype_name(enum ice_tcptype tcptype);
+enum ice_cand_type ice_cand_type_base(enum ice_cand_type type);
+
+
+/* Local candidates */
+int trice_lcand_add(struct ice_lcand **lcandp, struct trice *icem,
+		    unsigned compid, int proto, uint32_t prio,
+		    const struct sa *addr, const struct sa *base_addr,
+		    enum ice_cand_type type, const struct sa *rel_addr,
+		    enum ice_tcptype tcptype,
+		    void *sock, int layer);
+struct list      *trice_lcandl(const struct trice *icem);
+struct ice_lcand *trice_lcand_find(struct trice *icem,
+				   enum ice_cand_type type,
+				   unsigned compid, int proto,
+				   const struct sa *addr);
+struct ice_lcand *trice_lcand_find2(const struct trice *icem,
+				    enum ice_cand_type type, int af);
+void *trice_lcand_sock(struct trice *icem, const struct ice_lcand *lcand);
+void trice_lcand_recv_packet(struct ice_lcand *lcand,
+			     const struct sa *src, struct mbuf *mb);
+
+
+/* Remote candidate */
+struct list *trice_rcandl(const struct trice *icem);
+int trice_rcand_add(struct ice_rcand **rcandp, struct trice *icem,
+		    unsigned compid, const char *foundation, int proto,
+		    uint32_t prio, const struct sa *addr,
+		    enum ice_cand_type type, enum ice_tcptype tcptype);
+struct ice_rcand *trice_rcand_find(struct trice *icem, unsigned compid,
+				   int proto, const struct sa *addr);
+
+
+/* ICE Candidate pairs */
+struct list *trice_checkl(const struct trice *icem);
+struct list *trice_validl(const struct trice *icem);
+struct ice_candpair *trice_candpair_find_state(const struct list *lst,
+					   enum ice_candpair_state state);
+int  trice_candpair_debug(struct re_printf *pf, const struct ice_candpair *cp);
+int  trice_candpairs_debug(struct re_printf *pf, bool ansi_output,
+			   const struct list *list);
+
+
+/* ICE checklist */
+void trice_checklist_set_waiting(struct trice *icem);
+int  trice_checklist_start(struct trice *icem, struct stun *stun,
+			   uint32_t interval,
+			   trice_estab_h *estabh, trice_failed_h *failh,
+			   void *arg);
+void trice_checklist_stop(struct trice *icem);
+bool trice_checklist_isrunning(const struct trice *icem);
+bool trice_checklist_iscompleted(const struct trice *icem);
+
+
+/* ICE Conncheck */
+int trice_conncheck_send(struct trice *icem, struct ice_candpair *pair,
+			bool use_cand);
+
+/* Port range */
+int trice_set_port_range(struct trice *trice,
+			 uint16_t min_port, uint16_t max_port);
diff --git a/include/rew.h b/include/rew.h
new file mode 100644
index 0000000..afeeb68
--- /dev/null
+++ b/include/rew.h
@@ -0,0 +1,24 @@
+/**
+ * @file rew.h  Wrapper for librew headers
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+
+#ifndef REW_H__
+#define REW_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "re_pcp.h"
+#include "re_shim.h"
+#include "re_trice.h"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif