Пример #1
0
static bool default_send_receive(connection_t *connection, transaction_t *transaction)
{
	transaction_t reply;
	const options_t *options = get_options_object();
	connection_send(connection, transaction, sizeof(transaction_t));

	ssize_t num_read = connection_read(connection, options->timeout, &reply,
			sizeof(transaction_t));
	if (num_read <= 0) {
		return false;
	}

	if (reply.status == SUCCESS) {
		fprintf(stderr, "Request executed successfully\n");
	}
	else {
		if (reply.status == PROCESSING) {
			fprintf(stderr, "The server is busy processing your request: %s\n",
						reply.payload.data);
		}
		else {
			fprintf(stderr, "Error processing the request: %s\n",
					reply.payload.data);
			return false;
		}
	}

	return true;
}
Пример #2
0
int main(int argc, char* argv[])
{
  struct connection conn;
  iopoll_fd fds[2];
  int selfpipe;
  int i;

  msg_debug_init();
  testmode = getenv("TESTMODE") != 0;

  if ((shell_argv = malloc((argc + 3) * sizeof *argv)) == 0)
    die_oom(111);
  for (i = 1; i < argc; ++i)
    shell_argv[i-1] = argv[i];
  for (; i < argc + 4; ++i)
    shell_argv[i-1] = 0;
  shell_argc = argc - 1;

  if ((path = getenv("PATH")) == 0)
    die1(111, "No PATH is set");
  if ((devnull = open("/dev/null", O_RDWR)) == -1)
    die1sys(111, "Could not open \"/dev/null\"");
  if (!nonblock_on(0))
    die1sys(111, "Could not set non-blocking status");
  if ((selfpipe = selfpipe_init()) == -1)
    die1sys(111, "Could not create self-pipe");
  init_slots();
  connection_init(&conn, 0, 0);
  fds[0].fd = 0;
  fds[0].events = IOPOLL_READ;
  fds[1].fd = selfpipe;
  fds[1].events = IOPOLL_READ;
  for (;;) {
    if (iopoll_restart(fds, 2, -1) == -1)
      die1sys(111, "Poll failed");
    if (fds[0].revents)
      if (connection_read(&conn, handle_packet) <= 0)
	break;
    if (fds[1].revents) {
      read(selfpipe, &i, 1);
      handle_child(WNOHANG);
    }
  }
  msg1("Waiting for remaining slots to complete");
  while (slots_used > 0)
    handle_child(0);
  return 0;
}
Пример #3
0
static bool status_command(connection_t *connection, transaction_t *transaction) {
	const options_t *options = get_options_object();

	transaction_t reply;
	do {

		bzero(&reply, sizeof(reply));
		connection_send(connection, transaction, sizeof(transaction_t));
		do {
			ssize_t num_read = connection_read(connection, options->timeout,
					&reply, sizeof(transaction_t));
			if (num_read <= 0) {
				printf("Timed out while trying to read");
				continue;
			}

			if (reply.status == PROCESSING) {
				entry_t *entry = (entry_t *) reply.payload.data;

				switch (entry->status) {
					case STARTED: {
						printf("Downloading %.0f of %.0f of file %s at %.0f Kb/s\n",
								entry->complete, entry->size, entry->id.name,
								(entry->speed / 1024));
						break;
					}
					case WAITING: {
						printf("Downloaded file %s is waiting for available slots\n",
								 entry->id.name);
						break;
					}
					case COMPLETED:
					case PAUSED: {
						printf("Downloaded %.0f of %.0f of file %s\n",
							entry->complete, entry->size, entry->id.name);
						break;
					}
					default: {
						break;
					}

				}
			}
		} while (reply.status == PROCESSING);
		//printf("Finished processing ... \n")
		sleep(1);
	} while (options->keep_alive);
}
Пример #4
0
static void
test(struct connection_pool *p, int id) {
	int i=0;
	while (i<5) {
		int handle = id;
		const char * line = connection_readline(p, handle, "\n",  NULL);
		if (line == NULL) {
			line = connection_poll(p,1000,&handle,NULL);
		}
		if (line) {
			printf("%d %d: %s\n",i,handle, line);
			connection_write(p,handle,"readline\n",9);
			++i;
		} else {
			if (handle) {
				printf("Close %d\n",handle);
				return;
			}
		}
	}
	i=0;
	while (i<5) {
		int handle = id;
		uint8_t * buffer = connection_read(p, handle, 8);
		if (buffer == NULL) {
			buffer = connection_poll(p,1000,&handle,NULL);
		}
		if (buffer) {
			int j;
			printf("%d %d: ",i,handle);
			for (j=0;j<8;j++) {
				printf("%02x ",buffer[j]);
			}
			printf("\n");
			connection_write(p,handle,"readblock\n",10);
			++i;
		} else {
			if (handle) {
				printf("Close %d\n", handle);
				return;
			}
		}
	}
}
Пример #5
0
static tree
connection_retrieve (string name, string session) {
  // cout << "Retrieve " << name << ", " << session << "\n";
  connection con= connection (name * "-" * session);
  if (is_nil (con)) return "";
  tree doc (DOCUMENT);
  while (true) {
    con->forced_eval= true;
#ifndef QTTEXMACS
    perform_select ();
#endif
    con->forced_eval= false;
    tree next= connection_read (name, session);
    if (next == "");
    else if (is_document (next)) doc << A (next);
    else doc << next;
    if (con->status == WAITING_FOR_INPUT) break;
  }
  if (N(doc) == 0) return "";
  // cout << "Retrieved " << doc << "\n";
  return doc;
}
Пример #6
0
static int telnet_input(struct connection *connection)
{
	int bytes_read;
	unsigned char buffer[TELNET_BUFFER_SIZE];
	unsigned char *buf_p;
	struct telnet_connection *t_con = connection->priv;
	struct command_context *command_context = connection->cmd_ctx;

	bytes_read = connection_read(connection, buffer, TELNET_BUFFER_SIZE);

	if (bytes_read == 0)
		return ERROR_SERVER_REMOTE_CLOSED;
	else if (bytes_read == -1) {
		LOG_ERROR("error during read: %s", strerror(errno));
		return ERROR_SERVER_REMOTE_CLOSED;
	}

	buf_p = buffer;
	while (bytes_read) {
		switch (t_con->state) {
			case TELNET_STATE_DATA:
				if (*buf_p == 0xff)
					t_con->state = TELNET_STATE_IAC;
				else {
					if (isprint(*buf_p)) {	/* printable character */
						/* watch buffer size leaving one spare character for
						 * string null termination */
						if (t_con->line_size == TELNET_LINE_MAX_SIZE-1) {
							/* output audible bell if buffer is full
							 * "\a" does not work, at least on windows */
							telnet_write(connection, "\x07", 1);
						} else if (t_con->line_cursor == t_con->line_size) {
							telnet_write(connection, buf_p, 1);
							t_con->line[t_con->line_size++] = *buf_p;
							t_con->line_cursor++;
						} else {
							int i;
							memmove(t_con->line + t_con->line_cursor + 1,
									t_con->line + t_con->line_cursor,
									t_con->line_size - t_con->line_cursor);
							t_con->line[t_con->line_cursor] = *buf_p;
							t_con->line_size++;
							telnet_write(connection,
									t_con->line + t_con->line_cursor,
									t_con->line_size - t_con->line_cursor);
							t_con->line_cursor++;
							for (i = t_con->line_cursor; i < t_con->line_size; i++)
								telnet_write(connection, "\b", 1);
						}
					} else {	/* non-printable */
						if (*buf_p == 0x1b) {	/* escape */
							t_con->state = TELNET_STATE_ESCAPE;
							t_con->last_escape = '\x00';
						} else if ((*buf_p == 0xd) || (*buf_p == 0xa)) {	/* CR/LF */
							int retval;

							/* skip over combinations with CR/LF and NUL characters */
							if ((bytes_read > 1) && ((*(buf_p + 1) == 0xa) ||
									(*(buf_p + 1) == 0xd))) {
								buf_p++;
								bytes_read--;
							}
							if ((bytes_read > 1) && (*(buf_p + 1) == 0)) {
								buf_p++;
								bytes_read--;
							}
							t_con->line[t_con->line_size] = 0;

							telnet_write(connection, "\r\n\x00", 3);

							if (strcmp(t_con->line, "history") == 0) {
								int i;
								for (i = 1; i < TELNET_LINE_HISTORY_SIZE; i++) {
									/* the t_con->next_history line contains empty string
									 * (unless NULL), thus it is not printed */
									char *history_line = t_con->history[(t_con->
											next_history + i) %
											TELNET_LINE_HISTORY_SIZE];
									if (history_line) {
										telnet_write(connection, history_line,
												strlen(history_line));
										telnet_write(connection, "\r\n\x00", 3);
									}
								}
								t_con->line_size = 0;
								t_con->line_cursor = 0;
								continue;
							}

							/* save only non-blank not repeating lines in the history */
							char *prev_line = t_con->history[(t_con->current_history > 0) ?
									t_con->current_history - 1 : TELNET_LINE_HISTORY_SIZE-1];
							if (*t_con->line && (prev_line == NULL ||
									strcmp(t_con->line, prev_line))) {
								/* if the history slot is already taken, free it */
								if (t_con->history[t_con->next_history])
									free(t_con->history[t_con->next_history]);

								/* add line to history */
								t_con->history[t_con->next_history] = strdup(t_con->line);

								/* wrap history at TELNET_LINE_HISTORY_SIZE */
								t_con->next_history = (t_con->next_history + 1) %
										TELNET_LINE_HISTORY_SIZE;

								/* current history line starts at the new entry */
								t_con->current_history =
										t_con->next_history;

								if (t_con->history[t_con->current_history])
									free(t_con->history[t_con->current_history]);
								t_con->history[t_con->current_history] = strdup("");
							}

							t_con->line_size = 0;

							/* to suppress prompt in log callback during command execution */
							t_con->line_cursor = -1;

							if (strcmp(t_con->line, "shutdown") == 0)
								telnet_save_history(t_con);

							retval = command_run_line(command_context, t_con->line);

							t_con->line_cursor = 0;

							if (retval == ERROR_COMMAND_CLOSE_CONNECTION)
								return ERROR_SERVER_REMOTE_CLOSED;

							/* the prompt is always * placed at the line beginning */
							telnet_write(connection, "\r", 1);

							retval = telnet_prompt(connection);
							if (retval == ERROR_SERVER_REMOTE_CLOSED)
								return ERROR_SERVER_REMOTE_CLOSED;

						} else if ((*buf_p == 0x7f) || (*buf_p == 0x8)) {	/* delete character */
							if (t_con->line_cursor > 0) {
								if (t_con->line_cursor != t_con->line_size) {
									int i;
									telnet_write(connection, "\b", 1);
									t_con->line_cursor--;
									t_con->line_size--;
									memmove(t_con->line + t_con->line_cursor,
											t_con->line + t_con->line_cursor + 1,
											t_con->line_size -
											t_con->line_cursor);

									telnet_write(connection,
											t_con->line + t_con->line_cursor,
											t_con->line_size -
											t_con->line_cursor);
									telnet_write(connection, " \b", 2);
									for (i = t_con->line_cursor; i < t_con->line_size; i++)
										telnet_write(connection, "\b", 1);
								} else {
									t_con->line_size--;
									t_con->line_cursor--;
									/* back space: move the 'printer' head one char
									 * back, overwrite with space, move back again */
									telnet_write(connection, "\b \b", 3);
								}
							}
						} else if (*buf_p == 0x15) /* clear line */
							telnet_clear_line(connection, t_con);
						else if (*buf_p == CTRL('B')) {	/* cursor left */
							if (t_con->line_cursor > 0) {
								telnet_write(connection, "\b", 1);
								t_con->line_cursor--;
							}
							t_con->state = TELNET_STATE_DATA;
						} else if (*buf_p == CTRL('F')) {	/* cursor right */
							if (t_con->line_cursor < t_con->line_size)
								telnet_write(connection, t_con->line + t_con->line_cursor++, 1);
							t_con->state = TELNET_STATE_DATA;
						} else if (*buf_p == CTRL('P'))		/* cursor up */
							telnet_history_up(connection);
						else if (*buf_p == CTRL('N'))		/* cursor down */
							telnet_history_down(connection);
						else
							LOG_DEBUG("unhandled nonprintable: %2.2x", *buf_p);
					}
				}
				break;
			case TELNET_STATE_IAC:
				switch (*buf_p) {
				case 0xfe:
					t_con->state = TELNET_STATE_DONT;
					break;
				case 0xfd:
					t_con->state = TELNET_STATE_DO;
					break;
				case 0xfc:
					t_con->state = TELNET_STATE_WONT;
					break;
				case 0xfb:
					t_con->state = TELNET_STATE_WILL;
					break;
				}
				break;
			case TELNET_STATE_SB:
				break;
			case TELNET_STATE_SE:
				break;
			case TELNET_STATE_WILL:
			case TELNET_STATE_WONT:
			case TELNET_STATE_DO:
			case TELNET_STATE_DONT:
				t_con->state = TELNET_STATE_DATA;
				break;
			case TELNET_STATE_ESCAPE:
				if (t_con->last_escape == '[') {
					if (*buf_p == 'D') {	/* cursor left */
						if (t_con->line_cursor > 0) {
							telnet_write(connection, "\b", 1);
							t_con->line_cursor--;
						}
						t_con->state = TELNET_STATE_DATA;
					} else if (*buf_p == 'C') {	/* cursor right */
						if (t_con->line_cursor < t_con->line_size)
							telnet_write(connection,
									t_con->line + t_con->line_cursor++, 1);
						t_con->state = TELNET_STATE_DATA;
					} else if (*buf_p == 'A') {	/* cursor up */
						telnet_history_up(connection);
					} else if (*buf_p == 'B') {	/* cursor down */
						telnet_history_down(connection);
					} else if (*buf_p == '3')
						t_con->last_escape = *buf_p;
					else
						t_con->state = TELNET_STATE_DATA;
				} else if (t_con->last_escape == '3') {
					/* Remove character */
					if (*buf_p == '~') {
						if (t_con->line_cursor < t_con->line_size) {
							int i;
							t_con->line_size--;
							/* remove char from line buffer */
							memmove(t_con->line + t_con->line_cursor,
									t_con->line + t_con->line_cursor + 1,
									t_con->line_size - t_con->line_cursor);

							/* print remainder of buffer */
							telnet_write(connection, t_con->line + t_con->line_cursor,
									t_con->line_size - t_con->line_cursor);
							/* overwrite last char with whitespace */
							telnet_write(connection, " \b", 2);

							/* move back to cursor position*/
							for (i = t_con->line_cursor; i < t_con->line_size; i++)
								telnet_write(connection, "\b", 1);
						}

						t_con->state = TELNET_STATE_DATA;
					} else
						t_con->state = TELNET_STATE_DATA;
				} else if (t_con->last_escape == '\x00') {
					if (*buf_p == '[')
						t_con->last_escape = *buf_p;
					else
						t_con->state = TELNET_STATE_DATA;
				} else {
					LOG_ERROR("BUG: unexpected value in t_con->last_escape");
					t_con->state = TELNET_STATE_DATA;
				}

				break;
			default:
				LOG_ERROR("unknown telnet state");
				return ERROR_FAIL;
		}

		bytes_read--;
		buf_p++;
	}

	return ERROR_OK;
}
Пример #7
0
static int tcl_input(struct connection *connection)
{
	Jim_Interp *interp = (Jim_Interp *)connection->cmd_ctx->interp;
	int retval;
	int i;
	ssize_t rlen;
	const char *result;
	int reslen;
	struct tcl_connection *tclc;
	unsigned char in[256];

	rlen = connection_read(connection, &in, sizeof(in));
	if (rlen <= 0) {
		if (rlen < 0)
			LOG_ERROR("error during read: %s", strerror(errno));
		return ERROR_SERVER_REMOTE_CLOSED;
	}

	tclc = connection->priv;
	if (tclc == NULL)
		return ERROR_CONNECTION_REJECTED;

	/* push as much data into the line as possible */
	for (i = 0; i < rlen; i++)
	{
		/* buffer the data */
		tclc->tc_line[tclc->tc_lineoffset] = in[i];
		if (tclc->tc_lineoffset < TCL_MAX_LINE)
			tclc->tc_lineoffset++;
		else
			tclc->tc_linedrop = 1;

		/* ctrl-z is end of command. When testing from telnet, just
		 * press ctrl-z a couple of times first to put telnet into the
		 * mode where it will send 0x1a in response to pressing ctrl-z
		 */
		if (in[i] != '\x1a')
			continue;

		/* process the line */
		if (tclc->tc_linedrop) {
#define ESTR "line too long\n"
			retval = tcl_output(connection, ESTR, sizeof(ESTR));
			if (retval != ERROR_OK)
				return retval;
#undef ESTR
		}
		else {
			tclc->tc_line[tclc->tc_lineoffset-1] = '\0';
			LOG_DEBUG("Executing script:\n %s", tclc->tc_line);
			retval = Jim_Eval_Named(interp, tclc->tc_line, "remote:connection",1);
			LOG_DEBUG("Result: %d\n %s", retval, Jim_GetString(Jim_GetResult(interp), &reslen));
			result = Jim_GetString(Jim_GetResult(interp), &reslen);
			retval = tcl_output(connection, result, reslen);
			if (retval != ERROR_OK)
				return retval;
			/* Always output ctrl-d as end of line to allow multiline results */
			tcl_output(connection, "\x1a", 1);
		}

		tclc->tc_lineoffset = 0;
		tclc->tc_linedrop = 0;
	}

	return ERROR_OK;
}
Пример #8
0
int lwm2m_client_cb(void *args)
{
	int argc;
	char **argv;

	int i;
	int result;
	int opt;
	char *name = "testlwm2mclient";

#ifdef WITH_MBEDTLS
	unsigned char psk[MBEDTLS_PSK_MAX_LEN];

	/* set default tls option */

	/*
	 * if you want to change auth_mode, please change 3rd parameter of tls_opt structure
	 * - auth_mode can be configured (2: mandatory 1: optional, 0: not verify)
	 */
	tls_opt option = {MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, 0, 1, NULL, };
	/* set cipher suite to all*/
	option.force_ciphersuites[0] = mbedtls_ssl_get_ciphersuite_id(LWM2M_CIPHERSUIT);
	option.force_ciphersuites[1] = 0;
#endif

	struct timeval tv = {60, 0};
	argc = ((struct pthread_arg *)args)->argc;
	argv = ((struct pthread_arg *)args)->argv;

	lwm2mH = NULL;
	g_quit = 0;
	server = DEFAULT_SERVER_IPV4;
	serverPort = LWM2M_STANDARD_PORT_STR;
	/* Setting up the command line interface. */
	command_desc_t commands[] = {
		{"list", "List known servers.", NULL, prv_output_servers, NULL},
		{
			"change", "Change the value of resource.", " change URI [DATA]\r\n"
			"   URI: uri of the resource such as /3/0, /3/0/2\r\n"
			"   DATA: (optional) new value\r\n", prv_change, NULL
		},
		{
			"update", "Trigger a registration update", " update SERVER\r\n"
			"   SERVER: short server id such as 123\r\n", prv_update, NULL
		},
		{"ls", "List Objects and Instances", NULL, prv_object_list, NULL},
		{
			"dump", "Dump an Object", "dump URI"
			"URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL
		},
		{"add", "Add support of object 1024", NULL, prv_add, NULL},
		{"rm", "Remove support of object 1024", NULL, prv_remove, NULL},
		{"quit", "Quit the client gracefully.", NULL, prv_quit, NULL},
		{"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL},
		COMMAND_END_LIST
	};

	memset(&data, 0, sizeof(client_data_t));
	data.addressFamily = AF_INET;

	opt = 1;
	while (opt < argc) {
		if (argv[opt] == NULL
			|| argv[opt][0] != '-'
			|| argv[opt][2] != 0) {
			print_usage();
			return 0;
		}
		switch (argv[opt][1]) {
		case 't':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			if (1 != sscanf(argv[opt], "%d", &g_lifetime)) {
				print_usage();
				return 0;
			}
			break;
#ifdef WITH_MBEDTLS
		case 'i':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			g_pskId = argv[opt];
			break;
		case 's':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			g_pskBuffer = argv[opt];
			break;
#endif
		case 'h':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			server = argv[opt];
			break;
		default:
			print_usage();
			return 0;
		}
		opt += 1;
	}

	/* Parse server URI to distinguish protocol and server address */
	g_proto = coap_get_protocol_from_uri(server);
	if (g_proto >= COAP_PROTOCOL_MAX) {
		printf("Not supported protocol : %d\n", g_proto);
		return -1;
	}

	/* Move pointer to address field */
	server += strlen(coap_uri_prefix[g_proto]);
	serverPort = coap_get_port_from_proto(g_proto);

	if (lwm2m_init_object() < 0) {
	}

	/* This call an internal function that create an socket. */
	printf("Trying to bind LWM2M Client to port %s\n", serverPort);
	data.sock = create_socket(g_proto, serverPort, data.addressFamily);
	if (data.sock < 0) {
		fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno));
		return -1;
	}

