summaryrefslogtreecommitdiff
path: root/user_socket.c
diff options
context:
space:
mode:
authort00fcxen <t00fcxen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2012-11-25 14:36:23 +0000
committert00fcxen <t00fcxen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2012-11-25 14:36:23 +0000
commit56c7d1c81c55fda0619d96eac39e093789bca063 (patch)
treee87cc16c42d376f6208b2653142e8f00d1a0256c /user_socket.c
parent1252c73fc5c1fd7e181b8b11081cc442dec13858 (diff)
downloadusrsctplib-56c7d1c81c55fda0619d96eac39e093789bca063.tar.gz
Add a routing for dumping packets and initially support peeloff().
Needs testing. git-svn-id: http://sctp-refimpl.googlecode.com/svn/trunk/KERN/usrsctp/usrsctplib@8353 9df1edf5-d72c-5b5f-11c0-5f5209eb73f7
Diffstat (limited to 'user_socket.c')
-rwxr-xr-xuser_socket.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/user_socket.c b/user_socket.c
index 6a4f156..4598990 100755
--- a/user_socket.c
+++ b/user_socket.c
@@ -38,6 +38,7 @@
#include <netinet/sctp_var.h>
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_input.h>
+#include <netinet/sctp_peeloff.h>
#ifdef INET6
#include <netinet6/sctp6_var.h>
#endif
@@ -1927,6 +1928,35 @@ userspace_accept(struct socket *so, struct sockaddr *aname, socklen_t *anamelen)
return (usrsctp_accept(so, aname, anamelen));
}
+struct socket *
+usrsctp_peeloff(struct socket *head, sctp_assoc_t id)
+{
+ struct socket *so;
+
+ if ((errno = sctp_can_peel_off(head, id)) != 0) {
+ return (NULL);
+ }
+ if ((so = sonewconn(head, SS_ISCONNECTED)) == NULL) {
+ return (NULL);
+ }
+ ACCEPT_LOCK();
+ SOCK_LOCK(so);
+ soref(so);
+ TAILQ_REMOVE(&head->so_comp, so, so_list);
+ head->so_qlen--;
+ so->so_state |= (head->so_state & SS_NBIO);
+ so->so_qstate &= ~SQ_COMP;
+ so->so_head = NULL;
+ SOCK_UNLOCK(so);
+ ACCEPT_UNLOCK();
+ if ((errno = sctp_do_peeloff(head, so, id)) != 0) {
+ so->so_count = 0;
+ sodealloc(so);
+ return (NULL);
+ }
+ return (so);
+}
+
int
sodisconnect(struct socket *so)
{
@@ -3010,15 +3040,16 @@ free_mbuf:
#define HEADER "\n0000 "
#define TRAILER "# SCTP_PACKET\n"
-void
+char *
usrsctp_dumppacket(unsigned char *packet, size_t len)
{
size_t i, pos;
char *buf;
if ((buf = malloc(strlen(HEADER) + 3 * len + strlen(TRAILER) + 1)) == NULL) {
- return;
+ return (NULL);
}
+ /* XXX: Add timestamp header */
pos = 0;
stpcpy(buf + pos, HEADER);
pos += strlen(HEADER);
@@ -3035,9 +3066,12 @@ usrsctp_dumppacket(unsigned char *packet, size_t len)
stpcpy(buf + pos, TRAILER);
pos += strlen(TRAILER);
buf[pos++] = '\0';
- fflush(stdout);
- printf("%s", buf);
- fflush(stdout);
+ return (buf);
+}
+
+void
+usrsctp_freedumpbuffer(char *buf)
+{
free(buf);
}
#endif
@@ -3049,9 +3083,12 @@ usrsctp_conninput(void *addr, const void *buffer, size_t length, uint8_t ecn_bit
struct mbuf *m;
struct sctphdr *sh;
struct sctp_chunkhdr *ch;
-
#if 0
- usrsctp_dumppacket((unsigned char *)buffer, length);
+ char *buf;
+
+ buf = usrsctp_dumppacket((unsigned char *)buffer, length);
+ printf("%s", buf);
+ usrsctp_freedumpbuffer(buf);
#endif
memset(&src, 0, sizeof(struct sockaddr_conn));
src.sconn_family = AF_CONN;