mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
700 lines
20 KiB
C
700 lines
20 KiB
C
// vim:foldmethod=marker:syntax=lpc:noexpandtab
|
|
|
|
// this whole file is a mistake... and not in use...
|
|
|
|
#ifdef FORK // {{{
|
|
|
|
#include <net.h>
|
|
#include <url.h>
|
|
#include <services.h>
|
|
|
|
inherit NET_PATH "state";
|
|
inherit NET_PATH "queue2";
|
|
|
|
#include "../psyc/edit.i"
|
|
|
|
string psycName() { return ""; }
|
|
|
|
varargs mixed find_psyc_object(string t, object connection, array(mixed) u) {
|
|
string r, svc, user;
|
|
object o;
|
|
|
|
PT((">> t: %O\n", t))
|
|
|
|
unless (strlen(t) && u = (u || parse_uniform(t))) return 0;
|
|
|
|
//unless (u[UScheme] && u[UScheme] == "psyc") {
|
|
unless (u[UScheme] && strlen(u[UScheme])) {
|
|
if (connection)
|
|
connection -> w("_failure_unsupported_target_relative",
|
|
"No support for relative targets yet.");
|
|
return 0;
|
|
//QUIT
|
|
}
|
|
unless (u[UHost] && strlen(u[UHost])) {
|
|
if (connection)
|
|
connection -> w("_failure_unsupported_notation_location",
|
|
"No support for fancy UNLs yet.");
|
|
return 0;
|
|
//QUIT
|
|
}
|
|
// TODO: croak if host:port isnt us?
|
|
// or implement proxy service?
|
|
// do any checking for gateway schemes?
|
|
user = u[UUser];
|
|
r = u[UResource];
|
|
if (r && strlen(r)) {
|
|
#if __EFUN_DEFINED__(trim)
|
|
# include <sys/strings.h>
|
|
r = trim(r, TRIM_RIGHT, '/');
|
|
#else
|
|
while (r[<1] == '/') r = r[..<2];
|
|
#endif
|
|
if (strlen(r)) switch(r[0]) {
|
|
case '^':
|
|
case '~':
|
|
if (user) {
|
|
if (connection)
|
|
connection -> w("_error_invalid_uniform_user_duplicate",
|
|
"Two users in uniform not allowed here.");
|
|
// QUIT
|
|
return 0;
|
|
}
|
|
user = r[1..];
|
|
break;
|
|
case '$':
|
|
// target wird auf serv/args gesetzt
|
|
// weiss noch nicht ob das gut ist
|
|
t = r[1..];
|
|
unless (sscanf(t, "%s/%s", svc, r))
|
|
svc = t;
|
|
//P3(("find_service: %O for %O(%O)\n", o, svc, r))
|
|
if (o = find_service(lower_case(svc)))
|
|
break;
|
|
unless (user) {
|
|
if (connection)
|
|
connection -> w("_failure_unavailable_service",
|
|
"No service '[_service]' available here.", ([ "_service" : svc ]) );
|
|
return 0;
|
|
}
|
|
case '@':
|
|
// t[0..0] = PLACE_PATH;
|
|
r = PLACE_PATH + lower_case(r[1..]);
|
|
if (o = find_object(r)) break;
|
|
// should check for legal name instead
|
|
// of catch. TODO
|
|
catch(o = r -> load());
|
|
// fall thru
|
|
default:
|
|
o = find_object(r);
|
|
D2( if(!o)
|
|
D("OBJECT NOT FOUND: "+ r +"\n"); )
|
|
}
|
|
else unless (user) return 0;
|
|
if (user && !objectp(o)) {
|
|
o = summon_person(user);
|
|
// o = find_person(user);
|
|
// unless(o) o = createUser(user);
|
|
}
|
|
}
|
|
return o;
|
|
}
|
|
// new psyc-parser to fit the needs ot the new api. operates on _one_ string
|
|
// containing _one_ paket (everything after the mc is considered the data)
|
|
//
|
|
// returns the mc, psyc-data remains in the buffer.
|
|
#define ERROR(x) { monitor_report("_error_broken_syntax", x+((connection) ? sprintf(" from %O.", connection) : ".")); return 0; }
|
|
//#define ERROR(x) { monitor_report("_error_broken_syntax", x); return 0; }
|
|
|
|
static string spsyc_parse(string buf, mapping vars, int iscontext, string source,
|
|
object connection, object o) {
|
|
string mod, var, val, mc, line, lastmod, lastvar;
|
|
mixed lastval;
|
|
int a = 0, b;
|
|
|
|
while (a < strlen(buf) && !mc && ((b = strstr(buf, "\n", a)) != -1
|
|
|| b = strlen(buf))) {
|
|
|
|
val = "";
|
|
line = buf[a..b-1];
|
|
switch(buf[a]) {
|
|
case ':':
|
|
case '=':
|
|
case '+':
|
|
case '-':
|
|
unless (sscanf(line, "%1.1s%s%t%s", mod, var, val)
|
|
|| sscanf(line, "%1.1s%s", mod, var)) {
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"You are in league with Ratzinger,\
|
|
the evil lord or broken psyc.");
|
|
// <lynX> runtime error erzeugen!?? wie kommt ihr darauf
|
|
// das sei eine gute idee? damit man nen grund hat große
|
|
// teure catches zu machen? ich will in meinen logs nur
|
|
// runtime fehler von bugs - ist schon schlimm genug das
|
|
// schrottige http-zugriffe sowas auslösen, aber logs
|
|
// voller fehler von buggy psyc implementationen, nein!
|
|
// man sagt der gegenseite dass was faul ist, killt evtl
|
|
// die verbindung falls der fehler nicht recoverbar ist,
|
|
// reported oder loggt das problem, aber dann is gut!
|
|
ERROR(S("PSYC parsing failed in '%s'", line))
|
|
}
|
|
unless (sizeof(var)) {
|
|
if (mod == "-") {
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"Diminishing of lists is not supported.");
|
|
ERROR("PSYC parsing failed (Invalid list diminish)")
|
|
} else unless (lastvar) {
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"Wrong list continuation.");
|
|
ERROR("PSYC parsing failed (Invalid list continuation)")
|
|
} else unless (lastmod == mod) {
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"Inconsistent list continuation. Do not mix modifiers.");
|
|
ERROR("PSYC parsing failed (Invalid list continuation)")
|
|
}
|
|
|
|
if (pointerp(lastval)) {
|
|
lastval += ({ val });
|
|
} else {
|
|
lastval = ({ lastval, val });
|
|
}
|
|
a = b+1;
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
case '\t':
|
|
unless (lastvar) {
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"Continuation without variable.");
|
|
ERROR("PSYC parsing failed (Invalid variable continuation)")
|
|
}
|
|
if (pointerp(lastval))
|
|
lastval[<1] += "\n"+line[1..];
|
|
else lastval += "\n"+line[1..];
|
|
a = b+1;
|
|
continue;
|
|
case '_':
|
|
int i;
|
|
for (i = b - a - 1; i>=0; i--) {
|
|
unless (line[i] == '_' ||
|
|
(line[i] >= 'a' && line[i] <= 'z') ||
|
|
(line[i] >= '0' && line[i] <= '9') ||
|
|
(line[i] >= 'A' && line[i] <= 'Z')) {
|
|
if (connection)
|
|
connection -> w("_error_illegal_method",
|
|
"[_method] is not a valid method name.",
|
|
([ "_method" : line ]));
|
|
ERROR("PSYC parsing failed (Invalid method '"
|
|
+ line +"')\n")
|
|
}
|
|
}
|
|
mc = line;
|
|
switch(mc) {
|
|
case "_conversation": // we will soon have to decide its
|
|
case "_converse": // final name...
|
|
case "_talk":
|
|
mc = "_message";
|
|
break;
|
|
default:
|
|
if (abbrev("_conversation", mc)) {
|
|
mc[..12] = "_message";
|
|
} else if (abbrev("_converse", mc)) {
|
|
mc[..8] = "_message";
|
|
} else if (abbrev("_talk", mc)) {
|
|
mc[..4] = "_message";
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"Unsupported modifier '[_modifier]'",
|
|
([ "_modifier" : line[0] ]));
|
|
ERROR("PSYC parsing failed (Unknown modifier '"
|
|
+ line[0] + "')")
|
|
}
|
|
if (lastmod) switch(lastmod[0]) {
|
|
case '=':
|
|
if (o)
|
|
o -> Assign(source, lastvar, lastval, iscontext);
|
|
case ':':
|
|
vars[lastvar] = lastval;
|
|
break;
|
|
case '+':
|
|
if (o)
|
|
o -> Augment(source, lastvar, lastval, iscontext);
|
|
break;
|
|
case '-':
|
|
if (o)
|
|
o -> Diminish(source, lastvar, lastval, iscontext);
|
|
break;
|
|
}
|
|
|
|
lastmod = mod;
|
|
lastvar = var;
|
|
lastval = val;
|
|
a = b+1;
|
|
}
|
|
unless (mc) {
|
|
// malformed psyc-packet in buf. get on it!
|
|
if (connection)
|
|
connection -> w("_error_broken_syntax",
|
|
"Received packet without method.");
|
|
ERROR("PSYC parsing failed (Method missing)")
|
|
}
|
|
|
|
if (strlen(buf) == b) { // no data. packet ends with mc
|
|
buf = "";
|
|
} else {
|
|
// still data in buf. buf[b] is the last \n before the psyc-data
|
|
buf = buf[b+1..];
|
|
}
|
|
|
|
return mc;
|
|
}
|
|
|
|
// not exactly beautiful to have it here, but still more efficient than
|
|
// having hordes of if (psycd) checks..
|
|
int deliver(mixed ip, string peerip, object connection, string peeraddr,
|
|
string host, string data, mapping mvars) {
|
|
string psycaddr;
|
|
PT(("deliver(%O, %O, %O, %O)\n", ip, host, data, mvars))
|
|
mixed o, target = mvars["_target"];
|
|
int trustworthy = (member(mvars, "_INTERNAL_trust"))
|
|
? to_int(mvars["_INTERNAL_trust"])
|
|
: 0;
|
|
|
|
|
|
|
|
if (ip == -1) {
|
|
monitor_report("_error_something_because_somebody_was_once_again_too_lazy_to_look_up_a_method_which_most_likely_already_exists_in_library_dns_c", S("%O could not resolve %O.",
|
|
ME, host));
|
|
|
|
if (objectp(connection))
|
|
connection->w("_error_invalid_host", "Could not resolve [_host].",
|
|
([ "_host": host ]));
|
|
return 1;
|
|
}
|
|
|
|
if (ip && ip != peerip) {
|
|
monitor_report("_warning_rejected_relay_incoming",
|
|
"Dropped a packet from "+ peerip +
|
|
" trying to relay for "+ host);
|
|
P0(("Dropped a packet from "+ peerip +
|
|
" trying to relay for "+ host +"\n"+
|
|
" in parse:deliver(%O, %O, %O, %O)\n",
|
|
ip, host, data, mvars))
|
|
if (connection)
|
|
connection->w("_error_rejected_relay_incoming",
|
|
"You are not allowed to relay for [_host].",
|
|
([ "_host": host ]));
|
|
return 1;
|
|
} else if (psycaddr = mvars["_context"] || mvars["_source"]) {
|
|
// schmorp??
|
|
if (connection)
|
|
// is psycaddr already lc?
|
|
register_target(lower_case(psycaddr), connection);
|
|
} else psycaddr = "psyc://"+peeraddr;
|
|
|
|
if (member(mvars, "_source_identification")) {
|
|
mixed t = lookup_identification(psycaddr,
|
|
mvars["_source_identification"]);
|
|
unless (t) {
|
|
// the i: is a safety measure in case of a supergau
|
|
// that mvars["_source_identification"] could somehow resemble
|
|
// some other queue in the system.. not convinced..
|
|
// see also two more occurences in this file.
|
|
//
|
|
string n = "i:"+mvars["_source_identification"]+psycaddr;
|
|
unless (qExists(n)) qInit(n, 100, 5);
|
|
enqueue(n, ({ ip, peerip, connection, peeraddr, host, data,
|
|
mvars }));
|
|
return 0;
|
|
} else if (t == mvars["_source_identification"]) {
|
|
// TODO: increase trustworthy ness
|
|
mvars["_source_technical"] = psycaddr;
|
|
mvars["_source"] = mvars["_source_identification"];
|
|
m_delete(mvars, "_source_identification");
|
|
} else {
|
|
PT(("someone (%O) claims an identification (%O) though he is "
|
|
"already"
|
|
" registered as someone else. Will we allow multiple"
|
|
" identifications per unl? Should - in theory - be possible"
|
|
" and okay. dropping this message.\n",
|
|
psycaddr, mvars["_source_identification"]))
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
{
|
|
string state, err, mc;
|
|
mixed source, t;
|
|
mixed *u;
|
|
int iscontext = 0; // if we are in context-state
|
|
mapping psycvars = ([ "_INTERNAL_origin" : connection ]);
|
|
|
|
// this is our new context-routing without target.
|
|
// 1 _source
|
|
// 2 _target
|
|
// 4 _context
|
|
switch(
|
|
(member(mvars, "_source") ? 1 : 0) |
|
|
(member(mvars, "_target") ? 2 : 0) |
|
|
(member(mvars, "_context") ? 4 : 0)
|
|
) {
|
|
case 5:
|
|
# if DEBUG > 0
|
|
PT(("Received both context(%s) and source(%s) from %O\n",
|
|
mvars["_context"], mvars["_source"], psycaddr))
|
|
# endif
|
|
case 4:
|
|
t = mvars["_context"];
|
|
state = t;
|
|
iscontext = 1;
|
|
o = find_context(t);
|
|
unless (o) {
|
|
// no one is interested / online
|
|
// is this an abuse or a feature?
|
|
// fippo: feature, context may be 0
|
|
// if no one who is normally listening is online
|
|
PT(("Dropped messages from %s because there was no\
|
|
context slave for %s.\n",
|
|
psycaddr, mvars["_context"]))
|
|
return 1;
|
|
}
|
|
break;
|
|
case 6: // this is unicast from context to target in the context's
|
|
// state
|
|
state = mvars["_context"];
|
|
iscontext = 1;
|
|
case 3:
|
|
// "Link to [_source] established.. uses this
|
|
// and place/slave too (although improperly)
|
|
//m_delete(mvars, "_source");
|
|
unless (iscontext) {
|
|
source = lower_case(mvars["_source"]);
|
|
state = source;
|
|
}
|
|
case 2:
|
|
t = mvars["_target"];
|
|
// this is a message from the rootobj but since its target is
|
|
// not our rootmsg we need to offer some kind of source.
|
|
// TODO: Why not use ME here ??
|
|
unless (source)
|
|
source = psycaddr;
|
|
if (trustworthy > 7) {
|
|
P2(("%O relaying permitted for %O to %O via %O\n",
|
|
ME, source, t, o))
|
|
// We should do mmp-routing here.. but find out before if
|
|
// there is any connections registered for that target/host
|
|
}
|
|
u = parse_uniform(t);
|
|
if (u && (u[UResource] == "" || !u[UResource])) {
|
|
// rootMSG. that parse_uniform makes me quite unhappy.
|
|
// we may check the string t only for the existance of a
|
|
// resource since we allready know that it is a valid url.
|
|
// TODO
|
|
} else unless (o = psyc_object(t) || find_psyc_object(t)) {
|
|
PT(("Found no recipent for %O. Dropping message.\n", t))
|
|
return 1;
|
|
}
|
|
|
|
break;
|
|
case 1:
|
|
// this is a message to our rootmsg from someone
|
|
source = lower_case(mvars["_source"]);
|
|
break;
|
|
case 0:
|
|
// going to our rootmsg from hell
|
|
source = psycaddr;
|
|
break;
|
|
default:
|
|
PT(("Unimplemented routing-scheme (_source, _target and _context are all present)\n"))
|
|
return 1;
|
|
}
|
|
// can this safely move into one of the ifs above? TODO
|
|
if (t = mvars["_source_relay"]) {
|
|
if (t = psyc_object(t)) {
|
|
P2(("local _source_relay %O from %O, cont %O\n",
|
|
t, source, mvars["_context"]))
|
|
mvars["_source_relay"] = t;
|
|
}
|
|
}
|
|
|
|
unless (mc = spsyc_parse(&data, psycvars, iscontext, state,
|
|
connection, o)) {
|
|
if (connection)
|
|
destruct(connection);
|
|
return 1;
|
|
}
|
|
|
|
# ifdef PSYC_TCP
|
|
P2(("TCP[%s] => %O: %s\n", peeraddr, o || t, mc))
|
|
# else
|
|
PT(("UDP[%s] => %O: %s\n", peeraddr, o || t, mc))
|
|
# endif
|
|
|
|
# ifndef GOOD_IDEA
|
|
// why do we parse for auth mcs here if we already do it
|
|
// in common::rootMsg? if this should be here instead,
|
|
// you can make these checks a bit more efficient if
|
|
// you first ensure that the target of this message is
|
|
// the server root. it's also nicer to the users that
|
|
// you're not looking at their messages here.. ;)
|
|
//
|
|
if (mc == "_error_invalid_authentication") {
|
|
string n;
|
|
unless (member(mvars, "_source") &&
|
|
member(psycvars, "_location")) {
|
|
PT(("got _error_invalid_authentication without proper"
|
|
"vars.\n"))
|
|
return 0;
|
|
|
|
}
|
|
n = "i:"+mvars["_source"]+psycvars["_location"];
|
|
unless (qExists(n)) {
|
|
PT(("got _error_invalid_authentication for something we "
|
|
"never requested.\n"))
|
|
return 0;
|
|
}
|
|
sendmsg(psycvars["_location"], "_error_invalid_source_identification",
|
|
"Your identification [_location] seems to be bogus. "
|
|
"Du kommst hier ned rein!\n",
|
|
([ "_location" : mvars["_source"]]));
|
|
qDel(n);
|
|
return 1;
|
|
} else if (mc == "_notice_authentication") {
|
|
string n;
|
|
unless (member(mvars, "_source") &&
|
|
member(psycvars, "_location")) {
|
|
PT(("got _notice_authentication without proper"
|
|
"vars.\n"))
|
|
return 0;
|
|
}
|
|
n = "i:"+mvars["_source"]+psycvars["_location"];
|
|
unless (qExists(n)) {
|
|
PT(("got _notice_authentication for something we "
|
|
"never requested.\n"))
|
|
return 0;
|
|
}
|
|
register_location(psycvars["_location"], mvars["_source"]);
|
|
while (qSize(n))
|
|
apply(#'deliver, shift(n));
|
|
return 1;
|
|
}
|
|
# endif
|
|
|
|
// we could put these mmp-vars into cvars only to avoid this loop
|
|
foreach (string key : mvars) {
|
|
if (mergeRoutingVar(key))
|
|
psycvars[key] = mvars[key];
|
|
}
|
|
PT(("deliver ending with target: %O and mc: %O\n", o, mc))
|
|
|
|
if (objectp(o))
|
|
o -> msg(source, mc, (data == "" ? 0 : data), psycvars, 0,
|
|
source);
|
|
else if (connection) {
|
|
// per-connection "server root" which actually handles
|
|
// connection feature negotiation
|
|
connection -> rootMsg(source, mc, data == "" ? 0 : data,
|
|
psycvars, source);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* wrong order of arguments.. elsaga: how did this ever work!?
|
|
int msg(mixed target, string mc, mixed data, mapping vars,
|
|
mixed source, mixed target2) {
|
|
*/
|
|
int msg(mixed source, string mc, mixed data, mapping vars,
|
|
mixed showingLog, mixed target) {
|
|
string sname;
|
|
int port;
|
|
string user, host, obj;
|
|
string buf, room;
|
|
object o;
|
|
mixed t;
|
|
array(mixed) u = parse_uniform(target);
|
|
|
|
unless (u[UHost]) {
|
|
sendmsg(source, "_failure_unsupported_notation_location",
|
|
"PSYC server-independent uniform network "
|
|
"identificators not implemented yet.", 0, 0);
|
|
return 0;
|
|
}
|
|
#if DEBUG > 0
|
|
unless (stringp(mc)) {
|
|
P0(("psyc_sendmsg got mc == %O from %O.\n"
|
|
"probably a mistake when converting a walk_mapping.\n",
|
|
mc, previous_object()))
|
|
return 0;
|
|
}
|
|
#endif
|
|
sname = psyc_name(source);
|
|
// host = lower_case(u[UHostPort]);
|
|
// unless (u[URoot]) u[URoot] = "psyc://"+host;
|
|
|
|
// TODO: no need for vars
|
|
unless (mappingp(vars)) vars = ([ ]);
|
|
P3(("looking for %O(%O) in %O..\n", target, u[UHostPort], targets))
|
|
// if (member(targets, t2 = u[URoot])) {
|
|
// t = targets[t2];
|
|
// if (t) {
|
|
unless (port = u[UPort]) port = PSYC_SERVICE;
|
|
else if (port < 0) {
|
|
sendmsg(vars["_context"] || source,
|
|
"_failure_network_connect_invalid_port",
|
|
"No connectable port known for [_source_relay].",
|
|
([ "_source_relay" : target || u[UHost] ]), ME);
|
|
// ME shouldn't be necessary! TODO
|
|
return 0;
|
|
}
|
|
host = lower_case(u[UHost]);
|
|
user = u[UUser];
|
|
obj = u[UResource];
|
|
// was: obj = u[UResource];
|
|
// but probably caused the erratic rootMsg() events
|
|
//obj = u[UUser] ? "~" + u[UUser] : u[UResource];
|
|
//
|
|
// if (host == SERVER_HOST) host = "127.0.0.1";
|
|
#if 1
|
|
//
|
|
// at this point i should be able to recognize targets which are my own!
|
|
// net/gateway/aim would use that.. TODO
|
|
//
|
|
// see also legal_domain and legal_host
|
|
if (query_udp_port() == port && (host == "127.0.0.1"
|
|
|| host == "127.1"
|
|
#ifdef __HOST_IP_NUMBER__
|
|
|| host == __HOST_IP_NUMBER__
|
|
#else
|
|
|| host == myIP
|
|
#endif
|
|
// || host == SERVER_HOST
|
|
// || lower_case(host) == myLowerCaseHost
|
|
|| host == my_lower_case_host() || host == "localhost")) {
|
|
if (stringp(obj)) {
|
|
if (obj[<1] == '/') obj = obj[..<2];
|
|
if (strlen(obj)) switch(obj[0]) {
|
|
case '^':
|
|
case '~':
|
|
unless(user) user = obj[1..];
|
|
break;
|
|
case '$':
|
|
// no services available yet
|
|
// but here's the support for them
|
|
obj[0..0] = "/service/";
|
|
break;
|
|
case '@':
|
|
// t[0..0] = PLACE_PATH;
|
|
obj = PLACE_PATH + lower_case(obj[1..]);
|
|
if (o = find_object(obj)) break;
|
|
// should check for legal name instead
|
|
// of catch. TODO
|
|
catch(obj -> load());
|
|
// fall thru
|
|
default:
|
|
o = find_object(obj);
|
|
D2( if(!o) D(S("OBJECT NOT FOUND: %O\n", t)); )
|
|
} else unless(user) {
|
|
// rootMsg(source, mc,
|
|
// buffer == "" ? 0 : buffer, cvars);
|
|
return 0;
|
|
}
|
|
}
|
|
// user@ is ignored if /@ or /~ is given..
|
|
if (user && !objectp(o)) {
|
|
o = summon_person(user); //, PSYC_PATH "user");
|
|
//o = find_person(user);
|
|
//unless(o) o = createUser(user);
|
|
}
|
|
// cache the resulting object for the url
|
|
register_target(lower_case(target), o);
|
|
return sendmsg(o, mc, data, vars, source);
|
|
// or deliver directly?
|
|
}
|
|
#endif
|
|
// okay so we have no existing connection..
|
|
// current rule of thumb to decide whether to open up a tcp
|
|
// also all localhost traffic should be handled by udp TODO
|
|
#ifdef _flag_enable_routing_UDP
|
|
unless (u[UTransport] == "d" || abbrev("_notice", mc)) {
|
|
#endif
|
|
dns_resolve(host, (:
|
|
object o;
|
|
string addr = $1;
|
|
string hopo = $2;
|
|
string psycaddr = "psyc://"+ addr;
|
|
|
|
// if ($3 && $3 != PSYC_SERVICE) {
|
|
if ($9) {
|
|
hopo += ":"+$9;
|
|
addr += ":"+$9;
|
|
}
|
|
unless (o = find_target_handler(psycaddr)) {
|
|
o = ("psyc:"+hopo) -> circuit($2, $3, 0, "psyc", 0,
|
|
system_queue());
|
|
}
|
|
register_target($4, o);
|
|
register_target("psyc://"+hopo, o);
|
|
register_target(psycaddr, o);
|
|
P2(("delivering %O(%O) over %O\n", hopo, $1, o))
|
|
// psyc/circuit.c will register psyc://IP:PORT at logon()
|
|
// the last thing missing is a way to register all CNAMEs
|
|
return o->msg($5, $6, $7, $8, 0, $4);
|
|
// ip=1 2 3 4 5 6 7 8 9
|
|
:),
|
|
host, port, target, sname, mc, data, vars, u[UPort]
|
|
);
|
|
return 1;
|
|
#ifdef _flag_enable_routing_UDP
|
|
}
|
|
// fall thru to UDP
|
|
# if DEBUG > 1
|
|
if (port) {
|
|
D(S("UDP[%s:%d] <= %O: %s\n", host, port, source, mc));
|
|
} else {
|
|
D(S("UDP[%s] <= %O: %s\n", host, source, mc));
|
|
}
|
|
# endif
|
|
if (objectp(source)) buf = make_psyc(mc, data, vars, source);
|
|
else buf = make_psyc(mc, data, vars);
|
|
buf = make_mmp(buf, vars);
|
|
|
|
if (host == "localhost") return send_udp(host, port, buf);
|
|
P3(("send_udp %O:%O packet:\n%O", host,port,buf))
|
|
dns_resolve(host, (: if ($2 < 0) {
|
|
send_udp($1, $2, $3);
|
|
}
|
|
return; :), port, buf);
|
|
return 1;
|
|
#endif /* _flag_enable_routing_UDP */
|
|
}
|
|
|
|
object load() {
|
|
return ME;
|
|
}
|
|
|
|
int outstate() {
|
|
return 1;
|
|
}
|
|
|
|
mapping state() {
|
|
return ([]);
|
|
}
|
|
|
|
void create() {
|
|
qCreate();
|
|
}
|
|
|
|
#endif // }}}
|