blob: 73997ddc5bb6e616303b368a7499fc6fc1d57c37 [file] [log] [blame]
/** @file
WCCP router simulation for testing.
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <memory.h>
#include <strings.h>
#include <getopt.h>
#include "Wccp.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
static char const USAGE_TEXT[] = "%s\n"
"--address IP address to bind.\n"
"--help Print usage and exit.\n";
static bool Ready = true;
inline void
Error(char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
Ready = false;
}
int
main(int argc, char **argv)
{
wccp::Router wcp;
// Reading stdin support.
size_t in_size = 200;
char *in_buff = 0;
ssize_t in_count;
// getopt return values. Selected to avoid collisions with
// short arguments.
static int const OPT_ADDRESS = 257; ///< Bind to IP address option.
static int const OPT_HELP = 258; ///< Print help message.
static int const OPT_MD5 = 259; ///< MD5 key.
static option OPTIONS[] = {
{"address", 1, 0, OPT_ADDRESS}, {"md5", 1, 0, OPT_MD5}, {"help", 0, 0, OPT_HELP}, {0, 0, 0, 0} // required terminator.
};
in_addr ip_addr = {INADDR_ANY};
int zret; // getopt return.
int zidx; // option index.
bool fail = false;
char const *FAIL_MSG = "";
while (-1 != (zret = getopt_long_only(argc, argv, "", OPTIONS, &zidx))) {
switch (zret) {
case OPT_HELP:
FAIL_MSG = "Usage:";
fail = true;
break;
case '?':
FAIL_MSG = "Invalid option specified.";
fail = true;
break;
case OPT_ADDRESS:
if (0 == inet_aton(optarg, &ip_addr)) {
FAIL_MSG = "Invalid IP address specified for client.";
fail = true;
}
break;
case OPT_MD5:
wcp.useMD5Security(optarg);
break;
}
}
if (fail) {
printf(USAGE_TEXT, FAIL_MSG);
return 1;
}
if (!Ready)
return 4;
if (0 > wcp.open(ip_addr.s_addr)) {
fprintf(stderr, "Failed to open or bind socket.\n");
return 2;
}
static int const POLL_FD_COUNT = 2;
pollfd pfa[POLL_FD_COUNT];
// Poll on STDIN and the socket.
pfa[0].fd = STDIN_FILENO;
pfa[0].events = POLLIN;
pfa[1].fd = wcp.getSocket();
pfa[1].events = POLLIN;
while (true) {
int n = poll(pfa, POLL_FD_COUNT, wccp::TIME_UNIT * 1000);
if (n < 0) { // error
perror("General polling failure");
return 5;
} else if (n > 0) { // things of interest happened
if (pfa[1].revents) {
if (pfa[1].revents & POLLIN) {
wcp.handleMessage();
// wcp.sendPendingMessages();
} else {
fprintf(stderr, "Socket failure.\n");
return 6;
}
}
if (pfa[0].revents) {
if (pfa[0].revents & POLLIN) {
in_count = getline(&in_buff, &in_size, stdin);
fprintf(stderr, "Terminated from console.\n");
return 0;
}
}
} else { // timeout
// wcp.sendPendingMessages();
}
}
}