#ifdef WITH_MBEDTLS
	if (g_proto == COAP_TCP_TLS || g_proto == COAP_UDP_DTLS) {

		/* Set Transport layer (TCP or UDP) */
		switch (g_proto) {
		case COAP_TCP_TLS:
			option.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
			break;
		case COAP_UDP_DTLS:
			option.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
			break;
		default:
			break;
		}
		data.tls_opt = &option;

		/* Set credential information */
		tls_cred cred;
		memset(&cred, 0, sizeof(tls_cred));

		if (g_pskBuffer) {
			if (lwm2m_unhexify(psk, g_pskBuffer, &cred.psk_len) == 0) {
				if (g_pskId) {
					cred.psk_identity = g_pskId;
					cred.psk = psk;
				}
			}
			if (cred.psk_identity == NULL && cred.psk == NULL) {
				printf("failed to set psk info\n");
				goto exit;
			}
		} else {
			printf("Please set psk and psk_id\n");
			goto exit;
		}

		data.tls_context = TLSCtx(&cred);
		if (data.tls_context == NULL) {
			printf("TLS context initialize failed\n");
			goto exit;
		}
	}
#endif
	if ((lwm2mH = lwm2m_init(&data)) == NULL) {
		printf("lwm2m_init2() failed\n");
		goto exit;
	}
	lwm2mH->protocol = g_proto;

	if ((result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray)) != 0) {
		printf("lwm2m_configure() failed: 0x%X\n", result);
		goto exit;
	}

	/* Register the command line command */
	for (i = 0 ; commands[i].name != NULL ; i++) {
		commands[i].userData = (void *)lwm2mH;
	}
	printf("LWM2M Client \"%s\" started on port %s\n>  ", name, serverPort);

	/* We now enter in a while loop that will handle the communications from the server */
	while (0 == g_quit) {
		tv.tv_sec = 60;
		tv.tv_usec = 0;

		if ((result = lwm2m_step(lwm2mH, &(tv.tv_sec))) != 0) {
			printf("lwm2m_step() failed: 0x%X\n", result);
			goto exit;
		} else {
			printf(" -> State: %s\n", g_step[lwm2mH->state]);
		}

		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(data.sock, &readfds);
		FD_SET(STDIN_FILENO, &readfds);

		result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv);
		if (result < 0) {
			if (errno != EINTR) {
				fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno));
			}
		} else if (result > 0) {
			uint8_t buffer[MAX_PACKET_SIZE];
			int numBytes;

			if (FD_ISSET(data.sock, &readfds)) {
				client_data_t *user_data = lwm2mH->userData;

				numBytes = connection_read(g_proto, user_data->connP, data.sock, buffer, MAX_PACKET_SIZE, NULL, 0);

				if (numBytes > 0) {
					output_buffer(stderr, buffer, numBytes, 0);
					lwm2m_handle_packet(lwm2mH, buffer, numBytes, user_data->connP);
					conn_s_updateRxStatistic(objArray[7], numBytes, false);
				} else {
					printf("received bytes ignored!\n");
				}
				/* If the event happened on the SDTIN */
			} else if (FD_ISSET(STDIN_FILENO, &readfds)) {
				numBytes = read_input_command_line((char *)buffer);
				if (numBytes > 1) {
					buffer[numBytes] = 0;
					handle_command(commands, (char *)buffer);
				}
				if (g_quit == 0) {
					fprintf(stdout, "\r\n> ");
					fflush(stdout);
				}
			}
		}
	}

