示例#1
0
int main(int argc, char **argv)
{
	bool fork_desired = TRUE;
	bool log_to_stderr_desired = FALSE;
	bool nat_traversal = FALSE;
	bool nat_t_spf = TRUE;  /* support port floating */
	unsigned int keep_alive = 0;
	bool force_keepalive = FALSE;
	char *virtual_private = NULL;
	int lockfd;
#ifdef CAPABILITIES
	cap_t caps;
	int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */

	/* initialize library and optionsfrom */
	if (!library_init(NULL))
	{
		library_deinit();
		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
	}
	if (!libhydra_init("pluto"))
	{
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	if (!pluto_init(argv[0]))
	{
		pluto_deinit();
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_DAEMON_INTEGRITY);
	}
	options = options_create();

	ha_mcast_addr.s_addr = inet_addr(SA_SYNC_MULTICAST);

	/* handle arguments */
	for (;;)
	{
#       define DBG_OFFSET 256
		static const struct option long_opts[] = {
			/* name, has_arg, flag, val */
			{ "help", no_argument, NULL, 'h' },
			{ "version", no_argument, NULL, 'v' },
			{ "optionsfrom", required_argument, NULL, '+' },
			{ "nofork", no_argument, NULL, 'd' },
			{ "stderrlog", no_argument, NULL, 'e' },
			{ "noklips", no_argument, NULL, 'n' },
			{ "nocrsend", no_argument, NULL, 'c' },
			{ "strictcrlpolicy", no_argument, NULL, 'r' },
			{ "crlcheckinterval", required_argument, NULL, 'x'},
			{ "cachecrls", no_argument, NULL, 'C' },
			{ "probe-psk", no_argument, NULL, 'o' },
			{ "uniqueids", no_argument, NULL, 'u' },
			{ "interface", required_argument, NULL, 'i' },
			{ "ha_interface", required_argument, NULL, 'H' },
			{ "ha_multicast", required_argument, NULL, 'M' },
			{ "ha_vips", required_argument, NULL, 'V' },
			{ "ha_seqdiff_in", required_argument, NULL, 'S' },
			{ "ha_seqdiff_out", required_argument, NULL, 'O' },
			{ "ikeport", required_argument, NULL, 'p' },
			{ "ctlbase", required_argument, NULL, 'b' },
			{ "secretsfile", required_argument, NULL, 's' },
			{ "foodgroupsdir", required_argument, NULL, 'f' },
			{ "perpeerlogbase", required_argument, NULL, 'P' },
			{ "perpeerlog", no_argument, NULL, 'l' },
			{ "policygroupsdir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
			{ "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
			{ "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
			{ "pkcs11module", required_argument, NULL, 'm' },
			{ "pkcs11keepstate", no_argument, NULL, 'k' },
			{ "pkcs11initargs", required_argument, NULL, 'z' },
			{ "pkcs11proxy", no_argument, NULL, 'y' },
			{ "nat_traversal", no_argument, NULL, '1' },
			{ "keep_alive", required_argument, NULL, '2' },
			{ "force_keepalive", no_argument, NULL, '3' },
			{ "disable_port_floating", no_argument, NULL, '4' },
			{ "debug-natt", no_argument, NULL, '5' },
			{ "virtual_private", required_argument, NULL, '6' },
#ifdef DEBUG
			{ "debug-none", no_argument, NULL, 'N' },
			{ "debug-all", no_argument, NULL, 'A' },
			{ "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
			{ "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
			{ "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
			{ "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
			{ "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
			{ "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
			{ "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
			{ "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
			{ "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
			{ "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
			{ "debug-ha", no_argument, NULL, DBG_HA + DBG_OFFSET },
			{ "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },

			{ "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
			{ "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
			{ "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
			{ "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
#endif
			{ 0,0,0,0 }
			};
		/* Note: we don't like the way short options get parsed
		 * by getopt_long, so we simply pass an empty string as
		 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
		 */
		int c = getopt_long(argc, argv, "", long_opts, NULL);

		/* Note: "breaking" from case terminates loop */
		switch (c)
		{
		case EOF:       /* end of flags */
			break;

		case 0: /* long option already handled */
			continue;

		case ':':       /* diagnostic already printed by getopt_long */
		case '?':       /* diagnostic already printed by getopt_long */
			usage("");
			break;   /* not actually reached */

		case 'h':       /* --help */
			usage(NULL);
			break;      /* not actually reached */

		case 'v':       /* --version */
			{
				const char **sp = ipsec_copyright_notice();

				printf("strongSwan "VERSION"%s\n", compile_time_interop_options);
				for (; *sp != NULL; sp++)
					puts(*sp);
			}
			exit_pluto(0);
			break;      /* not actually reached */

		case '+':       /* --optionsfrom <filename> */
			if (!options->from(options, optarg, &argc, &argv, optind))
			{
				exit_pluto(1);
			}
			continue;

		case 'd':       /* --nofork*/
			fork_desired = FALSE;
			continue;

		case 'e':       /* --stderrlog */
			log_to_stderr_desired = TRUE;
			continue;

		case 'n':       /* --noklips */
			no_klips = TRUE;
			continue;

		case 'c':       /* --nocrsend */
			no_cr_send = TRUE;
			continue;

		case 'r':       /* --strictcrlpolicy */
			strict_crl_policy = TRUE;
			continue;

		case 'x':       /* --crlcheckinterval <time>*/
			if (optarg == NULL || !isdigit(optarg[0]))
				usage("missing interval time");

			{
				char *endptr;
				long interval = strtol(optarg, &endptr, 0);

				if (*endptr != '\0' || endptr == optarg
				|| interval <= 0)
					usage("<interval-time> must be a positive number");
				crl_check_interval = interval;
			}
			continue;

		case 'C':       /* --cachecrls */
			cache_crls = TRUE;
			continue;

		case 'o':       /* --probe-psk */
			probe_psk = TRUE;
			continue;

		case 'u':       /* --uniqueids */
			uniqueIDs = TRUE;
			continue;

		case 'i':       /* --interface <ifname> */
			if (!use_interface(optarg))
				usage("too many --interface specifications");
			continue;

		case 'H':       /* --ha_interface <ifname> */
			if (optarg && strcmp(optarg, "none") != 0)
				ha_interface = optarg;
			continue;

		case 'M':	/* --ha_multicast <ip> */
			ha_mcast_addr.s_addr = inet_addr(optarg);
			if (ha_mcast_addr.s_addr == INADDR_NONE ||
				(((unsigned char *) &ha_mcast_addr.s_addr)[0] & 0xF0) != 0xE0)
				ha_mcast_addr.s_addr = inet_addr(SA_SYNC_MULTICAST);
			continue;

		case 'V':	/* --ha_vips <ip addresses> */
			if(add_ha_vips(optarg))
				usage("misconfigured ha_vip addresses");
			continue;

		case 'S':	/* --ha_seqdiff_in <diff> */
			ha_seqdiff_in = strtoul(optarg, NULL, 0);
			continue;

		case 'O':       /* --ha_seqdiff_out <diff> */
			ha_seqdiff_out = strtoul(optarg, NULL, 0);
			continue;

		case 'p':       /* --port <portnumber> */
			if (optarg == NULL || !isdigit(optarg[0]))
				usage("missing port number");

			{
				char *endptr;
				long port = strtol(optarg, &endptr, 0);

				if (*endptr != '\0' || endptr == optarg
				|| port <= 0 || port > 0x10000)
					usage("<port-number> must be a number between 1 and 65535");
				pluto_port = port;
			}
			continue;

		case 'b':       /* --ctlbase <path> */
			if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
			, "%s%s", optarg, CTL_SUFFIX) == -1)
				usage("<path>" CTL_SUFFIX " too long for sun_path");
			if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
			, "%s%s", optarg, INFO_SUFFIX) == -1)
				usage("<path>" INFO_SUFFIX " too long for sun_path");
			if (snprintf(pluto_lock, sizeof(pluto_lock)
			, "%s%s", optarg, LOCK_SUFFIX) == -1)
				usage("<path>" LOCK_SUFFIX " must fit");
			continue;

		case 's':       /* --secretsfile <secrets-file> */
			shared_secrets_file = optarg;
			continue;

		case 'f':       /* --policygroupsdir <policygroups-dir> */
			policygroups_dir = optarg;
			continue;

		case 'a':       /* --adns <pathname> */
			pluto_adns_option = optarg;
			continue;

		case 'm':       /* --pkcs11module <pathname> */
			pkcs11_module_path = optarg;
			continue;

		case 'k':       /* --pkcs11keepstate */
			pkcs11_keep_state = TRUE;
			continue;

		case 'y':       /* --pkcs11proxy */
			pkcs11_proxy = TRUE;
			continue;

		case 'z':       /* --pkcs11initargs */
			pkcs11_init_args = optarg;
			continue;

#ifdef DEBUG
		case 'N':       /* --debug-none */
			base_debugging = DBG_NONE;
			continue;

		case 'A':       /* --debug-all */
			base_debugging = DBG_ALL;
			continue;
#endif

		case 'P':       /* --perpeerlogbase */
			base_perpeer_logdir = optarg;
			continue;

		case 'l':
			log_to_perpeer = TRUE;
			continue;

		case '1':       /* --nat_traversal */
			nat_traversal = TRUE;
			continue;
		case '2':       /* --keep_alive */
			keep_alive = atoi(optarg);
			continue;
		case '3':       /* --force_keepalive */
			force_keepalive = TRUE;
			continue;
		case '4':       /* --disable_port_floating */
			nat_t_spf = FALSE;
			continue;
		case '5':       /* --debug-nat_t */
			base_debugging |= DBG_NATT;
			continue;
		case '6':       /* --virtual_private */
			virtual_private = optarg;
			continue;

		default:
#ifdef DEBUG
			if (c >= DBG_OFFSET)
			{
				base_debugging |= c - DBG_OFFSET;
				continue;
			}
#       undef DBG_OFFSET
#endif
			bad_case(c);
		}
		break;
	}
	if (optind != argc)
		usage("unexpected argument");
	reset_debugging();
	lockfd = create_lock();

	/* select between logging methods */

	if (log_to_stderr_desired)
	{
		log_to_syslog = FALSE;
	}
	else
	{
		log_to_stderr = FALSE;
	}

	/* set the logging function of pfkey debugging */
#ifdef DEBUG
	pfkey_debug_func = DBG_log;
#else
	pfkey_debug_func = NULL;
#endif

	/* create control socket.
	 * We must create it before the parent process returns so that
	 * there will be no race condition in using it.  The easiest
	 * place to do this is before the daemon fork.
	 */
	{
		err_t ugh = init_ctl_socket();

		if (ugh != NULL)
		{
			fprintf(stderr, "pluto: %s", ugh);
			exit_pluto(1);
		}
	}

	/* If not suppressed, do daemon fork */

	if (fork_desired)
	{
		{
			pid_t pid = fork();

			if (pid < 0)
			{
				int e = errno;

				fprintf(stderr, "pluto: fork failed (%d %s)\n",
					errno, strerror(e));
				exit_pluto(1);
			}

			if (pid != 0)
			{
				/* parent: die, after filling PID into lock file.
				 * must not use exit_pluto: lock would be removed!
				 */
				exit(fill_lock(lockfd, pid)? 0 : 1);
			}
		}

		if (setsid() < 0)
		{
			int e = errno;

			fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
				errno, strerror(e));
			exit_pluto(1);
		}
	}
	else
	{
		/* no daemon fork: we have to fill in lock file */
		(void) fill_lock(lockfd, getpid());
		fprintf(stdout, "Pluto initialized\n");
		fflush(stdout);
	}

	/* Close everything but ctl_fd and (if needed) stderr.
	 * There is some danger that a library that we don't know
	 * about is using some fd that we don't know about.
	 * I guess we'll soon find out.
	 */
	{
		int i;

		for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
		{
			if ((!log_to_stderr || i != 2) && i != ctl_fd)
				close(i);
		}

		/* make sure that stdin, stdout, stderr are reserved */
		if (open("/dev/null", O_RDONLY) != 0)
			abort();
		if (dup2(0, 1) != 1)
			abort();
		if (!log_to_stderr && dup2(0, 2) != 2)
			abort();
	}

	init_constants();
	init_log("pluto");

	/* Note: some scripts may look for this exact message -- don't change
	 * ipsec barf was one, but it no longer does.
	 */
	plog("Starting IKEv1 pluto daemon (strongSwan "VERSION")%s",
		 compile_time_interop_options);

	if (lib->integrity)
	{
		plog("integrity tests enabled:");
		plog("lib    'libstrongswan': passed file and segment integrity tests");
		plog("lib    'libhydra': passed file and segment integrity tests");
		plog("daemon 'pluto': passed file integrity test");
	}

	/* load plugins, further infrastructure may need it */
	if (!lib->plugins->load(lib->plugins, NULL,
			lib->settings->get_str(lib->settings, "pluto.load", PLUGINS)))
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	print_plugins();

	init_builder();
	if (!init_secret() || !init_crypto())
	{
		plog("initialization failed - aborting pluto");
		exit_pluto(SS_RC_INITIALIZATION_FAILED);
	}
	init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
	init_virtual_ip(virtual_private);
	scx_init(pkcs11_module_path, pkcs11_init_args);
	init_states();
	init_demux();
	init_kernel();
	init_adns();
	init_myid();
	fetch_initialize();
	ac_initialize();
	whack_attribute_initialize();

	/* HA System: set sequence number delta and open HA interface */
	if (ha_interface != NULL)
	{
		int version;

		if (kernel_ops->type == KERNEL_TYPE_LINUX
		&& (version = xfrm_aevent_version()) != XFRM_AEVENT_VERSION)
		{
			if (version == 0)
				plog("HA system: XFRM sequence number updates only "
				     "supported with kernel version 2.6.17 and later.");
			else if (version == -1)
				plog("HA system: error reading kernel version. "
				     "Sequence number updates disabled.");
			else
				plog("HA system: Strongswan compiled for wrong kernel "
				     "AEVENT version! Please set XFRM_AEVENT_VERSION "
				     "to %d in src/include/linux/xfrm.h", version);

			ha_seqdiff_in = 0;
			ha_seqdiff_out = 0;
		}
		else
		{
			FILE *etime = fopen("/proc/sys/net/core/xfrm_aevent_etime", "w");
			FILE *rseqth = fopen("/proc/sys/net/core/xfrm_aevent_rseqth", "w");

			if (etime == NULL || rseqth == NULL)
			{
				plog("HA System: no sequence number support in Kernel! "
					"Please use at least kernel 2.6.17.");
				ha_seqdiff_in = 0;
				ha_seqdiff_out = 0;
			}
			else
			{
				/*
				 * Disable etime (otherwise set to a multiple of 100ms,
				 * e.g. 300 for 30 seconds). Using ha_seqdiff_out.
				 */
				fprintf(etime, "0");
				fprintf(rseqth, "%d", ha_seqdiff_out);
			}

			fclose(etime);
			fclose(rseqth);
		}

		if (open_ha_iface() >= 0)
		{
			plog("HA system enabled and listening on interface %s", ha_interface);
			if (access("/var/master", F_OK) == 0)
			{
				plog("Initial HA switch to master mode");
				ha_master = 1;
				event_schedule(EVENT_SA_SYNC_UPDATE, 30, NULL);
			}
		}
		else
		{
			plog("HA system failed to listen on interface %s. "
			     "HA system disabled.", ha_interface);
			ha_interface = NULL;
		}
	}

	/* drop unneeded capabilities and change UID/GID */
	prctl(PR_SET_KEEPCAPS, 1);

#ifdef IPSEC_GROUP
	{
		struct group group, *grp;
	char buf[1024];

		if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
				grp == NULL || setgid(grp->gr_gid) != 0)
		{
			plog("unable to change daemon group");
			abort();
		}
	}
#endif
#ifdef IPSEC_USER
	{
		struct passwd passwd, *pwp;
	char buf[1024];

		if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
				pwp == NULL || setuid(pwp->pw_uid) != 0)
		{
			plog("unable to change daemon user");
			abort();
		}
		}
#endif

#ifdef CAPABILITIES
	caps = cap_init();
	cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
	cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
	cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
	if (cap_set_proc(caps) != 0)
	{
		plog("unable to drop daemon capabilities");
		abort();
	}
	cap_free(caps);
#endif /* CAPABILITIES */

	/* loading X.509 CA certificates */
	load_authcerts("ca", CA_CERT_PATH, X509_CA);
	/* loading X.509 AA certificates */
	load_authcerts("aa", AA_CERT_PATH, X509_AA);
	/* loading X.509 OCSP certificates */
	load_authcerts("ocsp", OCSP_CERT_PATH, X509_OCSP_SIGNER);
	/* loading X.509 CRLs */
	load_crls();
	/* loading attribute certificates (experimental) */
	ac_load_certs();

	daily_log_event();
	call_server();
	return -1;  /* Shouldn't ever reach this */
}
示例#2
0
/**
 * DPD Out Initiator
 *
 * @param p2st A state struct that is already in phase2 
 * @return void
 */
static void
dpd_outI(struct state *p1st, struct state *st, bool eroute_care
	 ,time_t delay, time_t timeout)
{
    time_t tm;
    time_t last;
    u_int32_t seqno;
    bool   eroute_idle;
    time_t nextdelay;

    DBG(DBG_DPD, DBG_log("processing dpd for state #%lu (\"%s\")"
			 , st->st_serialno
			 , st->st_connection->name));

    /* If no DPD, then get out of here */
    if (!st->hidden_variables.st_dpd)
        return;

    /* If there is no state, there can be no DPD */         
    if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))
        return;
      
    /* find out when now is */
    tm = now();

    /*
     * pick least recent activity value, since with multiple phase 2s,
     * it may well be that one phase 2 is very active, while the other
     * for some reason, gets stomped upon by some network screw up.
     *
     * (this would only happen if the network was sensitive to different
     *  SPI#, since for NAT-T, all traffic should be on the same UDP port.
     *  At worst, this means that we send a bit more traffic then we need
     *  to when there are multiple SAs and one is much less active.
     *
     */
    last = (p1st->st_last_dpd > st->st_last_dpd
	    ? st->st_last_dpd : p1st->st_last_dpd );

    nextdelay = p1st->st_last_dpd + delay - tm;

    /* has there been enough activity of late? */
    if(nextdelay > 0) {
	/* Yes, just reschedule "phase 2" */
	DBG(DBG_DPD, DBG_log("not yet time for dpd event: %lu < %lu"
			     , (unsigned long)tm
			     , (unsigned long)(p1st->st_last_dpd + delay)));
	event_schedule(EVENT_DPD, nextdelay, st);
	return;
    }
      
    /* now plan next check time */
    if(nextdelay < 1) {
	nextdelay = delay;
    }

    /*
     * check the phase 2, if we are supposed to,
     * and return if it is active recently 
     */
    if(eroute_care && !st->hidden_variables.st_nat_traversal) {
      
	eroute_idle = was_eroute_idle(st, delay);
	if(!eroute_idle) {
	    DBG(DBG_DPD, DBG_log("dpd out event not sent, phase 2 active"));
	    
	    /* update phase 2 time stamp only */
	    st->st_last_dpd = tm;
	    
	    event_schedule(EVENT_DPD, nextdelay, st);
	    return;
	}
    }

    if(st != p1st) {
	/*
	 * reschedule next event, since we can not do it from the activity
	 * routine.
	 */
	event_schedule(EVENT_DPD, nextdelay, st); 
    }
        
    if (!p1st->st_dpd_seqno)
    {   
        /* Get a non-zero random value that has room to grow */
        get_rnd_bytes((u_char *)&p1st->st_dpd_seqno
		      , sizeof(p1st->st_dpd_seqno));
        p1st->st_dpd_seqno &= 0x7fff;
        p1st->st_dpd_seqno++;
    }    
    seqno = htonl(p1st->st_dpd_seqno);

    /* make sure that the timeout occurs. We do this before the send,
     * because the send may fail due to network issues, etc, and
     * the timeout has to occur anyway
     */
    dpd_sched_timeout(p1st, tm, timeout);

    DBG(DBG_DPD, DBG_log("sending R_U_THERE %u to %s:%d (state #%lu)"
			 , seqno
			 , ip_str(&p1st->st_remoteaddr)
			 , p1st->st_remoteport
			 , p1st->st_serialno));

    if (send_isakmp_notification(p1st, R_U_THERE
				 , &seqno, sizeof(seqno)) != STF_IGNORE)
    {   
        loglog(RC_LOG_SERIOUS, "DPD Error: could not send R_U_THERE");
        return;
    }
        
    st->st_last_dpd = tm;
    p1st->st_last_dpd = tm;
    p1st->st_dpd_expectseqno = p1st->st_dpd_seqno++;

}
示例#3
0
/**
 * DPD Timeout Function
 *
 * This function is called when a timeout DPD_EVENT occurs.  We set clear/trap
 * both the SA and the eroutes, depending on what the connection definition
 * tells us (either 'hold' or 'clear')
 *
 * @param st A state structure that is fully negotiated 
 * @return void
 */
void
dpd_timeout(struct state *st)
{
    int action;
    struct connection *c = st->st_connection;
    action = st->st_connection->dpd_action;
    
    /* probably wrong thing to assert here */
    passert(action == DPD_ACTION_HOLD
	    || action == DPD_ACTION_CLEAR
	    || action == DPD_ACTION_RESTART
	    || action == DPD_ACTION_RESTART_BY_PEER
	    );
        
    /** delete the state, which is probably in phase 2 */
    set_cur_connection(c);

    openswan_log("DPD: No response from peer - declaring peer dead");

    switch(action) {
    case DPD_ACTION_HOLD:
	/** dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
	    leak traffic.  Also, being in %trap means new packets will
	    force an initiation of the conn again.  */
	openswan_log("DPD: Putting connection into %%trap");
	delete_states_by_connection(c, TRUE);  
	break;

    case DPD_ACTION_CLEAR:
        /** dpdaction=clear - Wipe the SA & eroute - everything */
    
        openswan_log("DPD: Clearing Connection");
	delete_states_by_connection(c, TRUE);
	DBG(DBG_DPD, DBG_log("unrouting connection"));
        unroute_connection(c);        /* --unroute */
	break;

    case DPD_ACTION_RESTART:
	/** dpdaction=restart - immediate renegotiate the connection. */
        openswan_log("DPD: Restarting Connection");

	/*
	 * unlike the other kinds, we do not delete any states,
	 * but rather, we arrange to replace all SAs involved.
	 */
	rekey_p2states_by_connection(c);

	if (c->kind == CK_INSTANCE) {
		/* If this is a template (eg: right=%any) we won't be able to
		 * reinitiate, the peer has probably changed IP addresses,
		 * or isn't available anymore.  So remove the routes too */
	        unroute_connection(c);        /* --unroute */
	}

	/* we schedule the replace of the SA so that we do it
	 * in a rational place and do it at a negative future time,
	 * so it will occur before any of the phase 2 replacements.
	 */
	delete_event(st);
	delete_dpd_event(st);
	event_schedule(EVENT_SA_REPLACE, 0, st);

	case DPD_ACTION_RESTART_BY_PEER:
	/* dpdaction=restart_by_peer - immediately renegotiate connections to the same peer. */
	openswan_log("DPD: Restarting all connections that share this peer");
	restart_connections_by_peer(c);
	break;

	break;
    }
    reset_cur_connection();
}
示例#4
0
// LED blink timer callback handler.  This is called from the
// context of the timer thread.
static void blink_timer_handler(void const *p_context)
{
  // Schedule a heart beat event.
  event_schedule(blink_event);
}
示例#5
0
文件: dpd.c 项目: millken/zhuxianB30
/*****************************************************************************************   
 函数名称: dpd_outI
 功能描述: dpd 处理事件,当dpd第一次触发时添加一个超时事件,
 	          如果是重传的dpd处理,不添加超时事件。
 输入参数: p1st
 输出参数: 无
 返 回 值: 无
-------------------------------------------------------------------------------------------    
 最近一次修改记录 :    
 修改作者: 王之云    
 修改目的: dpd_outI处理  
 修改日期: 2012年3月20日
********************************************************************************************/  	 
static void dpd_outI(struct state *p1st)
{
    time_t tm;
    u_int32_t seqno;
	time_t timeout = p1st->st_connection->dpd_timeout;
    EV_ADD  ev_arg;
    
	
    DBG(DBG_DPD, DBG_log("processing dpd for state #%lu (\"%s\")"
			 , p1st->st_serialno
			 , p1st->st_connection->name));

    /* If no DPD, then get out of here */
    if (!p1st->hidden_variables.st_dpd)
        return;

    /* If there is no state, there can be no DPD */         
    if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))
        return;
      
    /* find out when now is */
    tm = now();

    
    if (!p1st->st_dpd_seqno)
    {   
        p1st->st_dpd_seqno = dpd_seqno++;
    }    
    seqno = htonl(p1st->st_dpd_seqno);

	/* 如果dpd事件为空,添加dpd事件 */
	if(p1st->st_dpd_event == NULL)
	{
	    ev_arg.u.st = p1st;
		event_schedule(EVENT_DPD, p1st->st_connection->dpd_delay, &ev_arg);
	}

	/* 如果dpd超时事件为空,添加dpd超时事件 */
    if(p1st->st_dpd_timeout_event == NULL)
	{
		passert(timeout > 0);     
		ev_arg.u.st = p1st;
		event_schedule(EVENT_DPD_TIMEOUT, timeout, &ev_arg);   		
	}
	DBG(DBG_DPD, DBG_log("sending R_U_THERE %u to %s:%d (state #%lu)"
			 , seqno
			 , ip_str(&p1st->st_remoteaddr)
			 , p1st->st_remoteport
			 , p1st->st_serialno));

	if(p1st->hidden_variables.st_is_dp_dev && p1st->st_connection->modecfg_quick_dpd )
	{
		if (send_quick_isakmp_notification(p1st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE)
		{   
       		IPSEC_log(IPSEC_LOGLEVEL_PRIVATE, 
					"QUICK DPD Error: connection(%s) send R_U_THERE error\n", p1st->st_connection->name);
       	 	return;	
    	}
	}
	else
	{
		if (send_isakmp_notification(p1st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE)
		{	
			IPSEC_log(IPSEC_LOGLEVEL_PRIVATE, 
					"DPD Error: connection(%s) send R_U_THERE error\n", p1st->st_connection->name);
			return; 
		}
	}

  	p1st->st_dpd_expectseqno = p1st->st_dpd_seqno++;
}
示例#6
0
main()  /* Main function. */
{
    /* Open input and output files. */

    infile  = fopen("jobshop.in",  "r");
    outfile = fopen("jobshop.out", "w");

    /* Read input parameters. */

    fscanf(infile, "%d %d %f %f", &num_stations, &num_job_types,
           &mean_interarrival, &length_simulation);
    for (j = 1; j <= num_stations; ++j)
        fscanf(infile, "%d", &num_machines[j]);
    for (i = 1; i <= num_job_types; ++i)
        fscanf(infile, "%d", &num_tasks[i]);
    for (i = 1; i <= num_job_types; ++i) {
        for (j = 1; j <= num_tasks[i]; ++j)
            fscanf(infile, "%d", &route[i][j]);
        for (j = 1; j <= num_tasks[i]; ++j)
            fscanf(infile, "%f", &mean_service[i][j]);
    }
    for (i = 1; i <= num_job_types; ++i)
        fscanf(infile, "%f", &prob_distrib_job_type[i]);

    /* Write report heading and input parameters. */

    fprintf(outfile, "Job-shop model\n\n");
    fprintf(outfile, "Number of work stations%21d\n\n", num_stations);
    fprintf(outfile, "Number of machines in each station     ");
    for (j = 1; j <= num_stations; ++j)
        fprintf(outfile, "%5d", num_machines[j]);
    fprintf(outfile, "\n\nNumber of job types%25d\n\n", num_job_types);
    fprintf(outfile, "Number of tasks for each job type      ");
    for (i = 1; i <= num_job_types; ++i)
        fprintf(outfile, "%5d", num_tasks[i]);
    fprintf(outfile, "\n\nDistribution function of job types  ");
    for (i = 1; i <= num_job_types; ++i)
        fprintf(outfile, "%8.3f", prob_distrib_job_type[i]);
    fprintf(outfile, "\n\nMean interarrival time of jobs%14.2f hours\n\n",
            mean_interarrival);
    fprintf(outfile, "Length of the simulation%20.1f eight-hour days\n\n\n",
            length_simulation);
    fprintf(outfile, "Job type     Work stations on route");
    for (i = 1; i <= num_job_types; ++i) {
        fprintf(outfile, "\n\n%4d        ", i);
        for (j = 1; j <= num_tasks[i]; ++j)
            fprintf(outfile, "%5d", route[i][j]);
    }
    fprintf(outfile, "\n\n\nJob type     ");
    fprintf(outfile, "Mean service time (in hours) for successive tasks");
    for (i = 1; i <= num_job_types; ++i) {
        fprintf(outfile, "\n\n%4d    ", i);
        for (j = 1; j <= num_tasks[i]; ++j)
            fprintf(outfile, "%9.2f", mean_service[i][j]);
    }

    /* Initialize all machines in all stations to the idle state. */

    for (j = 1; j <= num_stations; ++j)
        num_machines_busy[j] = 0;

    /* Initialize simlib */

    init_simlib();

    /* Set maxatr = max(maximum number of attributes per record, 4) */

    maxatr = 4;  /* NEVER SET maxatr TO BE SMALLER THAN 4. */

    /* Schedule the arrival of the first job. */

    event_schedule(expon(mean_interarrival, STREAM_INTERARRIVAL),
                   EVENT_ARRIVAL);

    /* Schedule the end of the simulation.  (This is needed for consistency of
       units.) */

    event_schedule(8 * length_simulation, EVENT_END_SIMULATION);

    /* Run the simulation until it terminates after an end-simulation event
       (type EVENT_END_SIMULATION) occurs. */

    do {

        /* Determine the next event. */

        timing();

        /* Invoke the appropriate event function. */

        switch (next_event_type) {
            case EVENT_ARRIVAL:
                arrive(1);
                break;
            case EVENT_DEPARTURE:
                depart();
                break;
            case EVENT_END_SIMULATION:
                report();
                break;
        }

    /* If the event just executed was not the end-simulation event (type
       EVENT_END_SIMULATION), continue simulating.  Otherwise, end the
       simulation. */

    } while (next_event_type != EVENT_END_SIMULATION);

    fclose(infile);
    fclose(outfile);

    return 0;
}
示例#7
0
/* delete a state object */
void
delete_state(struct state *st)
{
    struct connection *const c = st->st_connection;
    struct state *old_cur_state = cur_state == st? NULL : cur_state;

    openswan_log("deleting state #%lu (%s)",
                 st->st_serialno,
                 enum_show(&state_names, st->st_state));

    /*
     * for most IKEv2 things, we may have further things to do after marking the state deleted,
     * so we do not actually free it here at all, but back in the main loop when all the work is done.
     */
    if(st->st_ikev2) {
        /* child sa*/
        if(st->st_clonedfrom != 0) {
            DBG(DBG_CONTROL, DBG_log("received request to delete child state"));
            if(st->st_state == STATE_CHILDSA_DEL) {
		DBG(DBG_CONTROL, DBG_log("now deleting the child state"));

            } else {
                /* Only send request if child sa is established
		 * otherwise continue with deletion
		 */
		if(IS_CHILD_SA_ESTABLISHED(st)) {
                    DBG(DBG_CONTROL, DBG_log("sending Child SA delete equest"));
                    send_delete(st);
                    change_state(st, STATE_CHILDSA_DEL);

                    /* actual deletion when we receive peer response*/
                    return;
		}
            }

        } else {
            DBG(DBG_CONTROL, DBG_log("considering request to delete IKE parent state"));
            /* parent sa */
            if(st->st_state == STATE_IKESA_DEL) {
                DBG(DBG_CONTROL, DBG_log("now deleting the IKE (or parent) state"));

            } else {
		/* Another check to verify if a secured
		 * INFORMATIONAL exchange can be sent or not
		 */
		if(st->st_skey_ei.ptr && st->st_skey_ai.ptr
                   && st->st_skey_er.ptr && st->st_skey_ar.ptr) {
                    DBG(DBG_CONTROL, DBG_log("sending IKE SA delete request"));
                    send_delete(st);
                    change_state(st, STATE_IKESA_DEL);
                    event_schedule(EVENT_SA_DELETE, 300, st);

                    /* actual deletion when we receive peer response*/
                    return;
		}
            }
        }
    }

    /* If DPD is enabled on this state object, clear any pending events */
    if(st->st_dpd_event != NULL)
            delete_dpd_event(st);

    /* if there is a suspended state transition, disconnect us */
    if (st->st_suspended_md != NULL)
    {
	passert(st->st_suspended_md->st == st);
	DBG(DBG_CONTROL, DBG_log("disconnecting state #%lu from md",
	    st->st_serialno));
	st->st_suspended_md->st = NULL;
    }

    /* tell the other side of any IPSEC SAs that are going down */
    if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
    || IS_ISAKMP_SA_ESTABLISHED(st->st_state))
	send_delete(st);

    delete_event(st);	/* delete any pending timer event */

    /* Ditch anything pending on ISAKMP SA being established.
     * Note: this must be done before the unhash_state to prevent
     * flush_pending_by_state inadvertently and prematurely
     * deleting our connection.
     */
    flush_pending_by_state(st);

    /* if there is anything in the cryptographic queue, then remove this
     * state from it.
     */
    delete_cryptographic_continuation(st);

    /* effectively, this deletes any ISAKMP SA that this state represents */
    unhash_state(st);

    /* tell kernel to delete any IPSEC SA
     * ??? we ought to tell peer to delete IPSEC SAs
     */
    if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
	|| IS_CHILD_SA_ESTABLISHED(st))
	delete_ipsec_sa(st, FALSE);
    else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
	delete_ipsec_sa(st, TRUE);

    if (c->newest_ipsec_sa == st->st_serialno)
	c->newest_ipsec_sa = SOS_NOBODY;

    if (c->newest_isakmp_sa == st->st_serialno)
	c->newest_isakmp_sa = SOS_NOBODY;

    /*
     * fake a state change here while we are still associated with a
     * connection.  Without this the state logging (when enabled) cannot
     * work out what happened.
     */
    fake_state(st, STATE_UNDEFINED);

    st->st_connection = NULL;	/* we might be about to free it */
    cur_state = old_cur_state;	/* without st_connection, st isn't complete */
    connection_discard(c);

    change_state(st, STATE_UNDEFINED);

    release_whack(st);

    change_state(st, STATE_CHILDSA_DEL);
}
示例#8
0
stf_status send_crypto_helper_request(struct pluto_crypto_req *r,
				 struct pluto_crypto_req_cont *cn)
{
	static int pc_worker_num = 0;	/* index of last worker assigned work */
	struct pluto_crypto_worker *w;	/* best worker for task */
	struct pluto_crypto_worker *c;	/* candidate worker */
	struct state *st = cur_state;	/* TRANSITIONAL */

	/*
	 * transitional: caller must have set pcrc_serialno.
	 * It ought to match cur_state->st_serialno.
	 */
	passert(cn->pcrc_serialno == st->st_serialno);

	passert(st->st_serialno != SOS_NOBODY);
	cn->pcrc_serialno = st->st_serialno;

	passert(cn->pcrc_func != NULL);

	/* do it all ourselves? */
	if (pc_workers == NULL) {
		reset_cur_state();

		pluto_do_crypto_op(r, -1);

		/* call the continuation */
		(*cn->pcrc_func)(cn, r);

		pfree(cn);	/* ownership transferred from caller */

		/* indicate that we completed the work */
		return STF_INLINE;
	}

	/* attempt to send to a worker thread */

	/* set up the id */
	r->pcr_id = pcw_id++;
	cn->pcrc_id = r->pcr_id;
	cn->pcrc_pcr = r;

	/* Find the first of the least-busy workers (if any) */

	w = NULL;
	for (c = pc_workers; c != &pc_workers[pc_workers_cnt]; c++) {
		DBG(DBG_CONTROL,
		    DBG_log("crypto helper %d%s: pcw_work: %d",
			    pc_worker_num,
			    c->pcw_dead? " DEAD" : "",
			    c->pcw_work));

		if (!c->pcw_dead && (w == NULL || c->pcw_work < w->pcw_work)) {
			w = c;	/* c is the best so far */
			if (c->pcw_work == 0)
				break;	/* early out: cannot do better */
		}
	}

	if (w != NULL &&
	    (w->pcw_work < w->pcw_maxbasicwork ||
	      (w->pcw_work < w->pcw_maxcritwork && r->pcr_pcim > pcim_ongoing_crypto)))
	{
		/* allocate task to worker w */

		/* link it to the worker's active list
		 * cn transferred from caller
		 */
		TAILQ_INSERT_TAIL(&w->pcw_active, cn, pcrc_list);

		passert(w->pcw_master_fd != -1);

		cn->pcrc_reply_stream = reply_stream;
		if (pbs_offset(&reply_stream) != 0) {
			/* copy partially built reply stream to heap
			 * IMPORTANT: don't leak this.
			 */
			cn->pcrc_reply_buffer =
				clone_bytes(reply_stream.start,
					    pbs_offset(&reply_stream),
						       "saved reply buffer");
		}

		if (!crypto_write_request(w, r)) {
			/* free the heap space */
			if (pbs_offset(&cn->pcrc_reply_stream) != 0)
				pfree(cn->pcrc_reply_buffer);
			cn->pcrc_reply_buffer = NULL;
			loglog(RC_LOG_SERIOUS, "cannot start crypto helper %d: failed to write",
				w->pcw_helpernum);
			return STF_FAIL;
		}

		w->pcw_work++;
	} else if (r->pcr_pcim >= pcim_demand_crypto) {
		/* Task is important: put it all on the backlog queue for later */

		/* cn transferred from caller */
		TAILQ_INSERT_TAIL(&backlog, cn, pcrc_list);

		/* copy the request */
		r = clone_bytes(r, r->pcr_len, "saved crypto request");
		cn->pcrc_pcr = r;

		cn->pcrc_reply_stream = reply_stream;
		if (pbs_offset(&reply_stream) != 0) {
			/* copy partially built reply stream to heap
			 * IMPORTANT: don't leak this.
			 */
			cn->pcrc_reply_buffer =
				clone_bytes(reply_stream.start,
					    pbs_offset(&reply_stream),
					    "saved reply buffer");
		}

		backlog_queue_len++;
		DBG(DBG_CONTROL,
		    DBG_log("critical demand crypto operation queued on backlog as %dth item; request ID %u",
			    backlog_queue_len, r->pcr_id));
	} else {
		/* didn't find any available workers */
		DBG(DBG_CONTROL,
		    DBG_log("failed to find any available crypto worker (import=%s)",
			    enum_name(&pluto_cryptoimportance_names,
				      r->pcr_pcim)));

		loglog(RC_LOG_SERIOUS, "cannot start crypto helper: failed to find any available worker");

		pfree(cn);	/* ownership transferred from caller */
		return STF_TOOMUCHCRYPTO;
	}

	/* cn ownership transferred on to backlog */

	DBG(DBG_CONTROLMORE, DBG_log("#%lu %s:%u st->st_calculating = TRUE;", st->st_serialno, __FUNCTION__, __LINE__));
	st->st_calculating = TRUE;
	delete_event(st);
	event_schedule(EVENT_CRYPTO_FAILED, EVENT_CRYPTO_FAILED_DELAY, st);

	return STF_SUSPEND;
}
示例#9
0
void arrive(int new_job)  /* Function to serve as both an arrival event of a job
                             to the system, as well as the non-event of a job's
                             arriving to a subsequent station along its
                             route. */
{
    int station;

    /* If this is a new arrival to the system, generate the time of the next
       arrival and determine the job type and task number of the arriving
       job. */


    if (new_job == 1) {

        event_schedule(sim_time + expon(mean_interarrival, STREAM_INTERARRIVAL),
                       EVENT_ARRIVAL);
        job_type = random_integer(prob_distrib_job_type, STREAM_JOB_TYPE);
        task     = 1;
    }

    /* Determine the station from the route matrix. */

    station = route[job_type][task];

    /* Check to see whether all machines in this station are busy. */

    if (num_machines_busy[station] == num_machines[station]) {

        /* All machines in this station are busy, so place the arriving job at
           the end of the appropriate queue. Note that the following data are
           stored in the record for each job:
             1. Time of arrival to this station.
             2. Job type.
             3. Current task number. */

        transfer[1] = sim_time;
        transfer[2] = job_type;
        transfer[3] = task;
        list_file(LAST, station);
    }

    else {

        /* A machine in this station is idle, so start service on the arriving
           job (which has a delay of zero). */

        sampst(0.0, station);                              /* For station. */
        sampst(0.0, num_stations + job_type);              /* For job type. */
        ++num_machines_busy[station];
        timest((float) num_machines_busy[station], station);

        /* Schedule a service completion.  Note defining attributes beyond the
           first two for the event record before invoking event_schedule. */

        transfer[3] = job_type;
        transfer[4] = task;
        event_schedule(sim_time
                       + erlang(2, mean_service[job_type][task],
                                STREAM_SERVICE),
                       EVENT_DEPARTURE);
    }
}
示例#10
0
/*
 * invoke helper to do DH work.
 */
stf_status start_dh_v2(struct pluto_crypto_req_cont *cn,
		       struct state *st,
		       enum crypto_importance importance,
		       enum phase1_role init,        /* TRUE=g_init,FALSE=g_r */
		       u_int16_t oakley_group2)
{
	struct pluto_crypto_req r;
	struct pcr_skeyid_q *dhq;
	err_t e;
	bool toomuch = FALSE;

	pcr_init(&r, pcr_compute_dh_v2, importance);

	dhq = &r.pcr_d.dhq;

	passert(st->st_sec_in_use);

	DBG(DBG_CONTROLMORE,
	    DBG_log("calculating skeyseed using prf=%s integ=%s cipherkey=%s",
		    enum_name(&ikev2_trans_type_prf_names,   st->st_oakley.prf_hash),
		    enum_name(&ikev2_trans_type_integ_names,
			      st->st_oakley.integ_hash),
		    enum_name(&ikev2_trans_type_encr_names,
			      st->st_oakley.encrypt)));

	/* convert appropriate data to dhq */
	dhq->auth = st->st_oakley.auth;
	dhq->prf_hash   = st->st_oakley.prf_hash;
	dhq->integ_hash = st->st_oakley.integ_hash;
	dhq->oakley_group = oakley_group2;
	dhq->init = init;
	dhq->keysize = st->st_oakley.enckeylen / BITS_PER_BYTE;

	passert(r.pcr_d.dhq.oakley_group != 0);

	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->ni,
			       st->st_ni);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->nr,
			       st->st_nr);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gi,
			       st->st_gi);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gr,
			       st->st_gr);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space,
			       &dhq->secret, st->st_sec_chunk);

	/*copying required encryption algo*/
	/*dhq->encrypt_algo = st->st_oakley.encrypter->common.algo_v2id;*/
	dhq->encrypter = st->st_oakley.encrypter;
	DBG(DBG_CRYPT,
	    DBG_log("Copying DH pub key pointer to be sent to a thread helper"));
	pluto_crypto_copychunk(&dhq->thespace, dhq->space,
			       &dhq->pubk, st->pubk);

	pluto_crypto_allocchunk(&dhq->thespace, &dhq->icookie, COOKIE_SIZE);
	memcpy(wire_chunk_ptr(dhq, &dhq->icookie),
	       st->st_icookie, COOKIE_SIZE);

	pluto_crypto_allocchunk(&dhq->thespace, &dhq->rcookie, COOKIE_SIZE);
	memcpy(wire_chunk_ptr(dhq, &dhq->rcookie),
	       st->st_rcookie, COOKIE_SIZE);

	passert(dhq->oakley_group != 0);
	e = send_crypto_helper_request(&r, cn, &toomuch);

	if (e != NULL) {
		loglog(RC_LOG_SERIOUS, "can not start crypto helper: %s", e);
		if (toomuch)
			return STF_TOOMUCHCRYPTO;
		else
			return STF_FAIL;
	} else if (!toomuch) {
		st->st_calculating = TRUE;
		delete_event(st);
		event_schedule(EVENT_CRYPTO_FAILED, EVENT_CRYPTO_FAILED_DELAY,
			       st);
		return STF_SUSPEND;
	} else {
		/* we must have run the continuation directly, so
		 * complete_state_transition already got called.
		 */
		return STF_INLINE;
	}
}
示例#11
0
/*
 * invoke helper to do DH work.
 */
stf_status start_dh_secretiv(struct pluto_crypto_req_cont *cn
			     , struct state *st
			     , enum crypto_importance importance
			     , enum phase1_role init       /* TRUE=g_init,FALSE=g_r */
			     , u_int16_t oakley_group2)
{
    struct pluto_crypto_req r;
    struct pcr_skeyid_q *dhq;
    const chunk_t *pss = get_preshared_secret(st->st_connection);
    err_t e;
    bool toomuch = FALSE;

    pcr_init(&r, pcr_compute_dh_iv, importance);

    dhq = &r.pcr_d.dhq;

    passert(st->st_sec_in_use);

    /* convert appropriate data to dhq */
    dhq->auth = st->st_oakley.auth;
    dhq->prf_hash = st->st_oakley.prf_hash;
    dhq->oakley_group = oakley_group2;
    dhq->init = init;
    dhq->keysize = st->st_oakley.enckeylen/BITS_PER_BYTE;

    passert(r.pcr_d.dhq.oakley_group != 0);
    DBG(DBG_CONTROL | DBG_CRYPT,
       DBG_log("parent1 type: %d group: %d len: %d\n", r.pcr_type,
	    r.pcr_d.dhq.oakley_group, (int)r.pcr_len));

    if(pss) {
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->pss, *pss);
    }
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->ni,  st->st_ni);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->nr,  st->st_nr);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gi,  st->st_gi);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gr,  st->st_gr);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space
			   , &dhq->secret, st->st_sec_chunk);

