2 /* -}{----------------------------------------------------------------------- */
7 /* -}{----------------------------------------------------------------------- */
9 extern int connection_writable(k_channel* chan, int bufpos, int len);
10 extern int connection_readable(k_channel* chan, int bufpos, int len);
12 /* -}{----------------------------------------------------------------------- */
14 #define TMPBUFSIZE 4096
15 static char tmpbuf[TMPBUFSIZE];
17 static char* nexus_channel;
18 static k_hashtable* chans_for_host;
20 /* -}{----------------------------------------------------------------------- */
22 static void nexus_file_read(char*, char*, char*, int, k_stat, void*);
23 static void write_nexus(char* hostname);
24 static void nexus_file_written(char*, char*, char*, int, k_stat, void*);
25 static int root_nexus(void);
26 static void listen_http(void);
27 static void listen_nexus(void);
28 static void connect_to_nexus(void);
29 static void ping_this(void* arg, char* key, void* val);
30 static char* generate_new_hostname(k_hashtable* ent_head, k_channel* chan);
31 static void set_channel_for(char* host, char* chanm);
32 static void show_np(void);
33 static void show_list(void* arg, char* key, void* val);
35 /* -}{----------------------------------------------------------------------- */
37 void init_uri2chan(void)
39 chans_for_host =k_hashtable_new("Channels for Host", 0);
41 k_file_read(".", "nexus.txt", USE_MALL, 0, nexus_file_read, 0);
43 is_np=!strcmp(k_ciux, "np");
44 if(is_np) listen_nexus();
46 k_log_out("root nexus - but listening on http");
50 k_log_out("connecting to nexus %s", nexus_channel);
55 char* get_host_for(char* uri)
57 if(0) k_log_out("get_host_for %s", uri);
59 if(0) k_log_out("host for %s=%s", uri, host);
63 char* get_channel_for(char* host)
65 if(0) k_log_out("get_channel_for %s", host);
66 char* chanm=k_hashtable_get(chans_for_host, host);
69 if(0) k_log_out("channel for %s=%s", host, chanm);
73 char* use_ping_info(k_hashtable* ent_head, k_channel* chan)
75 char* from=k_hashtable_get(ent_head, "From:");
76 char* to =k_hashtable_get(ent_head, "To:");
79 if(!strcmp(from, "-")) from=generate_new_hostname(ent_head, chan);
81 if(!ni_hostname() && to) write_nexus(to);
83 set_channel_for(from, chan->name);
85 if(0) k_log_out("%s PING %s", chan->name, from);
91 void use_from_info(k_hashtable* ent_head, k_channel* chan)
93 char* from=k_hashtable_get(ent_head, "From:");
97 set_channel_for(from, chan->name);
102 void ping_tunnels(void)
104 k_hashtable* channelspinged=k_hashtable_new("channelspinged", 0);
105 k_hashtable_apply(chans_for_host, ping_this, channelspinged);
106 k_hashtable_delete(channelspinged);
109 void send_ping(k_channel* chan, char* firstline, char* to)
111 char* from=ni_hostname();
115 int bufsize=TMPBUFSIZE;
117 ln+=snprintf(tmpbuf+ln, bufsize-ln, "%s" CRLF, firstline);
118 if(ln>=bufsize) return;
119 ln+=snprintf(tmpbuf+ln, bufsize-ln, "From: %s" CRLF, from);
120 if(ln>=bufsize) return;
122 ln+=snprintf(tmpbuf+ln, bufsize-ln, "To: %s" CRLF, to);
123 if(ln>=bufsize) return;
125 ln+=snprintf(tmpbuf+ln, bufsize-ln, "Server: %s" CRLF, k_version);
126 if(ln>=bufsize) return;
127 ln+=snprintf(tmpbuf+ln, bufsize-ln, "Channels: %s" CRLF, "-");
128 if(ln>=bufsize) return;
129 ln+=snprintf(tmpbuf+ln, bufsize-ln, CRLF);
130 if(ln>=bufsize) return;
132 char* head=k_strdup(tmpbuf);
133 k_channel_send(chan, head, ln, FREE_ON_SENT);
136 /* -}{----------------------------------------------------------------------- */
138 void nexus_file_read(char* basedir,
146 if(data) data[kstat.size-1]=0;
147 else data=k_strdup("");
148 k_hashtable* nex=k_hashtable_new("nexus", 1);
149 if(!ni_get_headers(data, nex, 0)){
150 k_log_err("Corrupt nexus.txt file");
151 k_hashtable_delete(nex);
154 nex=k_hashtable_new("nexus", 1);
155 ni_get_headers(data, nex, 0);
159 nexus_channel=k_hashtable_get_dup(nex, "Nexus-Channel:");
160 hostname =k_hashtable_get( nex, "Hostname:");
162 if(hostname) ni_hostname_set(hostname);
164 if(L) if(nexus_channel) k_log_out("Nexus-Channel: %s", nexus_channel);
165 if(L) if(hostname) k_log_out("Hostname: %s", hostname);
167 k_hashtable_delete(nex);
171 void write_nexus(char* hostname)
173 ni_hostname_set(hostname);
175 snprintf(tmpbuf, TMPBUFSIZE, "Nexus-Channel: %s\r\n"
176 "Hostname: %s\r\n", nexus_channel,
179 k_file_write(".", "nexus.txt", tmpbuf, strlen(tmpbuf),
180 nexus_file_written, 0);
183 void nexus_file_written(char* basedir,
190 if(!data) k_fatal("Failed to write nexus.txt");
191 else k_log_out("New nexus.txt written:\n%s", data);
196 char* hostname=ni_hostname();
197 if(!hostname || strchr(hostname, '-')) return 0;
201 void listen_http(void)
203 char* chanm="|nip-server|-|8081|-|";
204 k_channel_connect_name(chanm, connection_readable,
205 connection_writable);
208 void listen_nexus(void)
210 char* chanm="|nip-server|-|7747|-|";
211 k_channel_connect_name(chanm, connection_readable,
212 connection_writable);
215 void connect_to_nexus(void)
218 k_channel_connect_name(nexus_channel, connection_readable,
219 connection_writable);
221 else k_log_out("discovery of nexus not implemented yet!");
224 void ping_this(void* arg, char* key, void* val)
226 k_hashtable* channelspinged=arg;
229 if(strncmp(chanm, "nip-client", 11) ) return;
230 if(k_hashtable_get(channelspinged, chanm)) return;
231 k_hashtable_set(channelspinged, chanm, chanm);
233 k_channel* chan=k_channel_get_name(chanm);
234 //k_log_out("ping_this: host %s channel %s got=%p", key, chanm, chan);
236 if(!chan) k_channel_connect_name(chanm, connection_readable,
237 connection_writable);
240 if(chan && pingtodeath) send_ping(chan, "PING ni/0.5", 0);
243 char* generate_new_hostname(k_hashtable* ent_head, k_channel* chan)
245 if(!ni_hostname()) return 0;
246 unsigned long a=chan->clientip.s_addr;
248 ((unsigned char *)&a)[0], \
249 ((unsigned char *)&a)[1], \
250 ((unsigned char *)&a)[2], \
251 ((unsigned char *)&a)[3]
252 snprintf(tmpbuf, TMPBUFSIZE, "%s-%02x%02x%02x%02x.%d",
253 ni_hostname(), IPQUAD(a), 7747);
254 if(0) k_log_out("generated new hostname: %s\n", tmpbuf);
255 return k_strdup(tmpbuf);
258 /* -}{----------------------------------------------------------------------- */
260 void set_channel_for(char* host, char* chanm)
262 k_hashtable_put_dup(chans_for_host, host, chanm);
267 k_log_out("-------- channel for host ---------------");
268 k_hashtable_apply(chans_for_host, show_list, 0);
269 k_channel_show_all();
272 void show_list(void* arg, char* key, void* val)
275 k_log_out("%s %s", key, chanm);
278 void generate_random(void)
282 k_random_bytes((char*)&r, sizeof(r));
283 unsigned char r1=(t >>24) & 255;
284 unsigned char r2=(t >>16) & 255;
285 unsigned char r3=(t >> 8) & 255;
286 unsigned char r4=(t ) & 255;
287 unsigned char r5=(r >> 8) & 255;
288 unsigned char r6=(r ) & 255;
289 snprintf(tmpbuf, TMPBUFSIZE, "%02x-%02x-%02x-%02x-%02x-%02x",
290 r1, r2, r3, r4, r5, r6);
293 /* -}{----------------------------------------------------------------------- */