exit:
	if (g_quit && lwm2mH) {
		lwm2m_close(lwm2mH);
		sleep(1);
	}

#ifdef WITH_MBEDTLS
	if (data.tls_context) {
		TLSCtx_free(data.tls_context);
	}
#endif

	if (data.sock >= 0) {
		printf("Closing %d\n", data.sock);
		shutdown(data.sock, 3);
		if ((i = close(data.sock)) != 0) {
			printf("Fail to close %d\n", errno);
		}
	}

	if (data.connP) {
		connection_free(data.connP);
	}

	clean_security_object(objArray[0]);
	clean_server_object(objArray[1]);
	free_object_device(objArray[2]);
	free_object_firmware(objArray[3]);
	free_object_location(objArray[4]);
	free_test_object(objArray[5]);
	free_object_conn_m(objArray[6]);
	free_object_conn_s(objArray[7]);
	acl_ctrl_free_object(objArray[8]);
	lwm2m_free(objArray[0]);
	lwm2m_free(objArray[1]);

	return 0;
}
Пример #9
0
static void *
slapd_daemon_task(
	void *ptr
)
{
	int l;
	time_t	last_idle_check = 0;
	struct timeval idle;
	time( &starttime );

#define SLAPD_IDLE_CHECK_LIMIT 4

	if ( global_idletimeout > 0 ) {
		last_idle_check = slap_get_time();
		/* Set the select timeout.
		 * Don't just truncate, preserve the fractions of
		 * seconds to prevent sleeping for zero time.
		 */
		idle.tv_sec = global_idletimeout/SLAPD_IDLE_CHECK_LIMIT;
		idle.tv_usec = global_idletimeout - idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT;
		idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
	} else {
		idle.tv_sec = 0;
		idle.tv_usec = 0;
	}

	for ( l = 0; slap_listeners[l] != NULL; l++ ) {
		if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
			continue;
#ifdef LDAP_CONNECTIONLESS
		/* Since this is connectionless, the data port is the
		 * listening port. The listen() and accept() calls
		 * are unnecessary.
		 */
		if ( slap_listeners[l]->sl_is_udp ) {
			slapd_add( slap_listeners[l]->sl_sd );
			continue;
		}
#endif

		if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN ) == -1 ) {
			int err = sock_errno();

#ifdef LDAP_PF_INET6
			/* If error is EADDRINUSE, we are trying to listen to INADDR_ANY and
			 * we are already listening to in6addr_any, then we want to ignore
			 * this and continue.
			 */
			if ( err == EADDRINUSE ) {
				int i;
				struct sockaddr_in sa = slap_listeners[l]->sl_sa.sa_in_addr;
				struct sockaddr_in6 sa6;
				
				if ( sa.sin_family == AF_INET &&
				     sa.sin_addr.s_addr == htonl(INADDR_ANY) ) {
					for ( i = 0 ; i < l; i++ ) {
						sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
						if ( sa6.sin6_family == AF_INET6 &&
						     !memcmp( &sa6.sin6_addr, &in6addr_any, sizeof(struct in6_addr) ) )
							break;
					}

					if ( i < l ) {
						/* We are already listening to in6addr_any */
#ifdef NEW_LOGGING
						LDAP_LOG(CONNECTION, WARNING,
							   "slapd_daemon_task: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n", 0, 0, 0 );
#else
						Debug( LDAP_DEBUG_CONNS,
						       "daemon: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n",
						       0, 0, 0 );
#endif
						slapd_close( slap_listeners[l]->sl_sd );
						slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
						continue;
					}
				}
			}
#endif				
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, ERR, 
				"slapd_daemon_task: listen( %s, 5 ) failed errno=%d (%s)\n",
				slap_listeners[l]->sl_url.bv_val, err, sock_errstr(err) );
