示例#1
0
文件: imc.c 项目: bkero/Smaug
void imc_startup(const char *prefix)
{
  if (imc_active!=IA_NONE)
  {
    imc_logstring("imc_startup: called with imc_active=%d", imc_active);
    return;
  }

  imc_now=time(NULL);                  /* start our clock */
  imc_boot=imc_now;

  imc_logstring("%s initializing", IMC_VERSIONID);

#ifdef USEIOCTL
  outqsize = getsndbuf();
  imc_logstring("found TIOCOUTQ=%d", outqsize);
#endif

  imc_prefix=imc_strdup(prefix);

  imc_sequencenumber=imc_now;
  strcpy(imc_lasterror, "no error");

  imc_readconfig();
  imc_readignores();

  imc_active = imc_name ? IA_CONFIG2 : IA_CONFIG1;

  if (imc_active==IA_CONFIG2)
    imc_startup_network();
}
示例#2
0
文件: imc.c 项目: bkero/Smaug
/* handle a password response from a server */
static void serverpassword(imc_connect *c, const char *argument)
{
  char arg1[3], name[IMC_MNAME_LENGTH], pw[IMC_PW_LENGTH], version[20];
  imc_info *i;

  argument=imc_getarg(argument, arg1, 4);	/* has to be PW */
  argument=imc_getarg(argument, name, IMC_MNAME_LENGTH);
  argument=imc_getarg(argument, pw, IMC_PW_LENGTH);
  argument=imc_getarg(argument, version, 20);

  if (strcasecmp(arg1, "PW"))
  {
    imc_logstring("%s: non-PW password packet", imc_getconnectname(c));
    do_close(c);
    return;
  }

  i=imc_getinfo(name);
  if (!i || strcmp(i->serverpw, pw) ||
      i != c->info)
  {
    if ((!i || !(i->flags & IMC_QUIET)) && !(c->info->flags & IMC_QUIET))
    imc_logstring("%s: password failure for %s", imc_getconnectname(c), name);
    do_close(c);
    return;
  }

  if (i->connection)	/* kill old connections */
    do_close(i->connection);

  i->connection         = c;

  c->state              = IMC_CONNECTED;
  c->spamcounter1       = 0;
  c->spamcounter2       = 0;

  /* check for a version string (assume version 0 if not present) */
  if (sscanf(version, "version=%hu", &c->version)!=1)
    c->version=0;

  /* check for generator/interpreter */
  if (!imc_vinfo[c->version].generate ||
      !imc_vinfo[c->version].interpret)
  {
    if (!(i->flags & IMC_QUIET))
      imc_logstring("%s: unsupported version %d",
		    imc_getconnectname(c), c->version);
    do_close(c);
    return;
  }

  if (!(i->flags & IMC_QUIET))
    imc_logstring("%s: connected (version %d)",
		  imc_getconnectname(c), c->version);
  c->info->timer_duration=IMC_MIN_RECONNECT_TIME;
  c->info->last_connected=imc_now;
  imc_cancel_event(ev_login_timeout, c);
  imc_cancel_event(ev_reconnect, c->info);
}
示例#3
0
文件: imc-interp.c 项目: bkero/Smaug
void imc_autoconnect_reply_accept(const char *from, const char *rhost, int rport, const char *rclientpw, const char *rserverpw, 
						  int rrcvstamp, int rnoforward, const char *rflags, const char *remotename, const char *confirm) {
	/* Wow.. what a function name! This gets the packet that says "connection added"
	in it from the hub, then adds the appropriate connection here. -- Scion */

	imc_info *i,*o;

	imc_logstring("Received autoconnect reply from %s.", remotename);
	if (strcasecmp(confirm, "connection added")) { /* Don't change this, or it won't work. */
		imc_logstring("Confirmation refused: %s", confirm);
		return;
	}

	if (imc_name && !strcasecmp(remotename, imc_name)) {
	  imc_logstring("Autoconnect attempt allegedly from this host! Ignoring.");
      return; /* Hey! That's our name! */
  }
  else if (!strcasecmp(rhost, "!!!")) {
	  imc_logstring("Unknown host name for %s. Aborting.", remotename);
	  return;
  } else {
	/* Setup the new connection... */
  if((o=imc_getinfo(remotename))) /* remove old entries - shogar */
  {
  	i=imc_insert_info();
        i->connection=o->connection;
        i->flags=o->flags; 
        if(i->connection) i->connection->info=i;
  	imc_cancel_info(o); 
  }
  else
  {
  	i=imc_insert_info();
//        i->flags      = imc_flagvalue("hub reconnect new", imc_connection_flags);
        i->flags      = imc_flagvalue("hub new", imc_connection_flags);
  }

      i->name       = imc_strdup(remotename);
      i->host       = imc_strdup(rhost);
      i->port       = (unsigned short)rport;
      i->clientpw   = imc_strdup(rclientpw);
      i->serverpw   = imc_strdup(rserverpw);
      i->rcvstamp   = rrcvstamp;
      i->noforward  = rnoforward;
      i->connect_attempts = 0;

      imc_saveconfig();

	  imc_connect_to(remotename);
	  /* All done! */
	  imc_logstring("Added connection to %s.", remotename);

  }
  imc_send_keepalive();

}
示例#4
0
/* global init */
void icec_init(void) {
    imc_logstring("ICE client starting.");
    icec_recv_chain = imc_recv_hook;
    imc_recv_hook = icec_recv;
    imc_add_event(60, ev_icec_firstrefresh, NULL, 1);
    icec_load_channels();
}
示例#5
0
文件: imc.c 项目: bkero/Smaug
/* accept a connection on the control port */
static void do_accept(void)
{
  int d;
  imc_connect *c;
  struct sockaddr_in sa;
  int size = sizeof(sa);
  int r;

  d=accept(control, (struct sockaddr *) &sa, &size);
  if (d<0)
  {
    imc_lerror("accept");
    return;
  }

  r=fcntl(d, F_GETFL, 0);
  if (r<0 || fcntl(d, F_SETFL, O_NONBLOCK | r)<0)
  {
    imc_lerror("do_accept: fcntl");
    close(d);
    return;
  }

  c=imc_new_connect();
  c->state    = IMC_WAIT1;
  c->desc     = d;

  imc_add_event(IMC_LOGIN_TIMEOUT, ev_login_timeout, c, 1);
  imc_logstring("connection from %s:%d on descriptor %d",
		inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), d);
}
示例#6
0
文件: imc-interp.c 项目: bkero/Smaug
/* send a blank packet with a type of "inforequest" to everyone. The reply is automatic
so we don't need to send any data except who we are. Those with less than version 1.0a will
reply with a reject packet. */
void imc_send_info_request(void)
{
  imc_packet out;

  if (imc_active<IA_UP)
    return;
  global_directnum=-1;
  if(!time_of_last_salive) /* ping istat monitor - shogar */
  {
	time_of_last_salive=time(NULL);
  }
  else
  {
        time_since_last_salive = time(NULL) - time_of_last_salive;
	time_of_last_salive =time(NULL);
  }

  imc_initdata(&out.data);
  strcpy(out.type, "inforequest");
  strcpy(out.from, "*");
  strcpy(out.to, "*@*");

  imc_send(&out);
  imc_freedata(&out.data);
  imc_logstring("Polling for fast hubs.");
}
示例#7
0
文件: imc.c 项目: bkero/Smaug
int imc_disconnect(const char *mud)
{
  imc_connect *c;
  imc_info *i;
  int d;

  if (imc_active == IA_NONE)
  {
    imc_qerror("IMC is not active");
    return 0;
  }

  if ((d=atoi(mud))!=0)
  {
    /* disconnect a specific descriptor */

    for (c=imc_connect_list; c; c=c->next)
      if (c->desc==d)
      {
        imc_logstring("disconnect descriptor %s", imc_getconnectname(c));
	do_close(c);
	return 1;
      }

    imc_qerror("%d: no matching descriptor", d);
    return 0;
  }
    
  i=imc_getinfo(mud);
  if (!i)
  {
    if (strcasecmp(mud, "unknown")) /* disconnect all unknown muds */
    {
      imc_qerror("%s: unknown mud", mud);
      return 0;
    }
  }

  imc_logstring("disconnect %s", mud);

  for (c=imc_connect_list; c; c=c->next)
    if (c->info==i)
      do_close(c);

  return 1;
}
示例#8
0
文件: imc.c 项目: bkero/Smaug
/* time out a login */
void ev_login_timeout(void *data)
{
  imc_connect *c=(imc_connect *)data;

  if (!c->info || !(c->info->flags & IMC_QUIET))
    imc_logstring("%s: login timeout", imc_getconnectname(c));
  do_close(c);
}
示例#9
0
文件: imc-interp.c 项目: bkero/Smaug
/* send connection info to new hub for optimization */
void imc_send_autoconnect(const char *to)
{
  imc_packet out;
  imc_info *i;
  char no_port[IMC_MNAME_LENGTH];

  int a=0,b=0;

  if (imc_active<IA_UP)
    return;

  i=imc_getinfo(to);
  if(i && i == imc_info_list && i->connection) /* not if primary hub - shogar */
    return;

     /* Send all this info: -- Scion 
	 imc set <mudname> all <host> <port> <clientpw> <serverpw> <rcvstamp> <noforward> <flags>
		*/
  imc_initdata(&out.data);
  strcpy(out.type, "imc-switch");
  strcpy(out.from, "*");
  strcpy(out.to, "*@");
  imc_sncpy(out.to+2, to, IMC_MNAME_LENGTH-2);

  /* Get that pesky port out of the host name */
  for (a=0;a<strlen(imc_siteinfo.host); a++) {
	  if (imc_siteinfo.host[a]==':' 
	  || imc_siteinfo.host[a]==' ') 
	  {
		  break;
	  }
	  no_port[b++]=imc_siteinfo.host[a];
	  no_port[b]='\0';
  }
  imc_addkey(&out.data, "host", no_port);
  imc_addkeyi(&out.data, "port", (int)imc_port);
  
  if(i) /* don't assign new ones, if we have passwords */
  {
  	imc_addkey(&out.data, "clientpw", i->clientpw);
  	imc_addkey(&out.data, "serverpw", i->serverpw);
  }
  else 
  {
  	imc_addkey(&out.data, "clientpw", imc_make_password());/* these are random */
  	imc_addkey(&out.data, "serverpw", imc_make_password());
  }
  imc_addkeyi(&out.data, "rcvstamp", 0);
  imc_addkeyi(&out.data, "noforward", 0);
  imc_addkey(&out.data, "flags", "none");
  imc_addkey(&out.data, "localname", imc_name);

  imc_send(&out);
  imc_freedata(&out.data);
  imc_logstring("Autoconnect sent to %s", to);
}
示例#10
0
文件: imc-interp.c 项目: bkero/Smaug
/* Take the data from an info-reply packet and process it. We shouldn't get packets from MUDs, only
from hubs. -- Scion */
void imc_recv_info_reply(const char *from, const char *hub, int direct) {
	
/* Globals needed: hubname, directnum */

if (direct > global_directnum) 
{
	imc_info *i;

	/* spin infolist check for noswitch flag - shogar */
	  for (i=imc_info_list; i; i=i->next)
              if(i->flags & IMC_NOSWITCH && !strcasecmp(imc_mudof(from),i->name))
	      {
		imc_logstring("Rejecting info-reply(%d) from %s", direct,from);
			return;
	      }
		imc_sncpy(global_hubname, imc_mudof(from),  IMC_MNAME_LENGTH);
		global_directnum=direct;
	}
	imc_logstring("Received info-reply(%d) from %s", direct,from);
}
示例#11
0
文件: imc.c 项目: bkero/Smaug
/* shut down listening port */
void imc_shutdown_port(void)
{
  if (imc_active!=IA_LISTENING)
  {
    imc_logerror("imc_shutdown_port: called with imc_active=%d", imc_active);
    return;
  }

  imc_logstring("closing listen port");
  close(control);
  imc_active=IA_UP;
}
示例#12
0
文件: imc-interp.c 项目: bkero/Smaug
 /* This function was rendered useless when everything was packed into
 rquery, and the rquery info command returned that dumb little #define instead
 of this info. I swapped this with the rquery info function, and now I'm salvaging
 this function to use for something entirely different. 1/5/99 -- Scion
 */
