DEFINE_APITEST(peeloff, goodcase) { int lfd, cfd, pfd; struct sockaddr_in addr; socklen_t addr_len; sctp_assoc_t assoc_id; if ((lfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) { RETURN_FAILED_WITH_ERRNO; } if (sctp_bind(lfd, INADDR_LOOPBACK, 0) < 0) { close(lfd); RETURN_FAILED_WITH_ERRNO; } if (listen(lfd, 1) < 0) { close(lfd); RETURN_FAILED_WITH_ERRNO; } if ((cfd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { close(lfd); RETURN_FAILED_WITH_ERRNO; } if (sctp_bind(cfd, INADDR_LOOPBACK, 0) < 0) { close(lfd); close(cfd); RETURN_FAILED_WITH_ERRNO; } addr_len = (socklen_t)sizeof(struct sockaddr_in); if (getsockname (lfd, (struct sockaddr *) &addr, &addr_len) < 0) { close(lfd); close(cfd); RETURN_FAILED_WITH_ERRNO; } if (sctp_connectx(cfd, (struct sockaddr *) &addr, 1, &assoc_id) < 0) { close(lfd); close(cfd); RETURN_FAILED_WITH_ERRNO; } sctp_delay(SCTP_SLEEP_MS); if ((pfd = sctp_peeloff(cfd, assoc_id)) < 0) { close(lfd); close(cfd); RETURN_FAILED_WITH_ERRNO; } if (close(pfd) < 0) { close(cfd); close(lfd); RETURN_FAILED_WITH_ERRNO; } if (close(cfd) < 0) { close(lfd); RETURN_FAILED_WITH_ERRNO; } if (close(lfd) < 0) { RETURN_FAILED_WITH_ERRNO; } RETURN_PASSED; }
int main(int argc, char **argv) { int sock_fd,msg_flags,connfd,childpid; sctp_assoc_t assoc; char readbuf[BUFFSIZE]; struct sockaddr_in servaddr, cliaddr; struct sctp_sndrcvinfo sri; struct sctp_event_subscribe evnts; socklen_t len; size_t rd_sz; sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); bzero(&evnts, sizeof(evnts)); evnts.sctp_data_io_event = 1; Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)); Listen(sock_fd, LISTENQ); printf("Start waiting...\n"); /* include mod_servfork */ for ( ; ; ) { len = sizeof(struct sockaddr_in); rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), (SA *)&cliaddr, &len, &sri,&msg_flags); Sctp_sendmsg(sock_fd, readbuf, rd_sz, (SA *)&cliaddr, len, sri.sinfo_ppid, sri.sinfo_flags, sri.sinfo_stream, 0, 0); assoc = sctp_address_to_associd(sock_fd,(SA *)&cliaddr,len); if((int)assoc == 0){ err_ret("Can't get association id"); continue; } connfd = sctp_peeloff(sock_fd,assoc); if(connfd == -1){ err_ret("sctp_peeloff fails"); continue; } if((childpid = fork()) == 0) { Close(sock_fd); str_echo(connfd); exit(0); } else { Close(connfd); } } /* end mod_servfork */ }
int SctpSocket::PeelOff(sctp_assoc_t id) { int n = sctp_peeloff(GetSocket(), id); if (n == -1) { Handler().LogError(this, "SctpSocket", -1, "PeelOff failed", LOG_LEVEL_WARNING); return -1; } Socket *p = Create(); p -> Attach(n); p -> SetDeleteByHandler(); Handler().Add(p); return n; }
static PyObject* peeloff(PyObject* dummy, PyObject* args) { PyObject* ret = 0; int v1, v2, fd; if (PyArg_ParseTuple(args, "ii", &v1, &v2)) { fd = sctp_peeloff(v1, v2); if (fd < 0) { PyErr_SetFromErrno(PyExc_IOError); } else { ret = PyInt_FromLong(fd); } } return ret; }