#else
			Debug( LDAP_DEBUG_ANY,
				"daemon: listen(%s, 5) failed errno=%d (%s)\n",
					slap_listeners[l]->sl_url.bv_val, err,
					sock_errstr(err) );
#endif
			return( (void*)-1 );
		}

		slapd_add( slap_listeners[l]->sl_sd );
	}

#ifdef HAVE_NT_SERVICE_MANAGER
	if ( started_event != NULL ) {
		ldap_pvt_thread_cond_signal( &started_event );
	}
#endif
	/* initialization complete. Here comes the loop. */

	while ( !slapd_shutdown ) {
		ber_socket_t i;
		int ns;
		int at;
		ber_socket_t nfds;
#define SLAPD_EBADF_LIMIT 16
		int ebadf = 0;

		time_t	now;

		fd_set			readfds;
		fd_set			writefds;
		Sockaddr		from;

		struct timeval		tv;
		struct timeval		*tvp;

		now = slap_get_time();

		if( ( global_idletimeout > 0 ) &&
			difftime( last_idle_check +
			global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) {
			connections_timeout_idle( now );
			last_idle_check = now;
		}
		tv = idle;

#ifdef SIGHUP
		if( slapd_gentle_shutdown ) {
			ber_socket_t active;

			if( slapd_gentle_shutdown == 1 ) {
				Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
				close_listeners( 1 );
				global_restrictops |= SLAP_RESTRICT_OP_WRITES;
				slapd_gentle_shutdown = 2;
			}

			ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
			active = slap_daemon.sd_nactives;
			ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
			if( active == 0 ) {
				slapd_shutdown = 2;
				break;
			}
		}
#endif

		FD_ZERO( &writefds );
		FD_ZERO( &readfds );

		at = 0;

		ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );

#ifdef FD_SET_MANUAL_COPY
		for( s = 0; s < nfds; s++ ) {
			if(FD_ISSET( &slap_sd_readers, s )) {
				FD_SET( s, &readfds );
			}
			if(FD_ISSET( &slap_sd_writers, s )) {
				FD_SET( s, &writefds );
			}
		}
#else
		AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) );
		AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) );
