5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include <silcruntime.h>
22 /************************** Types and definitions ***************************/
24 /* Local net listener context */
26 SilcNetListener listener;
28 SilcNetCallback callback;
30 } *SilcLocalNetListener;
32 /************************ Static utility functions **************************/
34 /* Connection accept callback */
36 static void silc_local_net_accept(SilcResult result, SilcStream stream,
39 SilcLocalNetListener listener = context;
40 const char *remote_ip;
42 if (!silc_socket_stream_get_info(stream, NULL, NULL, &remote_ip, NULL)) {
43 silc_stream_destroy(stream);
47 /* Make sure the connection comes from local host */
48 if (strcmp(remote_ip, "127.0.0.1")) {
49 SILC_LOG_DEBUG(("Connection is coming from %s, will not accept",
51 silc_stream_destroy(stream);
55 listener->callback(result, stream, listener->context);
58 /****************************** Public API **********************************/
62 SilcNetListener silc_local_net_create_listener(const char *filepath,
63 SilcLocalNetSecurity security,
64 SilcSchedule schedule,
65 SilcNetCallback callback,
68 SilcLocalNetListener listener;
69 SilcUInt16 *local_port;
70 const char *addr = "127.0.0.1";
74 SILC_LOG_DEBUG(("Creating local network stream listener %s", filepath));
76 if (!filepath || !callback) {
77 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
81 /* Make sure file doesn't exist */
82 if (silc_file_stat(filepath, FALSE, NULL)) {
83 silc_set_errno(SILC_ERR_ALREADY_EXISTS);
87 listener = silc_calloc(1, sizeof(*listener));
90 listener->callback = callback;
91 listener->context = context;
93 listener->filepath = silc_strdup(filepath);
94 if (!listener->filepath) {
99 /* Create local TCP listener */
101 silc_net_tcp_create_listener(&addr, 1, 0, TRUE, FALSE, schedule,
102 silc_local_net_accept, listener);
108 /* Get the bound port */
109 local_port = silc_net_listener_get_port(listener->listener, NULL);
111 silc_net_close_listener(listener->listener);
119 if (security & SILC_LOCAL_NET_USER)
121 if (security & SILC_LOCAL_NET_GROUP)
124 /* Create the file */
125 silc_snprintf(port, sizeof(port), "%d", *local_port);
126 if (silc_file_writefile_mode(filepath, port, strlen(port) + 1, mode)) {
127 silc_free(local_port);
128 silc_net_close_listener(listener->listener);
133 SILC_LOG_DEBUG(("Created local network stream listener %p", listener));
135 silc_free(local_port);
137 return (SilcNetListener)listener;
142 void silc_local_net_close_listener(SilcNetListener local_listener)
144 SilcLocalNetListener listener = (SilcLocalNetListener)local_listener;
146 SILC_LOG_DEBUG(("Closing local network stream listener %p, %s",
147 listener, listener->filepath));
149 unlink(listener->filepath);
150 silc_net_close_listener(listener->listener);
151 silc_free(listener->filepath);
155 /* Connect to the local network listener */
157 SilcAsyncOperation silc_local_net_connect(const char *filepath,
158 SilcSchedule schedule,
159 SilcNetCallback callback,
162 unsigned char *port_data;
165 SILC_LOG_DEBUG(("Connecting to local network listner %s", filepath));
168 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
170 callback(silc_errno, NULL, context);
174 /* Read the port from file */
175 port_data = silc_file_readfile(filepath, NULL, NULL);
178 callback(silc_errno, NULL, context);
181 port = atoi(port_data);
183 silc_free(port_data);
186 return silc_net_tcp_connect("127.0.0.1", "127.0.0.1", port, schedule,