void imc_recv_inforequest(const char *from) {
	/* What we're going to do here is to reply to a type of packet
	labelled as "inforequest". We'll reply with two things: 
	1) Are we a hub or not?
	2) The number of direct connections we have.
	
	  What will happen when the MUD receives this info is that it will compare
	  each of the available hubs and find the one with the least number of direct
	  connections. It will then switch its hub connection to the hub with less
	  connections, hopefully averaging the number of connections per hub. You will
	  be able to prevent this auto-swap by #defining NO_OPTIMIZE in imc-config.h -- Scion */
  imc_packet reply;
  int num_direct=0;
  imc_info *i;
  
  extern imc_info *imc_info_list;

  strcpy(reply.to, from);
  strcpy(reply.from, "*");

  imc_initdata(&reply.data);

  if (imc_isignored(from)) /* Don't reply if they're ignored */
  {
    strcpy(reply.type, "info-unavailable");
    imc_send(&reply);
  }
  strcpy(reply.type, "info-reply");
    
  if (imc_is_router) 
  	/* don't even send a reply if we're not a hub -- Scion */
  {
	  imc_addkey(&reply.data, "hub",    "yes");
	  for (i=imc_info_list; i; i=i->next)
              if(i->connection && i->connection->state & IMC_CONNECTED) /* only the live ones - shogar */
			num_direct++;
	  imc_addkeyi(&reply.data, "direct",    
		imc_siteinfo.maxguests - num_direct);
  
        /*  don't send if num_direct exceeds maxguest - shogar */
        if(num_direct <= imc_siteinfo.maxguests)
        {
  		imc_send(&reply);
  		imc_logstring("Sent info-reply to %s.", from);
	}
  }
  imc_freedata(&reply.data);
}
示例#13
0
void icec_load_channels(void)
{
  FILE *fp;
  char name[MAX_STRING_LENGTH];
  char buf1[MAX_STRING_LENGTH];
  char buf2[MAX_STRING_LENGTH];
  char buf3[MAX_STRING_LENGTH];
  char buf4[MAX_STRING_LENGTH];
  int l;

  strcpy(name, imc_prefix);
  strcat(name, "icec");

  fp=fopen(name, "r");
  if (!fp)
  {
    imc_logerror("Can't open %s", name);
    return;
  }

  while (fscanf(fp,
		"%s %s %d\n"
		"%[^\n]\n"
		"%[^\n]\n", buf1, buf2, &l, buf3, buf4) == 5)
  {
    ice_channel *c=imc_malloc(sizeof(*c));

    c->local=imc_malloc(sizeof(*c->local));
    
    c->name=imc_strdup(buf1);
    c->local->name=imc_strdup(buf2);
    c->local->format1=imc_strdup(buf3);
    c->local->format2=imc_strdup(buf4);
    c->local->level=l;
    
    c->next=saved_channel_list;
    saved_channel_list=c;

    imc_logstring("ICEc: configured %s as %s",
		  c->name, c->local->name);
  }

  fclose(fp);
}
示例#14
0
文件: imc.c 项目: bkero/Smaug
/* forward a packet - main routing function, all packets pass through here */
static void forward(imc_packet *p)
{
  imc_info *i;
  int broadcast, isbroadcast;
  const char *to;
  imc_reminfo *route;
  imc_info *direct;
  imc_connect *c;
  char recievedfrom[IMC_MAXBUF]; /* SPAM fix - shogar */
  imc_connect *rf; /* SPAM fix - shogar */

  /* check for duplication, and register the packet in the sequence memory */
  
  if (p->i.sequence && checkrepeat(imc_mudof(p->i.from), p->i.sequence))
    return;

  /* check for packets we've already forwarded */

  if (inpath(p->i.path, imc_name))
    return;

  /* check for really old packets */

  route=imc_find_reminfo(imc_mudof(p->i.from), 1);
  if (route)
  {
    if ((p->i.sequence+IMC_PACKET_LIFETIME) < route->top_sequence)
    {
      imc_stats.sequence_drops++;
#ifdef LOG_LATE_PACKETS 
	/* kind of spammy, but late packets are natural when the path
           is broken between sender and reciever
      if(imc_is_router) /* spare the muds from seeing this - shogar */
         imc_logstring("sequence drop: %s (seq=%ld, top=%ld)",
		    p->i.path, p->i.sequence, route->top_sequence);
#endif
      return;
    }
    if (p->i.sequence > route->top_sequence)
      route->top_sequence=p->i.sequence;
  }

  /* update our routing info */

  updateroutes(p->i.path);

  /* forward to our mud if it's for us */

  if (!strcmp(imc_mudof(p->i.to), "*") ||
      !strcasecmp(imc_mudof(p->i.to), imc_name))
  {
    strcpy(p->to, imc_nameof(p->i.to));    /* strip the name from the 'to' */
    strcpy(p->from, p->i.from);

    imc_recv(p);
  }

  /* if its only to us (ie. not broadcast) don't forward it */
  if (!strcasecmp(imc_mudof(p->to), imc_name))
    return;

  /* check if we should just drop it (policy rules) */
  if (!can_forward(p))
    return;
  
  /* convert a specific destination to a broadcast in some cases */

  to=imc_mudof(p->i.to);

  isbroadcast=!strcmp(to, "*");	  /* broadcasts are, well, broadcasts */
  broadcast=1;		          /* unless we know better, flood packets */
  i=0;  			  /* make gcc happy */
  direct=NULL;			  /* no direct connection to send on */
  
  /* convert 'to' fields that we have a route for to a hop along the route */
  
  if (!isbroadcast &&
      (route=imc_find_reminfo(to, 0)) != NULL &&
      route->route != NULL &&
      !inpath(p->i.path, route->route))	/* avoid circular routing */
  {
    /*  check for a direct connection: if we find it, and the route isn't
     *  to it, then the route is a little suspect.. also send it direct
     */
    if (strcasecmp(to, route->route) &&
	(i=imc_getinfo(to))!=NULL &&
	i->connection)
      direct=i;
    to=route->route;
  }
  
  /* check for a direct connection */
  
  if (!isbroadcast &&
      (i=imc_getinfo(to)) != NULL &&
      i->connection &&
      !(i->flags & IMC_BROADCAST))
    broadcast=0;

  if (broadcast)
  {				/* need to forward a packet */
    /* SPAM fix - hubcnt and who just gave us the packet- shogar */
    int hubcnt,fromhub;
    hubcnt=0;
    fromhub=0;
    strcpy(recievedfrom,imc_lastinpath(p->i.path)); 
    for (rf=imc_connect_list; rf; rf=rf->next)
    {
	if(rf->info && rf->info->name && !strcmp(recievedfrom,rf->info->name))
        {
        	if(rf->info->flags & IMC_HUB) 
			fromhub=1;
	}
    }
    /* end SPAM fix */

    for (c=imc_connect_list; c; c=c->next)
      if (c->state==IMC_CONNECTED)
      {
	/* don't forward to sites that have already received it,
	 * or sites that don't need this packet
	 */
	if (inpath(p->i.path, c->info->name) ||
	    (p->i.stamp & c->info->noforward)!=0)
	  continue;
        /* SPAM fix - shogar */
        if(c->info->flags & IMC_HUB) 
        {
	    	if(!imc_is_router)
            	{
			if (fromhub)
				continue;
			if(hubcnt)
			{
				continue;
			}
			else
			{
				hubcnt=1;
			}
		}
/* if for imc3 we need to do this - shogar */
/*
        	if (imc_getkeyi(&p->data,"channel",0) == 2)
			continue;
*/
	}
	/* end SPAM fix */
	do_send_packet(c, p);
      }
  }
  else
    /* forwarding to a specific connection */
  {
    /* but only if they haven't seen it (sanity check) */
    if (i->connection && !inpath(p->i.path, i->name))
      do_send_packet(i->connection, p);

    /* send on direct connection, if we have one */
    if (direct && direct!=i && direct->connection &&
	!inpath(p->i.path, direct->name))
      do_send_packet(direct->connection, p);
  }
}
示例#15
0
文件: imc.c 项目: bkero/Smaug
/* handle a password from a client */
static void clientpassword(imc_connect *c, const char *argument)
{
  char arg1[3], name[IMC_MNAME_LENGTH], pw[IMC_PW_LENGTH], version[20];
  imc_info *i;
  char response[IMC_PACKET_LENGTH];

  argument=imc_getarg(argument, arg1, 4);      /* packet type (has to be PW) */
  argument=imc_getarg(argument, name, IMC_MNAME_LENGTH);  /* remote mud name */
  argument=imc_getarg(argument, pw, IMC_PW_LENGTH);	         /* password */
  argument=imc_getarg(argument, version, 20);	/* optional version=n string */

  if (strcasecmp(arg1, "PW"))
  {
    imc_logstring("%s: non-PW password packet", imc_getconnectname(c));
    do_close(c);
    return;
  }

  /* do we know them, and do they have the right password? */
  i=imc_getinfo(name);
  if (!i || strcmp(i->clientpw, pw))
  {
    if (!i || !(i->flags & IMC_QUIET))
    imc_logstring("%s: password failure for %s", imc_getconnectname(c), name);
    do_close(c);
    return;
  }

  /* deny access if deny flag is set (good for eg. muds that start crashing
   * on rwho)
   */
  if (i->flags & IMC_DENY)
  {
    if (!(i->flags & IMC_QUIET))
      imc_logstring("%s: denying connection", name);
    do_close(c);
    return;
  }

  if (i->connection)	                      /* kill old connections */
    do_close(i->connection);

  /* register them */
  i->connection     = c;

  c->state          = IMC_CONNECTED;
  c->info           = i;
  c->spamcounter1   = 0;
  c->spamcounter2   = 0;

  /* check for a version string (assume version 0 if not present) */
  if (sscanf(version, "version=%hu", &c->version)!=1)
    c->version=0;

  /* check for generator/interpreter */
  if (!imc_vinfo[c->version].generate ||
      !imc_vinfo[c->version].interpret)
  {
    if (!(i->flags & IMC_QUIET))
    imc_logstring("%s: unsupported version %d",
		  imc_getconnectname(c), c->version);
    do_close(c);
    return;
  }

  /* send our response */

  sprintf(response, "PW %s %s version=%d",
	  imc_name, i->serverpw, IMC_VERSION);
  do_send(c, response);

  if (!(i->flags & IMC_QUIET))
    imc_logstring("%s: connected (version %d)",
		  imc_getconnectname(c), c->version);

  c->info->timer_duration=IMC_MIN_RECONNECT_TIME;
  c->info->last_connected=imc_now;
  imc_cancel_event(ev_login_timeout, c);
  imc_cancel_event(ev_reconnect, c->info);
}
示例#16
0
文件: imc.c 项目: bkero/Smaug
/* close given connection */
static void do_close(imc_connect *c)
{
  const char *name;
  imc_reminfo *r;

  if (c->info) /* if our switched hub, get a new one right away - shogar */
  {
    if (!imc_is_router && (c->info->flags & IMC_NEW_HUB) && c->info == imc_info_list)
    {
	imc_cancel_event(ev_imc_pollforhub,NULL);
	imc_cancel_event(ev_imc_optimize,NULL);
  	imc_add_event(10, ev_imc_pollforhub, NULL, 1);
  	imc_add_event(70, ev_imc_optimize, NULL, 1);
    }
  }
  
  if (c->state==IMC_CLOSED)
    return;

  name=imc_getconnectname(c);
  if(name && c->state == IMC_CONNECTED) /* dont send if never connected */
  {
  	imc_close_notify(name);
        close(c->desc); /* dont close if closed */
  }
  if (c->state == IMC_CONNECTED)
    c->info->connection=NULL;

  /* handle reconnects */
  if (c->info)
    if ((c->info->flags & IMC_RECONNECT) &&
	!(c->info->flags & IMC_DENY) &&
	!(c->info->flags & IMC_CLIENT))
    {
      imc_setup_reconnect(c->info);
    }

  c->state=IMC_CLOSED;

  /* only log after we've set the state, in case imc_logstring
   * sends packets itself (problems with eg. output buffer overflow).
   */
  if (!c->info || !(c->info->flags & IMC_QUIET))
  {
  	name=imc_getconnectname(c);
    	if(name) imc_logstring("%s: closing link", name);
  }

  if (c->info)
  {
    r=imc_find_reminfo(c->info->name, 1);
    if (r)
      imc_delete_reminfo(r);
  }
  if(c->desc)
	close(c->desc);
  c->desc=0;
  c->inbuf[0]=0;
  c->outbuf[0]=0;
  
}
示例#17
0
文件: imc-interp.c 项目: bkero/Smaug
/* handle a packet destined for us, or a broadcast */
void imc_recv(const imc_packet *p)
{
  imc_char_data d;
  int bcast;
  imc_reminfo *i;

  bcast=!strcmp(imc_mudof(p->i.to), "*") ? 1 : 0;
  
  getdata(p, &d);

  if(!imc_is_router)
  {
	i=imc_find_reminfo(imc_mudof(p->from),0);
	if(i)
	{
		if(i->path)
			imc_strfree(i->path);
		i->path=imc_strdup(p->i.path);
		i->ping=0;
                i->type=0;
	}
  }
  
  /* chat: message to a channel (broadcast) */
  if (!strcasecmp(p->type, "chat") && !imc_isignored(p->from))
    imc_recv_chat(&d, imc_getkeyi(&p->data, "channel", 0),
		  imc_getkey(&p->data, "text", ""));

  /* emote: emote to a channel (broadcast) */
  else if (!strcasecmp(p->type, "emote") && !imc_isignored(p->from))
    imc_recv_emote(&d, imc_getkeyi(&p->data, "channel", 0),
		   imc_getkey(&p->data, "text", ""));

  /* tell: tell a player here something */
  else if (!strcasecmp(p->type, "tell"))
  {
    if (imc_isignored(p->from))
    {
      imc_sendignore(p->from);
    }
    else
    {
      imc_recv_tell(&d, p->to, imc_getkey(&p->data, "text", ""),
		    imc_getkeyi(&p->data, "isreply", 0));
    }
  }

  /* who-reply: receive a who response */
  else if (!strcasecmp(p->type, "who-reply"))
    imc_recv_whoreply(p->to, imc_getkey(&p->data, "text", ""),
		      imc_getkeyi(&p->data, "sequence", -1));

  /* who: receive a who request */
  else if (!strcasecmp(p->type, "who"))
  {
    if (imc_isignored(p->from))
    {
      imc_sendignore(p->from);
    }
    else
    {
      imc_recv_who(&d, imc_getkey(&p->data, "type", "who"));
    }
  }

  /* whois-reply: receive a whois response */
  else if (!strcasecmp(p->type, "whois-reply"))
    imc_recv_whoisreply(p->to, imc_getkey(&p->data, "text", ""));

  /* whois: receive a whois request */
  else if (!strcasecmp(p->type, "whois"))
    imc_recv_whois(&d, p->to);

  /* beep: beep a player */
  else if (!strcasecmp(p->type, "beep"))
  {
    if (imc_isignored(p->from))
    {
      imc_sendignore(p->from);
    }
    else
    {
      imc_recv_beep(&d, p->to);
    }
  }

  /* is-alive: receive a keepalive (broadcast) */
  else if (!strcasecmp(p->type, "is-alive"))
    imc_recv_keepalive(imc_mudof(p->from),
		       imc_getkey(&p->data, "versionid", "unknown"),
		       imc_getkey(&p->data, "flags", ""));

  /* ping: receive a ping request */
  else if (!strcasecmp(p->type, "ping"))
    imc_recv_ping(imc_mudof(p->from), imc_getkeyi(&p->data, "time-s", 0),
		  imc_getkeyi(&p->data, "time-us", 0), p->i.path);

  /* ping-reply: receive a ping reply */
  else if (!strcasecmp(p->type, "ping-reply"))
    imc_recv_pingreply(imc_mudof(p->from), imc_getkeyi(&p->data, "time-s", 0),
		       imc_getkeyi(&p->data, "time-us", 0),
		       imc_getkey(&p->data, "path", NULL), p->i.path);

  /* mail: mail something to a local player */
  else if (!strcasecmp(p->type, "mail"))
    imc_recv_mail(imc_getkey(&p->data, "from", "error@hell"),
		  imc_getkey(&p->data, "to", "error@hell"),
		  imc_getkey(&p->data, "date", "(IMC error: bad date)"),
		  imc_getkey(&p->data, "subject", "no subject"),
		  imc_getkey(&p->data, "id", "bad_id"),
		  imc_getkey(&p->data, "text", ""));

  /* mail-ok: remote confirmed that they got the mail ok */
  else if (!strcasecmp(p->type, "mail-ok"))
    imc_recv_mailok(p->from, imc_getkey(&p->data, "id", "bad_id"));

  /* mail-reject: remote rejected our mail, bounce it */
  else if (!strcasecmp(p->type, "mail-reject"))
    imc_recv_mailrej(p->from, imc_getkey(&p->data, "id", "bad_id"),
		     imc_getkey(&p->data, "reason",
				"(IMC error: no reason supplied"));

/* handle keepalive requests - shogar */
  else if (!strcasecmp(p->type, "keepalive-request"))
  {
        if(imc_is_router)
        	imc_logstring("Recieved keepalive request from %s", p->from);
	imc_send_keepalive();
  }
/* expire closed hubs - shogar */
  else if (!strcasecmp(p->type, "close-notify"))
  {
        imc_reminfo *r;
	char fake[90];
    	struct timeval tv;

        if(imc_is_router)
  		imc_logstring("%s reports %s closed.", p->from,
        	imc_getkey(&p->data, "host","unknown"));
        if(imc_is_router)
		return;

	r = imc_find_reminfo(imc_getkey(&p->data,"host","unknown"),0);
        if(r)
	{
		r->type = IMC_REMINFO_EXPIRED;
		for(r=imc_reminfo_list;r;r=r->next)
		{
			char *sf;
			sprintf(fake,"!%s",imc_getkey(&p->data,"host","___unknown"));
			if(r->name 
			&& r->path 
			&& (sf=strstr(r->path,fake))
			&& sf 
			&& (*(sf+strlen(fake))=='!' || *(sf+strlen(fake)) == 0) 
			)
			{

//				imc_logstring("Expiring %s",r->path);
				r->type = IMC_REMINFO_EXPIRED;
    				gettimeofday(&tv, NULL);
    				imc_send_ping(r->name, tv.tv_sec, tv.tv_usec);
			}
		}
				
	}
  }

/* These 4 added by me for the auto-hub-swap -- Scion 1/9/99 */
  else if (!strcasecmp(p->type, "inforequest")) /* Request connection info from all 1.00a hubs -- Scion */
    imc_recv_inforequest(p->from); /* Had to use inforequest because 0.10 responds to info-request :) */
  else if (!strcasecmp(p->type, "info-reply")) /* receive the reply from the inforequest :) -- Scion */
	imc_recv_info_reply(p->from, imc_getkey(&p->data, "hub", "no"), imc_getkeyi(&p->data, "direct", -1));
  
  else if (!strcasecmp(p->type, "switch-reply")) /* hub confirmed that it added a connection to us. -- Scion */
	  imc_autoconnect_reply_accept(    /* Add a connection back to the hub */
	  p->from,      
	  imc_getkey(&p->data, "host", "!!!"), 
	  imc_getkeyi(&p->data, "port", -1),
	  imc_getkey(&p->data, "clientpw", "password"), 
	  imc_getkey(&p->data, "serverpw", "password"), 
	  imc_getkeyi(&p->data, "rcvstamp", 0), 
	  imc_getkeyi(&p->data, "noforward", 0), 
	  imc_getkey(&p->data, "flags", "none"),
	  imc_getkey(&p->data, "localname", "!!!"),
	  imc_getkey(&p->data, "confirm", "not accepted")
	  );
  else if (!strcasecmp(p->type, "imc-switch")) /* hub receives request to add a connection -- Scion */
	  imc_recv_autoconnect(
	  p->from, 
	  imc_getkey(&p->data, "host", "!!!"), 
	  imc_getkeyi(&p->data, "port", -1),
	  imc_getkey(&p->data, "clientpw", "password"), 
	  imc_getkey(&p->data, "serverpw", "password"), 
	  imc_getkeyi(&p->data, "rcvstamp", 0), 
	  imc_getkeyi(&p->data, "noforward", 0), 
	  imc_getkey(&p->data, "flags", "none"),
	  imc_getkey(&p->data, "localname", "!!!")
	  );
/* call catch-all fn if present */
  else
  {
    imc_packet out;

	if (imc_recv_hook)
      if ((*imc_recv_hook)(p, bcast))
	return;

    if (bcast || !strcasecmp(p->type, "reject"))
      return;
    
    /* reject packet */
      if (!imc_is_router)
    { 
    strcpy(out.type, "reject");
    strcpy(out.to, p->from);
    strcpy(out.from, p->to);

    imc_clonedata(&p->data, &out.data);
    imc_addkey(&out.data, "old-type", p->type);

    imc_send(&out);
    imc_freedata(&out.data);
    }
  }
}
示例#18
0
文件: imc-interp.c 项目: bkero/Smaug
/* add the mud to our list if we're a hub, and reply with our info. -- Scion*/
void imc_recv_autoconnect(const char *to, const char *rhost, int rport, 
	const char *rclientpw, const char *rserverpw, 
  	int rrcvstamp, int rnoforward, const char *rflags, 
	const char *remotename)
{
  imc_packet out;
  char no_port[IMC_MNAME_LENGTH];

  int a=0,b=0;

  imc_info *i,*o;

   if (imc_active<IA_UP)
    return;


  /* Receive all this info: -- Scion 
	 imc set <mudname> all <host> <port> <clientpw> <serverpw> <rcvstamp> <noforward> <flags>
		*/
#ifdef NO_OPTIMIZE
   imc_logstring("Autoconnect refused because NO_OPTIMIZE is defined.");
   return;
#endif
  
  if (imc_name && !strcasecmp(remotename, imc_name)) {
	  imc_logstring("Autoconnect attempt allegedly from this server! Ignoring.");
      return; /* Hey! That's our name! */
  }
	  
  /* Get that pesky port out of the host name */
  for (a=0;a<strlen(imc_siteinfo.host); a++) {
	  if (imc_siteinfo.host[a]==':'
	  || imc_siteinfo.host[a]==' ') 
 	  {
		  break;
	  }
	  no_port[b++]=imc_siteinfo.host[a];
	  no_port[b]='\0';
  }
  /* Send our information back to the MUD */
  imc_initdata(&out.data);
  strcpy(out.type, "switch-reply");
  strcpy(out.from, "*");
  strcpy(out.to, "*@");
  imc_sncpy(out.to+2, remotename, IMC_MNAME_LENGTH-2);
  
  imc_addkey(&out.data, "confirm", "connection added");
  imc_addkey(&out.data, "host", no_port); /* don't put the port number in from imc_siteinfo.host b/c it's the game port */
  imc_addkeyi(&out.data, "port", (int)imc_port);
  imc_addkey(&out.data, "clientpw", rclientpw);
  imc_addkey(&out.data, "serverpw", rserverpw);
  imc_addkeyi(&out.data, "rcvstamp", 0);
  imc_addkeyi(&out.data, "noforward", 0);
  imc_addkey(&out.data, "flags", "none");
  imc_addkey(&out.data, "localname", imc_name);
  
  imc_send(&out);
  
  imc_freedata(&out.data); 
  
  /* Setup the new connection... */
  if((o=imc_getinfo(remotename))) /* remove old entries - shogar */
  {
  	i=imc_insert_info();
        i->connection=o->connection;
        i->flags=o->flags;
        if (i->connection) i->connection->info=i;
  	imc_cancel_info(o); 
  }
  else
  {
  	i=imc_insert_info();
        i->flags = imc_flagvalue("new", imc_connection_flags); /* Hubs don't need specific flags really */
  }


  i->name       = imc_strdup(remotename);
  i->host       = imc_strdup(rhost);
  i->port       = (unsigned short)rport;
  i->clientpw   = imc_strdup(rclientpw);
  i->serverpw   = imc_strdup(rserverpw);
  i->rcvstamp   = rrcvstamp;
  i->noforward  = rnoforward;
  i->connect_attempts = 0;


  imc_saveconfig();
  /* All done! */
  
  imc_logstring("Autoconnect accepted from %s", to);


}
示例#19
0
文件: imc.c 项目: bkero/Smaug
/* start up listening port */
void imc_startup_port(void)
{
  int i;
  struct sockaddr_in sa;

  if (imc_active!=IA_UP)
  {
    imc_logerror("imc_startup_port: called with imc_active=%d", imc_active);
    return;
  }

  if (imc_port==0)
  {
    imc_logerror("imc_startup_port: called with imc_port=0");
    return;
  }
  
  imc_logstring("binding port %d for incoming connections", imc_port);
      
  control = socket(AF_INET, SOCK_STREAM, 0);
  if (control<0)
  {
    imc_lerror("imc_startup_port: socket");
    return;
  }
    
  i=1;
  if (setsockopt(control, SOL_SOCKET, SO_REUSEADDR, (void *)&i,
		 sizeof(i))<0)
  {
    imc_lerror("imc_startup_port: SO_REUSEADDR");
    close(control);
    return;
  }
  
  if ((i=fcntl(control, F_GETFL, 0))<0)
  {
    imc_lerror("imc_startup_port: fcntl(F_GETFL)");
    close(control);
    return;
  }

  if (fcntl(control, F_SETFL, i | O_NONBLOCK)<0)
  {
    imc_lerror("imc_startup_port: fcntl(F_SETFL)");
    close(control);
    return;
  }

  sa.sin_family      = AF_INET;
  sa.sin_port        = htons(imc_port);
  sa.sin_addr.s_addr = imc_bind; /* already in network order */
  
  if (bind(control, (struct sockaddr *)&sa, sizeof(sa))<0)
  {
    imc_lerror("imc_startup_port: bind");
    close(control);
    return;
  }
  
  if (listen(control, 1)<0)
  {
    imc_lerror("imc_startup_port: listen");
    close(control);
    return;
  }
  
  imc_active=IA_LISTENING;
}
示例#20
0
文件: imc.c 项目: bkero/Smaug
/* connect to given mud */
int imc_connect_to(const char *mud)
{
  imc_info *i;
  imc_connect *c;
  int desc;
  struct sockaddr_in sa;
  char buf[IMC_DATA_LENGTH];
  int r;

  if (imc_active == IA_NONE)
  {
    imc_qerror("IMC is not active");
    return 0;
  }
    
  i=imc_getinfo(mud);
  if (!i)
  {
    imc_qerror("%s: unknown mud name", mud);
    return 0;
  }

  if (i->connection)
  {
    imc_qerror("%s: already connected", mud);
    return 0;
  }

  if (i->flags & IMC_CLIENT)
  {
    imc_qerror("%s: client-only flag is set", mud);
    return 0;
  }

  if (i->flags & IMC_DENY)
  {
    imc_qerror("%s: deny flag is set", mud);
    return 0;
  }

  if (!(i->flags & IMC_QUIET))
    imc_logstring("connect to %s", mud);

  /*  warning: this blocks. It would be better to farm the query out to
   *  another process, but that is difficult to do without lots of changes
   *  to the core mud code. You may want to change this code if you have an
   *  existing resolver process running.
   */

  if ((sa.sin_addr.s_addr=inet_addr(i->host)) == -1UL)
  {
    struct hostent *hostinfo;

    if (NULL == (hostinfo=gethostbyname(i->host)))
    {
      imc_logerror("imc_connect: couldn't resolve hostname");
      return 0;
    }

    sa.sin_addr.s_addr = *(unsigned long *) hostinfo->h_addr;
  }

  sa.sin_port   = htons(i->port);
  sa.sin_family = AF_INET;

  desc=socket(AF_INET, SOCK_STREAM, 0);
  if (desc<0)
  {
    imc_lerror("socket");
    return 0;
  }

  r=fcntl(desc, F_GETFL, 0);
  if (r<0 || fcntl(desc, F_SETFL, O_NONBLOCK | r)<0)
  {
    imc_lerror("imc_connect: fcntl");
    close(desc);
    return 0;
  }

  if (connect(desc, (struct sockaddr *)&sa, sizeof(sa))<0)
    if (errno != EINPROGRESS)
    {
      imc_lerror("connect");
      close(desc);
      return 0;
    }

  c=imc_new_connect();

  c->desc     = desc;
  c->state    = IMC_CONNECTING;
  c->info     = i;

  imc_add_event(IMC_LOGIN_TIMEOUT, ev_login_timeout, c, 1);

  sprintf(buf, "PW %s %s version=%d",
	  imc_name,
	  i->clientpw,
	  IMC_VERSION);
  do_send(c, buf);

  return 1;
}
示例#21
0
文件: imc.c 项目: bkero/Smaug
void imc_shutdown_network(void)
{
  imc_event *ev, *ev_next;
  imc_connect *c, *c_next;
  imc_reminfo *p, *pnext;

  if (imc_active < IA_UP)
  {
    imc_logerror("imc_shutdown_network: called with imc_active==%d",
		 imc_active);
    return;
  }

  if (imc_lock)
  {
    imc_logerror("imc_shutdown_network: called from within imc_idle_select");
    return;
  }

  imc_logstring("shutting down network");

  if (imc_active == IA_LISTENING)
    imc_shutdown_port();

  imc_logstring("rx %ld packets, %ld bytes (%ld/second)",
		imc_stats.rx_pkts,
		imc_stats.rx_bytes,
		(imc_now == imc_stats.start) ? 0 :
		imc_stats.rx_bytes / (imc_now - imc_stats.start));
  imc_logstring("tx %ld packets, %ld bytes (%ld/second)",
		imc_stats.tx_pkts,
		imc_stats.tx_bytes,
		(imc_now == imc_stats.start) ? 0 :
		imc_stats.tx_bytes / (imc_now - imc_stats.start));
  imc_logstring("largest packet %d bytes", imc_stats.max_pkt);
  imc_logstring("dropped %d packets by sequence number",
                imc_stats.sequence_drops);

  imc_mail_shutdown();

  for (c=imc_connect_list; c; c=c_next)
  {
    c_next=c->next;
    do_close(c);
    imc_extract_connect(c);
  }
  imc_connect_list=NULL; 
  if(!imc_is_router)
  	icec_shutdown();
  for (p=imc_reminfo_list; p; p=pnext)
  {
    pnext=p->next;
    imc_strfree(p->version);
    imc_strfree(p->name);
    if(p->path) imc_strfree(p->path); 
    imc_free(p, sizeof(imc_reminfo));
  }
  imc_reminfo_list=NULL;

  for (ev=imc_event_list; ev; ev=ev_next)
  {
    ev_next=ev->next;
    imc_free(ev, sizeof(imc_event));
  }
  for (ev=imc_event_free; ev; ev=ev_next)
  {
    ev_next=ev->next;
    imc_free(ev, sizeof(imc_event));
  }
  imc_event_list=imc_event_free=NULL;

  unlock_prefix();

  imc_active=IA_CONFIG2;
}
示例#22
0
文件: imc.c 项目: bkero/Smaug
/* start up IMC */
void imc_startup_network(void)
{
    imc_info *info;
	int toggle=0; /* This is to tell after we've done reconnects if we've connected to a hub or not -- Scion */

  if (imc_active != IA_CONFIG2)
  {
    imc_logerror("imc_startup_network: called with imc_active==%d",
		 imc_active);
    return;
  }

  if (!imc_siteinfo.name[0])
  {
    imc_logerror("InfoName not set, not initializing");
    return;
  }

  if (!imc_siteinfo.email[0])
  {
    imc_logerror("InfoEmail not set, not initializing");
    return;
  }
  
  imc_logstring("network initializing");

  imc_active=IA_UP;

  control=-1;

  if (imc_port)
    imc_startup_port();
  imc_stats.start    = imc_now;
  imc_stats.rx_pkts  = 0;
  imc_stats.tx_pkts  = 0;
  imc_stats.rx_bytes = 0;
  imc_stats.tx_bytes = 0;
  imc_stats.sequence_drops = 0;

  imc_add_event(20, ev_keepalive, NULL, 1);
  /* fill my imclist please - shogar */
  imc_add_event(30, ev_request_keepalive, NULL, 1);

  imc_mail_startup();		/* start up the mailer */

  if (!lock_prefix())
  {
    imc_logstring("another process is using the same config prefix, not autoconnecting.");
    return;
  }

  /* do autoconnects */
  for (info=imc_info_list; info; info=info->next)
    if (!(info->flags & IMC_NOAUTO) && !(info->flags & IMC_CLIENT) 
		&& !(info->flags & IMC_DENY) 
 /*               && !(info->flags & IMC_OLD_HUB)  not used anymore - shogar
                && !(info->flags & IMC_DEAD_HUB)
*/
		&& !(info->flags & IMC_HUB)) {
      if (imc_connect_to(info->name) && ((info->flags & IMC_MAIN_HUB) || (info->flags & IMC_HUB)))
		  toggle=1;
	}

  
	/* Setup optimization to run, it won't if we're a hub -- Scion */
   if(imc_hubswitch && !imc_is_router)
   {
   	imc_add_event(360, ev_imc_pollforhub, NULL, 1);
   	imc_add_event(420, ev_imc_optimize, NULL, 1);

   	imc_logstring("Setting auto-optimize to run in 6 minutes.");
   }

   /* Are we connected to any hubs, btw? -- Scion */

   if (!toggle) { /* No hubs connected! */
	   for (info=imc_info_list; info; info=info->next)
		   if ((info->flags & IMC_HUB) && (!toggle))
			   if (imc_connect_to(info->name))
				   toggle=0;
   }
   /* We're out of ideas, notify the admins -- Scion */
/*
   if (!toggle)
	   imc_logstring("No hubs connected! Check the configuration!");
*/
}