#endif
		assert(!FD_ISSET(wake_sds[0], &readfds));
		FD_SET( wake_sds[0], &readfds );

		for ( l = 0; slap_listeners[l] != NULL; l++ ) {
			if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
				continue;
			if ( slap_listeners[l]->sl_is_mute )
				FD_CLR( slap_listeners[l]->sl_sd, &readfds );
			else
			if (!FD_ISSET(slap_listeners[l]->sl_sd, &readfds))
			    FD_SET( slap_listeners[l]->sl_sd, &readfds );
		}

#ifndef HAVE_WINSOCK
		nfds = slap_daemon.sd_nfds;
#else
		nfds = dtblsize;
#endif
		if ( global_idletimeout && slap_daemon.sd_nactives )
			at = 1;

		ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );

		if ( !at )
			at = ldap_pvt_thread_pool_backload(&connection_pool);

#if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
		tvp = NULL;
#else
		tvp = at ? &tv : NULL;
#endif

		for ( l = 0; slap_listeners[l] != NULL; l++ ) {
			if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ||
			    slap_listeners[l]->sl_is_mute )
				continue;

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL1, 
				"slapd_daemon_task: select: listen=%d "
				"active_threads=%d tvp=%s\n",
				slap_listeners[l]->sl_sd, at, tvp == NULL ? "NULL" : "idle" );
