+ } else {
+ close_listener(listener);
+ }
+}
+
+/*
+ * add_sctp_listener- create a new listener
+ * port - the port number to listen on
+ * vhost_ip1/2 - if non-null must contain a valid IP address string
+ */
+void
+add_sctp_listener(int port, const char *vhost_ip1, const char *vhost_ip2, int ssl, int wsock)
+{
+ struct Listener *listener;
+ struct rb_sockaddr_storage vaddr[ARRAY_SIZE(listener->addr)];
+
+ /*
+ * if no port in conf line, don't bother
+ */
+ if (port == 0)
+ return;
+ memset(&vaddr, 0, sizeof(vaddr));
+
+ if (vhost_ip1 != NULL) {
+ if (rb_inet_pton_sock(vhost_ip1, &vaddr[0]) <= 0)
+ return;
+
+ if (vhost_ip2 != NULL) {
+ if (rb_inet_pton_sock(vhost_ip2, &vaddr[1]) <= 0)
+ return;
+ } else {
+ SET_SS_FAMILY(&vaddr[1], AF_UNSPEC);
+ SET_SS_LEN(&vaddr[1], sizeof(struct sockaddr_storage));
+ }
+
+ if (GET_SS_FAMILY(&vaddr[0]) == AF_INET && GET_SS_FAMILY(&vaddr[1]) == AF_INET6) {
+ /* always put INET6 first */
+ struct rb_sockaddr_storage tmp;
+ tmp = vaddr[0];
+ vaddr[0] = vaddr[1];
+ vaddr[1] = tmp;
+ }
+ } else {
+ memcpy(&((struct sockaddr_in6 *)&vaddr[0])->sin6_addr, &in6addr_any, sizeof(struct in6_addr));
+ SET_SS_FAMILY(&vaddr[0], AF_INET6);
+ SET_SS_LEN(&vaddr[0], sizeof(struct sockaddr_in6));
+
+ SET_SS_FAMILY(&vaddr[1], AF_UNSPEC);
+ SET_SS_LEN(&vaddr[1], sizeof(struct sockaddr_storage));
+ }
+
+ SET_SS_PORT(&vaddr[0], htons(port));
+ SET_SS_PORT(&vaddr[1], htons(port));
+
+ if ((listener = find_listener(vaddr, 1))) {
+ if(listener->F != NULL)
+ return;
+ } else {
+ listener = make_listener(vaddr);
+ listener->next = ListenerPollList;
+ ListenerPollList = listener;
+ }
+
+ listener->F = NULL;
+ listener->ssl = ssl;
+ listener->defer_accept = 0;
+ listener->sctp = 1;
+ listener->wsock = wsock;
+
+ if (inetport(listener)) {
+ listener->active = 1;
+ } else {