/* * udp_exec_pkt: passes the received udp packet to pkt_exec(). * `passed_argv' is a pointer to a udp_exec_pkt_argv struct */ void * udp_exec_pkt(void *passed_argv) { struct udp_exec_pkt_argv argv; PACKET rpkt; const char *ntop; memcpy(&argv, passed_argv, sizeof(struct udp_exec_pkt_argv)); memcpy(&rpkt, argv.recv_pkt, sizeof(PACKET)); if (argv.flags & UDP_THREAD_FOR_EACH_PKT) pthread_mutex_unlock(&udp_exec_lock); /* Drop any packet we sent in broadcast */ if (!memcmp(rpkt.from.data, me.cur_ip.data, MAX_IP_SZ)) { pkt_free(&rpkt, 0); return 0; } if (add_accept(rpkt.from, 1)) { ntop = inet_to_str(rpkt.from); debug(DBG_NORMAL, "ACPT: dropped UDP pkt from %s: " "Accept table full.", ntop); return 0; } pkt_exec(rpkt, argv.acpt_idx); pkt_free(&rpkt, 0); return 0; }
void finish_rule(int mach, int variable_trail_rule, int headcnt, int trailcnt) { add_accept( mach, num_rules ); /* we did this in new_rule(), but it often gets the wrong * number because we do it before we start parsing the current rule */ rule_linenum[num_rules] = linenum; /* if this is a continued action, then the line-number has * already been updated, giving us the wrong number */ if ( continued_action ) --rule_linenum[num_rules]; fprintf( temp_action_file, "case %d:\n", num_rules ); if ( variable_trail_rule ) { rule_type[num_rules] = RULE_VARIABLE; if ( performance_report ) fprintf( stderr, "Variable trailing context rule at line %d\n", rule_linenum[num_rules] ); variable_trailing_context_rules = true; } else { rule_type[num_rules] = RULE_NORMAL; if ( headcnt > 0 || trailcnt > 0 ) { /* do trailing context magic to not match the trailing characters */ char *scanner_cp = "yy_c_buf_p = yy_cp"; char *scanner_bp = "yy_bp"; fprintf( temp_action_file, "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" ); if ( headcnt > 0 ) fprintf( temp_action_file, "%s = %s + %d;\n", scanner_cp, scanner_bp, headcnt ); else fprintf( temp_action_file, "%s -= %d;\n", scanner_cp, trailcnt ); fprintf( temp_action_file, "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" ); } } line_directive_out( temp_action_file ); }
void * tcp_daemon(void *door) { pthread_t thread; pthread_attr_t t_attr; PACKET rpkt; struct sockaddr_storage addr; socklen_t addrlen = sizeof addr; inet_prefix ip; fd_set fdset; int fd, ret, err, i; interface *ifs; int max_sk_idx, dev_sk[me.cur_ifs_n]; u_short tcp_port = *(u_short *) door; const char *ntop; pthread_attr_init(&t_attr); pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED); debug(DBG_SOFT, "Preparing the tcp listening socket on port %d", tcp_port); err = sockets_all_ifs(my_family, SOCK_STREAM, tcp_port, me.cur_ifs, me.cur_ifs_n, dev_sk, &max_sk_idx); if (!err) return NULL; else if (err < 0) fatal("Creation of the %s daemon aborted. " "Is there another ntkd running?", "tcp"); pthread_mutex_init(&tcp_exec_lock, 0); for (i = 0; i < me.cur_ifs_n; i++) { if (!dev_sk[i]) continue; /* * While we are accepting the connections we keep the socket non * blocking. */ if (set_nonblock_sk(dev_sk[i])) { pthread_mutex_unlock(&tcp_daemon_lock); return NULL; } /* Shhh, it's listening... */ if (listen(dev_sk[i], 5) == -1) { inet_close(&dev_sk[i]); pthread_mutex_unlock(&tcp_daemon_lock); return NULL; } } debug(DBG_NORMAL, "Tcp daemon on port %d up & running", tcp_port); pthread_mutex_unlock(&tcp_daemon_lock); for (;;) { FD_ZERO(&fdset); if (!me.cur_ifs_n) { /* All the devices have been removed while ntkd was * running, sleep well */ sleep(1); continue; } for (i = 0; i < me.cur_ifs_n; i++) if (dev_sk[i]) FD_SET(dev_sk[i], &fdset); ret = select(dev_sk[max_sk_idx] + 1, &fdset, NULL, NULL, NULL); if (sigterm_timestamp) /* NetsukukuD has been closed */ break; if (ret < 0 && errno != EINTR) error("daemon_tcp: select error: %s", strerror(errno)); if (ret < 0) continue; for (i = 0; i < me.cur_ifs_n; i++) { ifs = &me.cur_ifs[i]; if (!dev_sk[i]) continue; if (!FD_ISSET(dev_sk[i], &fdset)) continue; fd = accept(dev_sk[i], (struct sockaddr *) &addr, &addrlen); if (fd == -1) { if (errno != EINTR && errno != EWOULDBLOCK) error("daemon_tcp: accept(): %s", strerror(errno)); continue; } setzero(&rpkt, sizeof(PACKET)); pkt_addsk(&rpkt, my_family, fd, SKT_TCP); pkt_add_dev(&rpkt, ifs, 0); rpkt.flags = MSG_WAITALL; pkt_addport(&rpkt, tcp_port); ntop = 0; sockaddr_to_inet((struct sockaddr *) &addr, &ip, 0); pkt_addfrom(&rpkt, &ip); if (server_opt.dbg_lvl) ntop = inet_to_str(ip); if ((ret = add_accept(ip, 0))) { debug(DBG_NORMAL, "ACPT: drop connection with %s: " "Accept table full.", ntop); /* Omg, we cannot take it anymore, go away: ACK_NEGATIVE */ pkt_err(rpkt, ret, 1); inet_close(&fd); continue; } else { /* * Ok, the connection is good, send back the * ACK_AFFERMATIVE. */ pkt_addto(&rpkt, &rpkt.from); send_rq(&rpkt, 0, ACK_AFFERMATIVE, 0, 0, 0, 0); } if (unset_nonblock_sk(fd)) continue; pthread_mutex_lock(&tcp_exec_lock); err = pthread_create(&thread, &t_attr, tcp_recv_loop, (void *) &rpkt); pthread_detach(thread); pthread_mutex_lock(&tcp_exec_lock); pthread_mutex_unlock(&tcp_exec_lock); } } return NULL; }
/* * m_accept - ACCEPT command handler * parv[0] = sender prefix * parv[1] = servername */ static void m_accept(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char *nick; char *p = NULL; static char addbuf[BUFSIZE]; static char delbuf[BUFSIZE]; struct Client *target_p; int accept_num; if(*parv[1] == '*') { list_accepts(source_p); return; } build_nicklist(source_p, addbuf, delbuf, parv[1]); /* parse the delete list */ for(nick = strtoken(&p, delbuf, ","); nick != NULL; nick = strtoken(&p, NULL, ",")) { /* shouldnt happen, but lets be paranoid */ if(((target_p = find_client(nick)) == NULL) || !IsPerson(target_p)) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, nick); continue; } /* user isnt on clients accept list */ if(!accept_message(target_p, source_p)) { sendto_one(source_p, form_str(ERR_ACCEPTNOT), me.name, source_p->name, target_p->name); continue; } del_from_accept(target_p, source_p); } /* get the number of accepts they have */ accept_num = dlink_list_length(&source_p->allow_list); /* parse the add list */ for(nick = strtoken(&p, addbuf, ","); nick; nick = strtoken(&p, NULL, ","), accept_num++) { /* shouldnt happen, but lets be paranoid */ if(((target_p = find_client(nick)) == NULL) || !IsPerson(target_p)) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, nick); continue; } /* user is already on clients accept list */ if(accept_message(target_p, source_p)) { sendto_one(source_p, form_str(ERR_ACCEPTEXIST), me.name, source_p->name, target_p->name); continue; } if(accept_num >= ConfigFileEntry.max_accept) { sendto_one(source_p, form_str(ERR_ACCEPTFULL), me.name, source_p->name); return; } /* why is this here? */ /* del_from accept(target_p, source_p); */ add_accept(source_p, target_p); } }
/* finish_rule - finish up the processing for a rule * * An accepting number is added to the given machine. If variable_trail_rule * is true then the rule has trailing context and both the head and trail * are variable size. Otherwise if headcnt or trailcnt is non-zero then * the machine recognizes a pattern with trailing context and headcnt is * the number of characters in the matched part of the pattern, or zero * if the matched part has variable length. trailcnt is the number of * trailing context characters in the pattern, or zero if the trailing * context has variable length. */ void finish_rule(int mach, int variable_trail_rule, int headcnt, int trailcnt) { char action_text[MAXLINE]; add_accept(mach, num_rules); /* We did this in new_rule(), but it often gets the wrong * number because we do it before we start parsing the current rule. */ rule_linenum[num_rules] = linenum; /* If this is a continued action, then the line-number has already * been updated, giving us the wrong number. */ if (continued_action) --rule_linenum[num_rules]; sprintf(action_text, "case %d:\n", num_rules); add_ind_action(2, action_text); if (variable_trail_rule) { rule_type[num_rules] = RULE_VARIABLE; if (performance_report > 0) fprintf(stderr, _("Variable trailing context rule at line %d\n"), rule_linenum[num_rules]); variable_trailing_context_rules = true; } else { rule_type[num_rules] = RULE_NORMAL; if (headcnt > 0 || trailcnt > 0) { /* Do trailing context magic to not match the trailing * characters. */ const char *scanner_cp = "yy_c_buf_p = yy_cp"; const char *scanner_bp = "yy_bp"; add_ind_action(3, "*yy_cp = yy_hold_char;\t/* undo effects of setting up yytext */\n"); if (headcnt > 0) { sprintf(action_text, "%s = %s + %d;\n", scanner_cp, scanner_bp, headcnt); add_ind_action(3, action_text); } else { sprintf(action_text, "%s -= %d;\n", scanner_cp, trailcnt); add_ind_action(3, action_text); } add_ind_action(3, "YY_DO_BEFORE_ACTION;\t/* set up yytext again */\n"); } } /* Okay, in the action code at this point yytext and yyleng have * their proper final values for this rule, so here's the point * to do any user action. But don't do it for continued actions, * as that'll result in multiple YY_RULE_SETUP's. */ if (!continued_action) add_ind_action(3, "YY_RULE_SETUP\n"); line_directive_out((FILE *) 0, 1); }