#else
			Debug( LDAP_DEBUG_CONNS,
				"daemon: select: listen=%d active_threads=%d tvp=%s\n",
					slap_listeners[l]->sl_sd, at,
					tvp == NULL ? "NULL" : "idle" );
#endif
		}

		switch(ns = select( nfds, &readfds,
#ifdef HAVE_WINSOCK
			/* don't pass empty fd_set */
			( writefds.fd_count > 0 ? &writefds : NULL ),
#else
			&writefds,
#endif
			NULL, tvp ))
		{
		case -1: {	/* failure - try again */
				int err = sock_errno();

				if( err == EBADF
#ifdef WSAENOTSOCK
					/* you'd think this would be EBADF */
					|| err == WSAENOTSOCK
#endif
				) {
					if (++ebadf < SLAPD_EBADF_LIMIT)
						continue;
				}

				if( err != EINTR ) {
#ifdef NEW_LOGGING
					LDAP_LOG( CONNECTION, INFO, 
						"slapd_daemon_task: select failed (%d): %s\n",
						err, sock_errstr(err), 0 );
#else
					Debug( LDAP_DEBUG_CONNS,
						"daemon: select failed (%d): %s\n",
						err, sock_errstr(err), 0 );
#endif
					slapd_shutdown = 2;
				}
			}
			continue;

		case 0:		/* timeout - let threads run */
			ebadf = 0;
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2,
				   "slapd_daemon_task: select timeout - yielding\n", 0, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
			    0, 0, 0 );
#endif
			ldap_pvt_thread_yield();
			continue;

		default:	/* something happened - deal with it */
			if( slapd_shutdown ) continue;

			ebadf = 0;
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				   "slapd_daemon_task: activity on %d descriptors\n", ns, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
				ns, 0, 0 );
#endif
			/* FALL THRU */
		}

		if( FD_ISSET( wake_sds[0], &readfds ) ) {
			char c[BUFSIZ];
			tcp_read( wake_sds[0], c, sizeof(c) );
#if defined(NO_THREADS) || defined(HAVE_GNU_PTH)
			waking = 0;
#endif
			continue;
		}

		for ( l = 0; slap_listeners[l] != NULL; l++ ) {
			ber_socket_t s;
			socklen_t len = sizeof(from);
			long id;
			slap_ssf_t ssf = 0;
			char *authid = NULL;
#ifdef SLAPD_RLOOKUPS
			char hbuf[NI_MAXHOST];
#endif

			char	*dnsname = NULL;
			char	*peeraddr = NULL;
#ifdef LDAP_PF_LOCAL
			char	peername[MAXPATHLEN + sizeof("PATH=")];
#elif defined(LDAP_PF_INET6)
			char	peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")];
#else
			char	peername[sizeof("IP=255.255.255.255:65336")];
#endif /* LDAP_PF_LOCAL */

			peername[0] = '\0';

			if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
				continue;

			if ( !FD_ISSET( slap_listeners[l]->sl_sd, &readfds ) )
				continue;

#ifdef LDAP_CONNECTIONLESS
			if ( slap_listeners[l]->sl_is_udp ) {
				/* The first time we receive a query, we set this
				 * up as a "connection". It remains open for the life
				 * of the slapd.
				 */
				if ( slap_listeners[l]->sl_is_udp < 2 ) {
				    id = connection_init(
					slap_listeners[l]->sl_sd,
				    	slap_listeners[l], "", "",
					2, ssf, authid );
				    slap_listeners[l]->sl_is_udp++;
				}
				continue;
			}
#endif

			/* Don't need to look at this in the data loops */
			FD_CLR( slap_listeners[l]->sl_sd, &readfds );
			FD_CLR( slap_listeners[l]->sl_sd, &writefds );

			s = accept( slap_listeners[l]->sl_sd,
				(struct sockaddr *) &from, &len );
			if ( s == AC_SOCKET_INVALID ) {
				int err = sock_errno();

				if(
#ifdef EMFILE
				    err == EMFILE ||
#endif
#ifdef ENFILE
				    err == ENFILE ||
#endif
				    0 )
				{
					ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
					emfile++;
					/* Stop listening until an existing session closes */
					slap_listeners[l]->sl_is_mute = 1;
					ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
				}

#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, ERR, 
					"slapd_daemon_task: accept(%ld) failed errno=%d (%s)\n",
					(long)slap_listeners[l]->sl_sd, 
					err, sock_errstr(err) );
#else
				Debug( LDAP_DEBUG_ANY,
					"daemon: accept(%ld) failed errno=%d (%s)\n",
					(long) slap_listeners[l]->sl_sd, err,
					sock_errstr(err) );
#endif
				ldap_pvt_thread_yield();
				continue;
			}

#ifndef HAVE_WINSOCK
			/* make sure descriptor number isn't too great */
			if ( s >= dtblsize ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, ERR, 
				   "slapd_daemon_task: %ld beyond descriptor table size %ld\n",
				   (long)s, (long)dtblsize, 0 );
#else
				Debug( LDAP_DEBUG_ANY,
					"daemon: %ld beyond descriptor table size %ld\n",
					(long) s, (long) dtblsize, 0 );
#endif

				slapd_close(s);
				ldap_pvt_thread_yield();
				continue;
			}
#endif

#ifdef LDAP_DEBUG
			ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );

			/* newly accepted stream should not be in any of the FD SETS */
			assert( !FD_ISSET( s, &slap_daemon.sd_actives) );
			assert( !FD_ISSET( s, &slap_daemon.sd_readers) );
			assert( !FD_ISSET( s, &slap_daemon.sd_writers) );

			ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
#endif

#if defined( SO_KEEPALIVE ) || defined( TCP_NODELAY )
#ifdef LDAP_PF_LOCAL
			/* for IPv4 and IPv6 sockets only */
			if ( from.sa_addr.sa_family != AF_LOCAL )
