+ int i, sock, rval;
+ const char *ipany = "0.0.0.0";
+
+ SILC_LOG_DEBUG(("Creating TCP listener"));
+
+ if (port < 0 || !schedule || !callback)
+ goto err;
+
+ listener = silc_calloc(1, sizeof(*listener));
+ if (!listener)
+ return NULL;
+ listener->schedule = schedule;
+ listener->callback = callback;
+ listener->context = context;
+ listener->require_fqdn = require_fqdn;
+ listener->lookup = lookup;
+
+ if (local_ip_count > 0) {
+ listener->socks = silc_calloc(local_ip_count, sizeof(*listener->socks));
+ if (!listener->socks)
+ return NULL;
+ } else {
+ listener->socks = silc_calloc(1, sizeof(*listener->socks));
+ if (!listener->socks)
+ return NULL;
+
+ local_ip_count = 1;
+ }
+
+ /* Bind to local addresses */
+ for (i = 0; i < local_ip_count; i++) {
+ SILC_LOG_DEBUG(("Binding to local address %s:%d",
+ local_ip_addr ? local_ip_addr[i] : ipany, port));
+
+ /* Set sockaddr for server */
+ if (!silc_net_set_sockaddr(&server,
+ local_ip_addr ? local_ip_addr[i] : ipany,
+ port))
+ goto err;
+
+ /* Create the socket */
+ sock = socket(server.sin.sin_family, SOCK_STREAM, 0);
+ if (sock < 0) {
+ SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
+ goto err;
+ }
+
+ /* Set the socket options */
+ rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
+ close(sock);
+ goto err;
+ }
+
+ /* Bind the listener socket */
+ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server));
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno)));
+ close(sock);
+ goto err;
+ }
+
+ /* Specify that we are listenning */
+ rval = listen(sock, 64);
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno)));
+ close(sock);
+ goto err;
+ }
+
+ /* Set the server socket to non-blocking mode */
+ silc_net_set_socket_nonblock(sock);