#ifdef HAVE_LIBNSS
    /*copying required encryption algo*/
    /*dhq->encrypt_algo = st->st_oakley.encrypt;*/
    dhq->encrypter = st->st_oakley.encrypter;
    DBG(DBG_CRYPT, DBG_log("Copying DH pub key pointer to be sent to a thread helper"));
    pluto_crypto_copychunk(&dhq->thespace, dhq->space , &dhq->pubk, st->pubk);
#endif

    pluto_crypto_allocchunk(&dhq->thespace, &dhq->icookie, COOKIE_SIZE);
    memcpy(wire_chunk_ptr(dhq, &dhq->icookie)
	   , st->st_icookie, COOKIE_SIZE);

    pluto_crypto_allocchunk(&dhq->thespace, &dhq->rcookie, COOKIE_SIZE);
    memcpy(wire_chunk_ptr(dhq, &dhq->rcookie)
	   , st->st_rcookie, COOKIE_SIZE);

    passert(dhq->oakley_group != 0);
    e = send_crypto_helper_request(&r, cn, &toomuch);

    if(e != NULL) {
	loglog(RC_LOG_SERIOUS, "can not start crypto helper: %s", e);
	if(toomuch) {
	    return STF_TOOMUCHCRYPTO;
	} else {
	    return STF_FAIL;
	}
    } else if(!toomuch) {
	st->st_calculating = TRUE;
	delete_event(st);
	event_schedule(EVENT_CRYPTO_FAILED, EVENT_CRYPTO_FAILED_DELAY, st);
	return STF_SUSPEND;
    } else {
	/* we must have run the continuation directly, so
	 * complete_state_transition already got called.
	 */
	return STF_INLINE;
    }
}
int main()  /* Main function. */
{
    printf("Masukkan batas atas job 1 (default: 10): \n");
    scanf("%d", &batasatasjob1);
    printf("\n\nMasukkan batas atas job 2 (default: 40): \n");
    scanf("%d", &batasatasjob2);

    /* Open input and output files. */

    infile  = fopen("tscomp-tugas.in",  "r");
    outfile = fopen("tscomp-tugas.out", "w");

    /* Read input parameters. */

    fscanf(infile, "%d %d %d %d %f %f %f %f",
           &min_terms, &max_terms, &incr_terms, &num_responses_required,
           &mean_think, &mean_service, &quantum, &swap);

    /* Write report heading and input parameters. */

    fprintf(outfile, "Time-shared computer model\n\n");
    fprintf(outfile, "Number of terminals%9d to%4d by %4d\n\n",
            min_terms, max_terms, incr_terms);
    fprintf(outfile, "Mean think time  %11.3f seconds\n\n", mean_think);
    fprintf(outfile, "Mean service time%11.3f seconds\n\n", mean_service);
    fprintf(outfile, "Quantum          %11.3f seconds\n\n", quantum);
    fprintf(outfile, "Swap time        %11.3f seconds\n\n", swap);
    fprintf(outfile, "Number of jobs processed%12d\n\n\n",
            num_responses_required);
    fprintf(outfile, "Number of      Average         Average");
    fprintf(outfile, "       Utilization      CPU-num/\n");
    fprintf(outfile, "terminals   response time  number in queue     of CPU          JOB-type");

    /* Run the simulation varying the number of terminals. */

    for (num_terms = min_terms; num_terms <= max_terms;
         num_terms += incr_terms) {

        /* Initialize simlib */

        init_simlib();

        /* Set maxatr = max(maximum number of attributes per record, 4) */

        maxatr = 4;  /* NEVER SET maxatr TO BE SMALLER THAN 4. */

        /* Initialize the non-simlib statistical counter. */

        num_responses = 0;

        /* Schedule the first arrival to the CPU from each terminal. */

        for (term = 1; term <= num_terms; ++term)
            event_schedule(expon(mean_think, STREAM_THINK), EVENT_ARRIVAL);

        /* Run the simulation until it terminates after an end-simulation event
           (type EVENT_END_SIMULATION) occurs. */

        do {

            /* Determine the next event. */

            timing();

            /* Invoke the appropriate event function. */

            switch (next_event_type) {
                case EVENT_ARRIVAL:
                    arrive();
                    break;
                case EVENT_END_CPU_1_RUN:
                    end_CPU_run(LIST_CPU_1);
                    break;
                case EVENT_END_CPU_2_RUN:
                    end_CPU_run(LIST_CPU_2);
                    break;
                case EVENT_END_CPU_3_RUN:
                    end_CPU_run(LIST_CPU_3);
                    break;
                case EVENT_END_SIMULATION:
                    report();
                    break;
            }

        /* If the event just executed was not the end-simulation event (type
           EVENT_END_SIMULATION), continue simulating.  Otherwise, end the
           simulation. */

        } while (next_event_type != EVENT_END_SIMULATION);
    }

    fclose(infile);
    fclose(outfile);

    printf("\n\nOutput hasil eksekusi program dapat dilihat pada tscomp-tugas.out\n");

    return 0;
}
void end_CPU_run(int list_cpu_num)  /* Event function to end a CPU run of a job. */
{
    /* Remove the job from the CPU. */

    list_remove(FIRST, list_cpu_num);

    int jenis_job_queue;
    switch (list_cpu_num){
    case LIST_CPU_1:
        jenis_job_queue=LIST_QUEUE_1;
    break;
    case LIST_CPU_2:
        jenis_job_queue=LIST_QUEUE_2;
    break;
    case LIST_CPU_3:
        jenis_job_queue=LIST_QUEUE_3;
    break;
    }

    /* Check to see whether this job requires more CPU time. */

    if (transfer[2] > 0.0) {

        /* This job requires more CPU time, so place it at the end of the queue
           and start the first job in the queue. */

        list_file(LAST, jenis_job_queue);
        start_CPU_run(jenis_job_queue);
    }

    else {

        /* This job is finished, so collect response-time statistics and send it
           back to its terminal, i.e., schedule another arrival from the same
           terminal. */

        sampst(sim_time - transfer[1], SAMPST_RESPONSE_TIMES);//TODO nanti hapus
        switch(jenis_job_queue){
        case (LIST_QUEUE_1):
            sampst(sim_time - transfer[1], SAMPST_RESPONSE_TIMES_1);
        break;
        case (LIST_QUEUE_2):
            sampst(sim_time - transfer[1], SAMPST_RESPONSE_TIMES_2);
        break;
        case (LIST_QUEUE_3):
            sampst(sim_time - transfer[1], SAMPST_RESPONSE_TIMES_3);
        break;
        }
	

        event_schedule(sim_time + expon(mean_think, STREAM_THINK),
                       EVENT_ARRIVAL); //TODO nanti ganti sama distribusi yang disebut di spek (belum jelas)

        /* Increment the number of completed jobs. */

        ++num_responses;

        /* Check to see whether enough jobs are done. */

        if (num_responses >= num_responses_required)

            /* Enough jobs are done, so schedule the end of the simulation
               immediately (forcing it to the head of the event list). */

            event_schedule(sim_time, EVENT_END_SIMULATION);

        else

            /* Not enough jobs are done; if the queue is not empty, start
               another job. */

            if (list_size[jenis_job_queue] > 0)
                start_CPU_run(jenis_job_queue);
    }
}
示例#14
0
文件: isal.c 项目: gunnarrb/isal
int main()
{
    // load datafiles
    parse_input("adal_inntak.in","velar_og_bidradir.in");
	
    // initialize arrays and variables
    if((fail_list = malloc(sizeof(breakdown)*NUM_MACHINES+1))==NULL) {
	printf("Allocation Error\n");
	exit(1);
    }
   
    for (failure_nr = min_no_failures; failure_nr<= max_no_failures; failure_nr++) {
	stream = (unsigned int)time(NULL) % 100;   
		
	memset( is_machine_busy,0, NUM_MACHINES +1 );
	memset( machine_broken,0, NUM_MACHINES +1);
	memset( queue_max_lengths,0, NUM_MACHINES +1);
	memset( fail_list,0, sizeof(breakdown)*(NUM_MACHINES+1));
	fail_index = 0;
	skaut_throughput = 0;
	sampst_delays = number_of_machines +1;
	throughput_time = number_of_machines +2;
		
	skaut_id = 1;
	skaut_throughput = 0;
		
		
	// Initialize rndlib
	init_twister();
		
	// Initialize simlib
	init_simlib();
		
	maxatr = 6; // how many attributes do we need?
		
	/* Schedule first wagen arrival */
	event_schedule( 10.0, EVENT_WAGEN_UNLOAD_ARRIVAL );
		
	/* Schedule end of warmup time */
	event_schedule( end_warmup_time, EVENT_END_WARMUP );
	event_schedule(end_warmup_time, EVENT_GENERATE_FAILURES );	
	/* Schedule simulation termination */
	event_schedule(end_simulation_time , EVENT_END_SIMULATION );
		
	next_event_type = 0;
		
        
	while (next_event_type != EVENT_END_SIMULATION) {
			
	    timing();
			
	    switch (next_event_type) {
	    case EVENT_WAGEN_UNLOAD_ARRIVAL:
		wagen_unload_arrival();
		break;
	    case EVENT_SKAUT_ARRIVAL:
		skaut_arrival();
		break;
	    case EVENT_SKAUT_DEPARTURE:
		skaut_departure();
		break;
	    case EVENT_MACHINE_FAILURE:
		machine_failure();
		break;
	    case EVENT_MACHINE_FIXED:
		machine_fixed();
		break;
	    case EVENT_END_WARMUP:
		end_warmup();
		break;
	    case EVENT_END_SIMULATION:
		report();
		break;
	    case EVENT_GENERATE_FAILURES:
		create_machine_fail_events();
		break;
					
	    }
	}
		
    }
}
示例#15
0
void bloodDemand()
{
	int i, g;
	/*
	1) Generate the daily demand for the items of various blood groups.
	//TODO: implement generators for daily demand of items i of blood groups g.
	*/
	float bloodDemand[MAXITEM][MAXBLOODGROUP];
	float demandSum = 0.0f; //not important - just for printing

	//stikar fyrir negative binomial dreifingarnar
	float sizevigur[8] = { 2.881316 , 5.469497,  2.126104 ,0.9013933, 2.278314, 1.755385 , 1.016910 , 1.5033445 };
	float muvigur[8]   = { 7.844908 ,4.519023 ,4.279691 , 1.6684022, 3.749920, 3.009935, 2.440104 , 0.6499638 };
	float result[16];

	//empirískar dreifingar
	float empFFPo[7] = { 0.533980583, 0.660194175, 0.825242718, 0.86407767, 0.912621359, 0.961165049, 1 };
	float empFFPb[8] = { 0.640776699, 0.747572816, 0.883495146, 0.912621359, 0.961165049, 0.980582524, 0.990291262,1 };
	float empFFPa[6] = { 0.699029126, 0.786407767, 0.932038835, 0.970873786, 0.990291262, 1 };
	float empFFPab[3]= { 0.980582524, 0.990291262, 1 };
	float empPlatelets[25] = { 0.29787234,0.329787234,0.361702128,0.393617021,0.510638298,0.521276596,0.531914894,
		0.563829787,0.595744681,0.638297872,0.691489362,0.712765957,0.755319149,0.776595745,0.787234043,0.808510638,
		0.872340426,0.904255319,0.914893617,0.957446809,0.968085106,0.978723404,0.989361702,1 };

	//byrja að fylla inn demand í result
	for (i = 0; i < 8; i++){
			result[i] = negativebinomrnd(sizevigur[i], muvigur[i], demand_seed); //demand sem er nbinom dreift
		}

	//fylli discrete ffp
	float FFPo = discrete_empirical(empFFPo, 7, demand_seed); result[8] = FFPo; //demand sem er empirical dreift
	float FFPb = discrete_empirical(empFFPb, 8, demand_seed); result[9] = FFPb;
	float FFPa = discrete_empirical(empFFPa, 6, demand_seed); result[10] = FFPa;
	float FFPab = discrete_empirical(empFFPab, 3, demand_seed); result[11] = FFPab;


	//fylli discrete platelets
	float p = discrete_empirical(empPlatelets, 25, demand_seed);

    for (i = 0; i < MAXBLOODGROUP; ++i)
    {
        result[i+12] = Perc[i]*p;
    }

	int teljari = 0;

	for (i = 0; i < MAXITEM; i++)
	{
		for (g = 0; g < MAXBLOODGROUP; g++)
		{

			bloodDemand[i][g] = result[teljari];
			demandSum += bloodDemand[i][g];
			teljari++;
		}
	}
	/*
	2) Update the stock levels of the items of various blood groups.
	3) If the unmet demand for an item is fulfilled using the stock of a
	substitutable item, update the stock of the latter.
	*/
	for (i = 0; i < MAXITEM; i++)
	{
		for (g = 0; g < MAXBLOODGROUP; g++)
		{
			int n = oldestBadge[i][g];
			//search through badges n=0,1,2,...,MAXNBATCH.
			//if a batch is empty, try next batch
			//if a batch has blood, use blood. If demand is fulfilled stop. Else try next badge while there is demand.
			while (bloodDemand[i][g] > 0.0f && n < oldestBadge[i][g]+N[i][g])
			{
				if (Stock[n][i][g] == 0.0f) ++n; //badge n is empty - check next badge
				else if (Stock[n][i][g] > bloodDemand[i][g]) //enough of blood in badge n to fulfill demand
				{
					Stock[n][i][g] -= bloodDemand[i][g];
					bloodDemand[i][g] = 0.0f;
					break;
				}
				else if(Stock[n][i][g] <= bloodDemand[i][g]) //blood in badge n, but not enough to fulfill demand - use up all blood in stock and check next badge n+1
				{
					bloodDemand[i][g] -= Stock[n][i][g];
					Stock[n][i][g] = 0.0f;
					++n;
				}
			}
		}
	}
	float shortageSum = 0;
	/*
	4) Update shortages if any.
	*/
	//Now bloodDemand[i][g] has been modified to be the unfulfilled demands, a.k.a the shortage
	for (i = 0; i < MAXITEM; i++)
	{
		for (g = 0; g < MAXBLOODGROUP; g++)
		{
			shortage[i][g] += bloodDemand[i][g];
			shortageSum += bloodDemand[i][g];
		}
	}

	DEBUGPRINTF("Daily demand: total %.2f units. Failed to fulfill %d%% of demands\n", demandSum, (int)(100*shortageSum/demandSum));
	//Schedule demand on the next day
	event_schedule(sim_time + 1.0f, EVENT_BLOOD_DEMAND); //daily
}
示例#16
0
stf_status
dpd_init(struct state *st)
{
    /**
     * Used to store the 1st state 
     */
    struct state *p1st;

#ifdef CONSOLE_DEBUG
    time_start = time(NULL);
#endif

    /* find the related Phase 1 state */
    p1st = find_state(st->st_icookie, st->st_rcookie,
		      &st->st_connection->that.host_addr, 0);

    if (p1st == NULL) {
        loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD");

	/*
	 * if the phase 1 state has gone away, it really should have
	 * deleted all of its children.
	 * Why would this happen? because a quick mode SA can take
	 * some time to create (DNS lookups for instance), and the phase 1
	 * might have been taken down for some reason in the meantime.
	 * We really can not do anything here --- attempting to invoke
	 * the DPD action would be a good idea, but we really should
	 * do that outside this function.
	 */
	return STF_FAIL;
    }

    /* if it was enabled, and we haven't turned it on already */
    if (p1st->hidden_variables.st_dpd) {
	time_t n = now();
	log("Dead Peer Detection (RFC 3706): enabled");

	/* If st is a phase 2 state, so turn its DPD on. This is needed, because
	 * DPD support is negotiated during phase 1.
	 */
	if (p1st != st)
	    st->hidden_variables.st_dpd = p1st->hidden_variables.st_dpd;

	if(st->st_dpd_event == NULL
	   || (st->st_connection->dpd_idle_timeout + n) <
	   st->st_dpd_event->ev_time) {
	    delete_dpd_event(st);
	    event_schedule(EVENT_DPD, st->st_connection->dpd_idle_timeout, st);
	}

    } else {
      log("Dead Peer Detection (RFC 3706): not enabled because peer did not advertise it");
    }

    if(p1st != st) {
	/* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */
	if(p1st->st_dpd_event != NULL
	   && p1st->st_dpd_event->ev_type == EVENT_DPD) {
	    delete_dpd_event(p1st);
	}
    }
    return STF_OK;
}