#endif /* LDAP_PF_LOCAL */
			{
				int rc;
				int tmp;
#ifdef SO_KEEPALIVE
				/* enable keep alives */
				tmp = 1;
				rc = setsockopt( s, SOL_SOCKET, SO_KEEPALIVE,
					(char *) &tmp, sizeof(tmp) );
				if ( rc == AC_SOCKET_ERROR ) {
					int err = sock_errno();
#ifdef NEW_LOGGING
					LDAP_LOG( CONNECTION, ERR, 
						"slapd_daemon_task: setsockopt( %ld, SO_KEEPALIVE)"
					   " failed errno=%d (%s)\n",
						(long)s, err, sock_errstr(err) );
#else
					Debug( LDAP_DEBUG_ANY,
						"slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
						"errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
#endif
				}
#endif
#ifdef TCP_NODELAY
				/* enable no delay */
				tmp = 1;
				rc = setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
					(char *)&tmp, sizeof(tmp) );
				if ( rc == AC_SOCKET_ERROR ) {
					int err = sock_errno();
#ifdef NEW_LOGGING
					LDAP_LOG( CONNECTION, ERR, 
						"slapd_daemon_task: setsockopt( %ld, "
						"TCP_NODELAY) failed errno=%d (%s)\n",
						(long)s, err, sock_errstr(err) );
#else
					Debug( LDAP_DEBUG_ANY,
						"slapd(%ld): setsockopt(TCP_NODELAY) failed "
						"errno=%d (%s)\n", (long) s, err, sock_errstr(err) );
#endif
				}
#endif
			}
#endif

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL1, 
				"slapd_daemon_task: new connection on %ld\n", (long)s, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n",
				(long) s, 0, 0 );
#endif
			switch ( from.sa_addr.sa_family ) {
#  ifdef LDAP_PF_LOCAL
			case AF_LOCAL:
				sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
				ssf = LDAP_PVT_SASL_LOCAL_SSF;
				{
					uid_t uid;
					gid_t gid;

					if( getpeereid( s, &uid, &gid ) == 0 ) {
						authid = ch_malloc(
							sizeof("uidnumber=4294967295+gidnumber=4294967295,"
								"cn=peercred,cn=external,cn=auth"));
						sprintf(authid, "uidnumber=%d+gidnumber=%d,"
							"cn=peercred,cn=external,cn=auth",
							(int) uid, (int) gid);
					}
				}
				dnsname = "local";
				break;
#endif /* LDAP_PF_LOCAL */

#  ifdef LDAP_PF_INET6
			case AF_INET6:
			if ( IN6_IS_ADDR_V4MAPPED(&from.sa_in6_addr.sin6_addr) ) {
				peeraddr = inet_ntoa( *((struct in_addr *)
							&from.sa_in6_addr.sin6_addr.s6_addr[12]) );
				sprintf( peername, "IP=%s:%d",
					 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
					 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
			} else {
				char addr[INET6_ADDRSTRLEN];

				peeraddr = (char *) inet_ntop( AF_INET6,
						      &from.sa_in6_addr.sin6_addr,
						      addr, sizeof addr );
				sprintf( peername, "IP=%s %d",
					 peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
					 (unsigned) ntohs( from.sa_in6_addr.sin6_port ) );
			}
			break;
#  endif /* LDAP_PF_INET6 */

			case AF_INET:
			peeraddr = inet_ntoa( from.sa_in_addr.sin_addr );
			sprintf( peername, "IP=%s:%d",
				peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
				(unsigned) ntohs( from.sa_in_addr.sin_port ) );
				break;

			default:
				slapd_close(s);
				continue;
			}

			if ( ( from.sa_addr.sa_family == AF_INET )
#ifdef LDAP_PF_INET6
				|| ( from.sa_addr.sa_family == AF_INET6 )
#endif
			) {
#ifdef SLAPD_RLOOKUPS
				if ( use_reverse_lookup ) {
					char *herr;
					if (ldap_pvt_get_hname( (const struct sockaddr *)&from, len, hbuf,
						sizeof(hbuf), &herr ) == 0) {
						ldap_pvt_str2lower( hbuf );
						dnsname = hbuf;
					}
				}
#else
				dnsname = NULL;
#endif /* SLAPD_RLOOKUPS */

#ifdef HAVE_TCPD
				if ( !hosts_ctl("slapd",
						dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
						peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
						SLAP_STRING_UNKNOWN ))
				{
					/* DENY ACCESS */
					Statslog( LDAP_DEBUG_STATS,
						"fd=%ld DENIED from %s (%s)\n",
						(long) s,
						dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
						peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
						0, 0 );
					slapd_close(s);
					continue;
				}
#endif /* HAVE_TCPD */
			}

			id = connection_init(s,
				slap_listeners[l],
				dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
				peername,
#ifdef HAVE_TLS
				slap_listeners[l]->sl_is_tls,
#else
				0,
#endif
				ssf,
				authid );

			if( authid ) ch_free(authid);

			if( id < 0 ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, INFO, 
					"slapd_daemon_task: "
					"connection_init(%ld, %s, %s) "
					"failed.\n",
					(long)s, peername, 
					slap_listeners[l]->sl_name.bv_val );
#else
				Debug( LDAP_DEBUG_ANY,
					"daemon: connection_init(%ld, %s, %s) "
					"failed.\n",
					(long) s,
					peername,
					slap_listeners[l]->sl_name.bv_val );
#endif
				slapd_close(s);
				continue;
			}

			Statslog( LDAP_DEBUG_STATS,
				"conn=%ld fd=%ld ACCEPT from %s (%s)\n",
				id, (long) s,
				peername,
				slap_listeners[l]->sl_name.bv_val,
				0 );

			slapd_add( s );
			continue;
		}

#ifdef LDAP_DEBUG
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, DETAIL2,
			   "slapd_daemon_task: activity on ", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
#endif
#ifdef HAVE_WINSOCK
		for ( i = 0; i < readfds.fd_count; i++ ) {
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				" %d%s", readfds.fd_array[i], "r", 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS, " %d%s",
				readfds.fd_array[i], "r", 0 );
#endif
		}
		for ( i = 0; i < writefds.fd_count; i++ ) {
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				" %d%s", writefds.fd_array[i], "w" , 0 );
#else
			Debug( LDAP_DEBUG_CONNS, " %d%s",
				writefds.fd_array[i], "w", 0 );
#endif
		}

#else
		for ( i = 0; i < nfds; i++ ) {
			int	r, w;

			r = FD_ISSET( i, &readfds );
			w = FD_ISSET( i, &writefds );
			if ( r || w ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, DETAIL2, 
					" %d%s%s", i, r ? "r" : "", w ? "w" : "" );
#else
				Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
				    r ? "r" : "", w ? "w" : "" );
