Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/sipsess/close.c b/src/sipsess/close.c
new file mode 100644
index 0000000..b680a9a
--- /dev/null
+++ b/src/sipsess/close.c
@@ -0,0 +1,74 @@
+/**
+ * @file close.c  SIP Session Close
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re_types.h>
+#include <re_mem.h>
+#include <re_mbuf.h>
+#include <re_sa.h>
+#include <re_list.h>
+#include <re_hash.h>
+#include <re_fmt.h>
+#include <re_uri.h>
+#include <re_tmr.h>
+#include <re_msg.h>
+#include <re_sip.h>
+#include <re_sipsess.h>
+#include "sipsess.h"
+
+
+static void bye_resp_handler(int err, const struct sip_msg *msg, void *arg)
+{
+	struct sipsess *sess = arg;
+
+	if (err || sip_request_loops(&sess->ls, msg->scode))
+		goto out;
+
+	if (msg->scode < 200) {
+		return;
+	}
+	else if (msg->scode < 300) {
+		;
+	}
+	else {
+		if (sess->peerterm)
+			goto out;
+
+		switch (msg->scode) {
+
+		case 401:
+		case 407:
+			err = sip_auth_authenticate(sess->auth, msg);
+			if (err)
+				break;
+
+			err = sipsess_bye(sess, false);
+			if (err)
+				break;
+
+			return;
+		}
+	}
+
+ out:
+	mem_deref(sess);
+}
+
+
+int sipsess_bye(struct sipsess *sess, bool reset_ls)
+{
+	if (sess->req)
+		return EPROTO;
+
+	if (reset_ls)
+		sip_loopstate_reset(&sess->ls);
+
+	return sip_drequestf(&sess->req, sess->sip, true, "BYE",
+			     sess->dlg, 0, sess->auth,
+			     NULL, bye_resp_handler, sess,
+			     "%s"
+			     "Content-Length: 0\r\n"
+			     "\r\n",
+			     sess->close_hdrs);
+}