int proc_loop(void) { int rc = 0; log_debug("setting working directory ...\n"); if ((mkdir(daemon_cfg.notify_dir, 0777) != 0) && (errno != EEXIST)) { rc = -errno; log_error("failed create folder %s (errno = %d)\n", daemon_cfg.notify_dir, errno); goto err; } log_debug("setting store ...\n"); rc = open_store(); if (rc < 0) { goto err; } log_debug("setting flow ...\n"); rc = open_flow(); if (rc < 0) { goto err; } log_debug("setting notification ...\n"); rc = open_notify(); if (rc < 0) { goto err; } log_debug("setting message processing ...\n"); rc = open_message(); if (rc < 0) { goto err; } log_debug("starting loop ...\n"); while ((0 == daemon_cfg.sig) && (errno != EINTR)) { fd_set readfds; struct timeval tv; int max_fd = -1; FD_ZERO(&readfds); FD_SET(daemon_cfg.sock_fd, &readfds); max_fd = daemon_cfg.sock_fd; FD_SET(daemon_cfg.notify_fd, &readfds); max_fd = (max_fd < daemon_cfg.notify_fd ? daemon_cfg.notify_fd : max_fd); /* Use timeout for select() call */ tv.tv_sec = 60; tv.tv_usec = 0; rc = select(max_fd + 1, &readfds, NULL, NULL, &tv); if (rc < 0) { rc = 0; if (errno != EINTR) { rc = -errno; log_error("Failed select() errno %d (%s)\n", errno, strerror(errno)); } goto err; } else if (rc == 0) { continue; } /* Check messages from processes */ if (FD_ISSET(daemon_cfg.sock_fd, &readfds)) { log_debug("message processing ...\n"); rc = proc_message(); } /* Check any events from file system monitor */ if (FD_ISSET(daemon_cfg.notify_fd, &readfds)) { log_debug("notification processing ...\n"); rc = proc_notify(); } } err: log_debug("finishing loop ...\n"); close_message(); close_notify(); close_flow(); close_store(); return rc; }
void send_v2_notification(struct state *p1st, u_int16_t type , struct state *encst , u_char *icookie , u_char *rcookie , chunk_t *n_data) { u_char buffer[1024]; pb_stream reply; pb_stream rbody; /* this function is not generic enough yet just enough for 6msg * TBD accept HDR FLAGS as arg. default ISAKMP_FLAGS_R * TBD when there is a child SA use that SPI in the notify paylod. * TBD support encrypted notifications payloads. * TBD accept Critical bit as an argument. default is set. * TBD accept exchange type as an arg, default is ISAKMP_v2_SA_INIT * do we need to send a notify with empty data? * do we need to support more Protocol ID? more than PROTO_ISAKMP */ IPSEC_dbg("sending %snotification %s to %s:%u" , encst ? "encrypted " : "" , enum_name(&ikev2_notify_names, type) , ip_str(&p1st->st_remoteaddr) , p1st->st_remoteport); if(n_data == NULL) { DBG(DBG_CONTROLMORE, DBG_log("don't send packet when notification data empty")); return; } memset(buffer, 0, sizeof(buffer)); init_pbs(&reply, buffer, sizeof(buffer), "notification msg"); /* HDR out */ { struct isakmp_hdr n_hdr ; zero(&n_hdr); /* default to 0 */ /* AAA should we copy from MD? */ n_hdr.isa_version = IKEv2_MAJOR_VERSION << ISA_MAJ_SHIFT | IKEv2_MINOR_VERSION; memcpy(n_hdr.isa_rcookie, rcookie, COOKIE_SIZE); memcpy(n_hdr.isa_icookie, icookie, COOKIE_SIZE); n_hdr.isa_xchg = ISAKMP_v2_SA_INIT; n_hdr.isa_np = ISAKMP_NEXT_v2N; n_hdr.isa_flags &= ~ISAKMP_FLAGS_I; n_hdr.isa_flags |= ISAKMP_FLAGS_R; if (!out_struct(&n_hdr, &isakmp_hdr_desc, &reply, &rbody)) { IPSEC_dbg("error initializing hdr for notify message"); return; } } chunk_t child_spi; child_spi.ptr = NULL; child_spi.len = 0; /* build and add v2N payload to the packet */ ship_v2N (ISAKMP_NEXT_NONE, ISAKMP_PAYLOAD_CRITICAL, PROTO_ISAKMP, &child_spi,type, n_data, &rbody); close_message(&rbody); close_output_pbs(&reply); clonetochunk(p1st->st_tpacket, reply.start, pbs_offset(&reply) , "notification packet"); ipsec_child_send_packet(p1st, "notification", TRUE); }