#endif
			}
		}
#endif
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, DETAIL2, "\n", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
#endif

#endif

		/* loop through the writers */
#ifdef HAVE_WINSOCK
		for ( i = 0; i < writefds.fd_count; i++ )
#else
		for ( i = 0; i < nfds; i++ )
#endif
		{
			ber_socket_t wd;
#ifdef HAVE_WINSOCK
			wd = writefds.fd_array[i];
#else
			if( ! FD_ISSET( i, &writefds ) ) {
				continue;
			}
			wd = i;
#endif

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				"slapd_daemon_task: write active on %d\n", wd, 0, 0 );
#else
			Debug( LDAP_DEBUG_CONNS,
				"daemon: write active on %d\n",
				wd, 0, 0 );
#endif
			/*
			 * NOTE: it is possible that the connection was closed
			 * and that the stream is now inactive.
			 * connection_write() must valid the stream is still
			 * active.
			 */

			if ( connection_write( wd ) < 0 ) {
				FD_CLR( (unsigned) wd, &readfds );
				slapd_close( wd );
			}
		}

#ifdef HAVE_WINSOCK
		for ( i = 0; i < readfds.fd_count; i++ )
#else
		for ( i = 0; i < nfds; i++ )
#endif
		{
			ber_socket_t rd;
#ifdef HAVE_WINSOCK
			rd = readfds.fd_array[i];
#else
			if( ! FD_ISSET( i, &readfds ) ) {
				continue;
			}
			rd = i;
#endif

#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, DETAIL2, 
				"slapd_daemon_task: read activity on %d\n", rd, 0, 0 );
#else
			Debug ( LDAP_DEBUG_CONNS,
				"daemon: read activity on %d\n", rd, 0, 0 );
#endif
			/*
			 * NOTE: it is possible that the connection was closed
			 * and that the stream is now inactive.
			 * connection_read() must valid the stream is still
			 * active.
			 */

			if ( connection_read( rd ) < 0 ) {
				slapd_close( rd );
			}
		}
		ldap_pvt_thread_yield();
	}

	if( slapd_shutdown == 1 ) {
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, CRIT,
		   "slapd_daemon_task: shutdown requested and initiated.\n", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE,
			"daemon: shutdown requested and initiated.\n",
			0, 0, 0 );
#endif

	} else if ( slapd_shutdown == 2 ) {
#ifdef HAVE_NT_SERVICE_MANAGER
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, CRIT,
			   "slapd_daemon_task: shutdown initiated by Service Manager.\n",
			   0, 0, 0);
#else
			Debug( LDAP_DEBUG_TRACE,
			       "daemon: shutdown initiated by Service Manager.\n",
			       0, 0, 0);
#endif
#else /* !HAVE_NT_SERVICE_MANAGER */
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, CRIT,
			   "slapd_daemon_task: abnormal condition, "
			   "shutdown initiated.\n", 0, 0, 0 );
#else
			Debug( LDAP_DEBUG_TRACE,
			       "daemon: abnormal condition, shutdown initiated.\n",
			       0, 0, 0 );
#endif
#endif /* !HAVE_NT_SERVICE_MANAGER */
	} else {
#ifdef NEW_LOGGING
		LDAP_LOG( CONNECTION, CRIT,
		   "slapd_daemon_task: no active streams, shutdown initiated.\n", 
		   0, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE,
		       "daemon: no active streams, shutdown initiated.\n",
		       0, 0, 0 );
#endif
	}

	if( slapd_gentle_shutdown != 2 ) {
		close_listeners ( 0 );
	}

	free ( slap_listeners );
	slap_listeners = NULL;

	if( !slapd_gentle_shutdown ) {
		connections_shutdown();
	}

#ifdef NEW_LOGGING
	LDAP_LOG( CONNECTION, CRIT, 
		"slapd_daemon_task: shutdown waiting for %d threads to terminate.\n",
		ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
#else
	Debug( LDAP_DEBUG_ANY,
	    "slapd shutdown: waiting for %d threads to terminate\n",
	    ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
#endif
	ldap_pvt_thread_pool_destroy(&connection_pool, 1);

	return NULL;
}
Пример #10
0
static int jsp_input(struct connection *connection)
{
	int bytes_read;
	unsigned char buffer[TELNET_BUFFER_SIZE];
	unsigned char *buf_p;
	struct telnet_connection *t_con = connection->priv;
	struct jsp_service *jsp_service = connection->service->priv;

	bytes_read = connection_read(connection, buffer, TELNET_BUFFER_SIZE);

	if (bytes_read == 0)
		return ERROR_SERVER_REMOTE_CLOSED;
	else if (bytes_read == -1) {
		LOG_ERROR("error during read: %s", strerror(errno));
		return ERROR_SERVER_REMOTE_CLOSED;
	}

	buf_p = buffer;
	while (bytes_read) {
		switch (t_con->state) {
			case TELNET_STATE_DATA:
				if (*buf_p == 0xff)
					t_con->state = TELNET_STATE_IAC;
				else {
					int out_len = 1;
					int in_len;
					unsigned char in_buffer[10];
					or1k_adv_jtag_jsp_xfer(jsp_service->jtag_info,
							       &out_len, buf_p, &in_len,
							       in_buffer);
					if (in_len)
						telnet_write(connection,
							     in_buffer, in_len);
				}
				break;
			case TELNET_STATE_IAC:
				switch (*buf_p) {
				case 0xfe:
					t_con->state = TELNET_STATE_DONT;
					break;
				case 0xfd:
					t_con->state = TELNET_STATE_DO;
					break;
				case 0xfc:
					t_con->state = TELNET_STATE_WONT;
					break;
				case 0xfb:
					t_con->state = TELNET_STATE_WILL;
					break;
				}
				break;
			case TELNET_STATE_SB:
				break;
			case TELNET_STATE_SE:
				break;
			case TELNET_STATE_WILL:
			case TELNET_STATE_WONT:
			case TELNET_STATE_DO:
			case TELNET_STATE_DONT:
				t_con->state = TELNET_STATE_DATA;
				break;
			default:
				LOG_ERROR("unknown telnet state");
				exit(-1);
		}

		bytes_read--;
		buf_p++;
	}

	return ERROR_OK;
}
Пример #11
0
int urg_raw_read(urg_t *urg, char *data, int max_data_size, int timeout)
{
    return connection_read(&urg->connection, data, max_data_size, timeout);
}