X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsymbian%2Fsilcsymbiannet.cpp;h=2c2fea50c374866a65086f3cf8db81fb1e0a27fd;hb=42cc827e60ddf50ea201e8984f8dd0e57372170e;hp=69fba82e299a9a13f08b621e4e30448c7f96d27e;hpb=29413acb036e3480df4ad604ff7424f3fc9d3961;p=silc.git diff --git a/lib/silcutil/symbian/silcsymbiannet.cpp b/lib/silcutil/symbian/silcsymbiannet.cpp index 69fba82e..2c2fea50 100644 --- a/lib/silcutil/symbian/silcsymbiannet.cpp +++ b/lib/silcutil/symbian/silcsymbiannet.cpp @@ -283,6 +283,153 @@ silc_net_tcp_create_listener(const char **local_ip_addr, return NULL; } +/* Create TCP listener, multiple ports */ + +SilcNetListener +silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, + SilcUInt32 port_count, + SilcBool ignore_port_error, + SilcBool lookup, SilcBool require_fqdn, + SilcSchedule schedule, + SilcNetCallback callback, void *context) +{ + SilcNetListener listener = NULL; + SilcSymbianTCPListener *l = NULL; + TInetAddr server; + TInt ret; + int i; + + SILC_LOG_DEBUG(("Creating TCP listener")); + + if (!schedule || !callback) + goto err; + + listener = (SilcNetListener)silc_calloc(1, sizeof(*listener)); + if (!listener) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + listener->schedule = schedule; + listener->callback = callback; + listener->context = context; + listener->require_fqdn = require_fqdn; + listener->lookup = lookup; + + if (port_count > 0) { + listener->socks = (SilcSocket *)silc_calloc(port_count, + sizeof(*listener->socks)); + if (!listener->socks) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + } else { + listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks)); + if (!listener->socks) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + + port_count = 1; + } + + /* Bind to ports */ + for (i = 0; i < port_count; i++) { + SILC_LOG_DEBUG(("Binding to local address %s:%d", + local_ip_addr ? local_ip_addr : "0.0.0.0", + ports ? ports[i] : 0)); + + l = new SilcSymbianTCPListener; + if (!l) + goto err; + + /* Connect to socket server */ + ret = l->ss.Connect(); + if (ret != KErrNone) + goto err; + +#ifdef SILC_THREADS + /* Make our socket shareable between threads */ + l->ss.ShareAuto(); +#endif /* SILC_THREADS */ + + /* Set listener address */ + if (!silc_net_set_sockaddr(&server, local_ip_addr, ports ? ports[i] : 0)) { + if (ignore_port_error) { + delete l; + continue; + } + goto err; + } + + /* Create the socket */ + ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp); + if (ret != KErrNone) { + if (ignore_port_error) { + delete l; + continue; + } + SILC_LOG_ERROR(("Cannot create socket, error %d", ret)); + goto err; + } + + /* Set the socket options */ + ret = l->sock.SetOpt(KSoReuseAddr, KSolInetIp, 1); + if (ret != KErrNone) { + if (ignore_port_error) { + delete l; + continue; + } + SILC_LOG_ERROR(("Cannot set socket options, error %d", ret)); + goto err; + } + + /* Bind the listener socket */ + ret = l->sock.Bind(server); + if (ret != KErrNone) { + if (ignore_port_error) { + delete l; + continue; + } + SILC_LOG_DEBUG(("Cannot bind socket, error %d", ret)); + goto err; + } + + /* Specify that we are listenning */ + ret = l->sock.Listen(5); + if (ret != KErrNone) { + if (ignore_port_error) { + delete l; + continue; + } + SILC_LOG_ERROR(("Cannot set socket listenning, error %d", ret)); + goto err; + } + l->Listen(); + + l->listener = listener; + listener->socks[i] = (SilcSocket)l; + listener->socks_count++; + } + + if (ignore_port_error && !listener->socks_count) { + l = NULL; + goto err; + } + + SILC_LOG_DEBUG(("TCP listener created")); + + return listener; + + err: + if (l) + delete l; + if (callback) + callback(SILC_NET_ERROR, NULL, context); + if (listener) + silc_net_close_listener(listener); + return NULL; +} + /* Close network listener */ void silc_net_close_listener(SilcNetListener listener)