summaryrefslogtreecommitdiff
path: root/afserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'afserver.c')
-rw-r--r--afserver.c1195
1 files changed, 676 insertions, 519 deletions
diff --git a/afserver.c b/afserver.c
index 86fb85e..369ef69 100644
--- a/afserver.c
+++ b/afserver.c
@@ -28,19 +28,29 @@
#include <fcntl.h>
#include <signal.h>
#include <string.h>
-
+#include <sys/time.h>
#include <getopt.h>
static void usage(char* info);
static void sig_int(int);
+static void remove_client(RealmT*, int, fd_set*, fd_set*, int*);
+static int find_client(RealmT*, char);
+static int eval_numofcon(RealmT*, int, int);
+static int eval_usernum(ConnectclientT*, int);
+static int find_usernum(ConnectclientT*, int);
+static void check_value(int*, char*, char*);
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"hostname", 1, 0, 'n'},
{"listenport", 1, 0, 'l'},
{"manageport", 1, 0, 'm'},
+ {"timeout", 1, 0, 't'},
{"verbose", 0, 0, 'v'},
{"users", 1, 0, 'u'},
+ {"clients", 1, 0, 'C'},
+ {"usrpcli", 1, 0, 'U'},
+ {"climode", 1, 0, 'M'},
{"cerfile", 1, 0, 'c'},
{"keyfile", 1, 0, 'k'},
{"cfgfile", 1, 0, 'f'},
@@ -60,7 +70,7 @@ static ConfigurationT config;
int
main(int argc, char **argv)
{
- int i, j, n, flags, sent;
+ int i, j=0, k, n, flags, sent;
socklen_t len;
unsigned char buff[9000];
char hostname[100];
@@ -71,9 +81,12 @@ main(int argc, char **argv)
char* listen = NULL;
char* manage = NULL;
char* amount = NULL;
+ char* clients = NULL;
+ char* usrpcli = NULL;
+ char* clim = NULL;
char* filenam = NULL;
char* type = NULL;
- char* znak;
+ char* timeout = NULL;
unsigned char pass[4] = {1, 2, 3, 4};
char verbose = 0;
char mode = 0;
@@ -102,7 +115,7 @@ main(int argc, char **argv)
config.logging = 0;
config.logfnam = NULL;
- while ((n = getopt_long(argc, argv, "hn:l:m:vu:c:k:f:p:o:O:46", long_options, 0)) != -1) {
+ while ((n = getopt_long(argc, argv, "hn:l:m:vu:c:k:f:p:o:O:46t:C:U:M:", long_options, 0)) != -1) {
switch (n) {
case 'h': {
usage(AF_VER("Active port forwarder (server)"));
@@ -120,6 +133,10 @@ main(int argc, char **argv)
manage = optarg;
break;
}
+ case 't': {
+ timeout = optarg;
+ break;
+ }
case 'v': {
++verbose;
break;
@@ -128,6 +145,18 @@ main(int argc, char **argv)
amount = optarg;
break;
}
+ case 'C': {
+ clients = optarg;
+ break;
+ }
+ case 'U': {
+ usrpcli = optarg;
+ break;
+ }
+ case 'M': {
+ clim = optarg;
+ break;
+ }
case 'c': {
config.certif = optarg;
break;
@@ -146,7 +175,7 @@ main(int argc, char **argv)
}
case 'O': {
config.logfnam = optarg;
- config.logging = 2;
+ config.logging = 3;
break;
}
case 'o': {
@@ -162,14 +191,14 @@ main(int argc, char **argv)
TYPE_UNSET_ZLIB(mode);
break;
}
- case 303: {
- n = strlen(optarg);
- memset(pass, 0, 4);
- for (i = 0; i < n; ++i) {
- pass[i%4] += optarg[i];
- }
- break;
- }
+ case 303: {
+ n = strlen(optarg);
+ memset(pass, 0, 4);
+ for (i = 0; i < n; ++i) {
+ pass[i%4] += optarg[i];
+ }
+ break;
+ }
case '4': {
if (ipfam != 0) {
ipfam = -1;
@@ -222,9 +251,21 @@ main(int argc, char **argv)
if (manage == NULL) {
manage = "50126";
}
+ if (timeout == NULL) {
+ timeout = "5";
+ }
if (amount == NULL) {
amount = "5";
}
+ if (clients == NULL) {
+ clients = "1";
+ }
+ if (usrpcli == NULL) {
+ usrpcli = amount;
+ }
+ if (clim == NULL) {
+ clim = "1";
+ }
if (config.certif == NULL) {
config.certif = "cacert.pem";
}
@@ -240,6 +281,10 @@ main(int argc, char **argv)
config.realmtable[0].lisportnum = listen;
config.realmtable[0].manportnum = manage;
config.realmtable[0].users = amount;
+ config.realmtable[0].clients = clients;
+ config.realmtable[0].timeout = timeout;
+ config.realmtable[0].usrpcli = usrpcli;
+ config.realmtable[0].clim = clim;
memcpy(config.realmtable[0].pass, pass, 4);
if (strcmp(type, "tcp") == 0) {
TYPE_SET_TCP(config.realmtable[0].type);
@@ -273,9 +318,9 @@ main(int argc, char **argv)
exit(1);
}
if (SSL_CTX_use_RSAPrivateKey_file(ctx, config.keys, SSL_FILETYPE_PEM) != 1) {
- printf("Setting rsa key failed (%s)... exiting\n", config.keys);
- exit(1);
- }
+ printf("Setting rsa key failed (%s)... exiting\n", config.keys);
+ exit(1);
+ }
if (SSL_CTX_use_certificate_file(ctx, config.certif, SSL_FILETYPE_PEM) != 1) {
printf("Setting certificate failed (%s)... exiting\n", config.certif);
exit(1);
@@ -292,34 +337,54 @@ main(int argc, char **argv)
for (i = 0; i < config.size; ++i) {
if ((config.realmtable[i].hostname == NULL) ||
(config.realmtable[i].lisportnum == NULL) ||
- (config.realmtable[i].manportnum == NULL) ||
- (config.realmtable[i].users == NULL)) {
+ (config.realmtable[i].manportnum == NULL)) {
printf("Missing some of the configurable variables...\n");
- printf("\nRealm: %d\nhostname: %s\nlistenport: %s\nmanageport: %s\nusers: %s\n",
+ printf("\nRealm: %d\nhostname: %s\nlistenport: %s\nmanageport: %s\n",
i, config.realmtable[i].hostname,
config.realmtable[i].lisportnum,
- config.realmtable[i].manportnum,
- config.realmtable[i].users);
+ config.realmtable[i].manportnum);
exit(1);
}
+ /* checking type of the realm */
if (!TYPE_IS_SET(config.realmtable[i].type)) {
- printf("Unrecognized type of the realm... exiting\n");
- exit(1);
- }
- if ((( config.realmtable[i].usernum = strtol(config.realmtable[i].users, &znak, 10)) == LONG_MAX) || (config.realmtable[i].usernum == LONG_MIN)) {
- printf("Invalid user amount - %s\n", config.realmtable[i].users);
- exit(1);
+ TYPE_SET_TCP(config.realmtable[i].type);
}
- if (((*(config.realmtable[i].users)) == '\0') || (*znak != '\0')) {
- printf("Invalid user amount - %s\n", config.realmtable[i].users);
- exit(1);
- }
-
+ /* checking users amount */
+ if (config.realmtable[i].users == NULL) {
+ config.realmtable[i].users = "5";
+ }
+ check_value(&(config.realmtable[i].usernum), config.realmtable[i].users, "Invalid users amount");
+ /* checking clients amount */
+ if (config.realmtable[i].clients == NULL) {
+ config.realmtable[i].clients = "1";
+ }
+ check_value(&(config.realmtable[i].clinum), config.realmtable[i].clients, "Invalid clients amount");
+ /* checking usrpcli value */
+ if (config.realmtable[i].usrpcli == NULL) {
+ config.realmtable[i].usrpcli = config.realmtable[i].users;
+ }
+ check_value(&(config.realmtable[i].upcnum), config.realmtable[i].usrpcli, "Invalid usrpcli value");
+ /* checking timeout value */
+ if (config.realmtable[i].timeout == NULL) {
+ config.realmtable[i].timeout = "5";
+ }
+ check_value(&(config.realmtable[i].tmout), config.realmtable[i].timeout, "Invalid timeout value");
+ /* checking climode value */
+ if (config.realmtable[i].clim == NULL) {
+ config.realmtable[i].clim = "1";
+ }
+ check_value(&(config.realmtable[i].climode), config.realmtable[i].clim, "Invalid climode value");
+ /* allocating memory*/
config.realmtable[i].contable = calloc( config.realmtable[i].usernum, sizeof(ConnectuserT));
if (config.realmtable[i].contable == NULL) {
printf("Calloc error - try define smaller amount of users\n");
exit(1);
}
+ config.realmtable[i].clitable = calloc( config.realmtable[i].clinum, sizeof(ConnectclientT));
+ if (config.realmtable[i].clitable == NULL) {
+ printf("Calloc error - try define smaller amount of clients\n");
+ exit(1);
+ }
ipfam = 0x01;
if (TYPE_IS_IPV4(config.realmtable[i].type)) {
ipfam |= 0x02;
@@ -343,21 +408,35 @@ main(int argc, char **argv)
}
config.realmtable[i].cliaddr = malloc(config.realmtable[i].addrlen);
- config.realmtable[i].cliconn.ssl = SSL_new(ctx);
- if (config.realmtable[i].cliconn.ssl == NULL) {
- printf("Creating of ssl object failed... exiting\n");
- exit(1);
- }
+ for (j=0; j<config.realmtable[i].clinum; ++j) {
+ config.realmtable[i].clitable[j].cliconn.ssl = SSL_new(ctx);
+ if (config.realmtable[i].clitable[j].cliconn.ssl == NULL) {
+ printf("Creating of ssl object failed... exiting\n");
+ exit(1);
+ }
+ }
FD_SET(config.realmtable[i].managefd, &allset);
FD_SET(config.realmtable[i].listenfd, &allset);
maxfdp1 = (maxfdp1 > (config.realmtable[i].managefd+1)) ? maxfdp1 : (config.realmtable[i].managefd+1);
maxfdp1 = (maxfdp1 > (config.realmtable[i].listenfd+1)) ? maxfdp1 : (config.realmtable[i].listenfd+1);
config.realmtable[i].usercon = 0;
- config.realmtable[i].ready = 0;
- config.realmtable[i].tv.tv_sec = 5;
- config.realmtable[i].tv.tv_usec = 0;
- }
+ config.realmtable[i].clicon = 0;
+ for (j=0; j<config.realmtable[i].clinum; ++j) {
+ config.realmtable[i].clitable[j].ready = 0;
+ config.realmtable[i].clitable[j].tv.tv_sec = config.realmtable[i].tmout;
+ config.realmtable[i].clitable[j].tv.tv_usec = 0;
+ config.realmtable[i].clitable[j].usernum = config.realmtable[i].upcnum;
+ config.realmtable[i].clitable[j].users = malloc( config.realmtable[i].clitable[j].usernum * sizeof(int));
+ if (config.realmtable[i].clitable[j].users == NULL) {
+ printf("Calloc error - try define smaller amount of usrpcli (or users)\n");
+ exit(1);
+ }
+ for (k=0; k<config.realmtable[i].clitable[j].usernum; ++k) {
+ config.realmtable[i].clitable[j].users[k] = -1;
+ }
+ }
+ }
if (loginit(verbose, config.logging, config.logfnam)) {
printf("Can't open file to log to... exiting\n");
@@ -375,18 +454,24 @@ main(int argc, char **argv)
aflog(3, ">select, maxfdp1: %d", maxfdp1);
if (manconnecting) {
/* find out, in what realm client is trying to connect */
- for (i = 0; i < config.size; ++i) {
- if ((config.realmtable[i].ready == 1) || (config.realmtable[i].ready == 2)) {
- break; /* so i points to first good realm */
- }
+ for (k = 0; k < config.size; ++k) {
+ for (j=0; j < config.realmtable[k].clinum; ++j) {
+ if ((config.realmtable[k].clitable[j].ready == 1) || (config.realmtable[k].clitable[j].ready == 2)) {
+ i = k;
+ k = config.size;
+ break; /* so i points to first good realm and j to good client */
+ }
+ }
}
- if (select(maxfdp1, &rset, &tmpset, NULL, (&(config.realmtable[i].tv))) == 0) {
- close (config.realmtable[i].cliconn.commfd);
- FD_CLR(config.realmtable[i].cliconn.commfd, &allset);
+ if (select(maxfdp1, &rset, &tmpset, NULL, (&(config.realmtable[i].clitable[j].tv))) == 0) {
+ close (config.realmtable[i].clitable[j].cliconn.commfd);
+ FD_CLR(config.realmtable[i].clitable[j].cliconn.commfd, &allset);
FD_SET(config.realmtable[i].managefd, &allset);
- config.realmtable[i].ready = 0;
+ SSL_clear(config.realmtable[i].clitable[j].cliconn.ssl);
+ config.realmtable[i].clitable[j].ready = 0;
manconnecting--;
- aflog(1, " realm[%d]: SSL_accept failed (timeout)", i);
+ config.realmtable[i].clicon--;
+ aflog(1, " realm[%d]: client[%d]: SSL_accept failed (timeout)", i, j);
}
}
else {
@@ -397,125 +482,131 @@ main(int argc, char **argv)
for (j = 0; j < config.size; ++j) {
pointer = (&(config.realmtable[j]));
for (i = 0; i <pointer->usernum; ++i) {
- if ((pointer->contable[i].state == S_STATE_OPEN) ||
- (pointer->contable[i].state == S_STATE_STOPPED))
- if (FD_ISSET(pointer->contable[i].connfd, &rset)) {
- aflog(3, " realm[%d]: user[%d]: FD_ISSET", j, i);
- if (TYPE_IS_TCP(pointer->type)) { /* forwarding tcp packets */
- n = read(pointer->contable[i].connfd, &buff[5], 8091);
- if (n == -1)
- n = 0;
- if (n) {
- aflog(2, " realm[%d]: FROM user[%d]: MESSAGE length=%d", j, i, n);
- if ((buff[5] == AF_S_MESSAGE) &&
- (buff[6] == AF_S_LOGIN) &&
- (buff[7] == AF_S_MESSAGE)) {
- aflog(2, " WARNING: got packet similiar to udp");
- }
- buff[0] = AF_S_MESSAGE; /* sending message */
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- buff[3] = n >> 8; /* high bits of message length */
- buff[4] = n; /* low bits of message length */
- send_message(pointer->type, pointer->cliconn, buff, n+5);
- }
- else {
- aflog(1, " realm[%d]: user[%d]: CLOSED", j, i);
- aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
+ if ((pointer->contable[i].state == S_STATE_OPEN) || (pointer->contable[i].state == S_STATE_STOPPED))
+ if (FD_ISSET(pointer->contable[i].connfd, &rset)) {
+ k = eval_usernum(&(pointer->clitable[pointer->contable[i].whatcli]), i);
+ aflog(3, " realm[%d]: client[%d]: user[%d]: FD_ISSET", j, pointer->contable[i].whatcli, k);
+ if (TYPE_IS_TCP(pointer->type)) { /* forwarding tcp packets */
+ n = read(pointer->contable[i].connfd, &buff[5], 8091);
+ if (n == -1) {
+ aflog(3, " realm[%d]: client[%d]: user[%d]: READ ERROR (%d)", j,
+ pointer->contable[i].whatcli, k, errno);
+ n = 0;
+ }
+ if (n) {
+ aflog(2, " realm[%d]: client[%d]: FROM user[%d]: MESSAGE length=%d", j,
+ pointer->contable[i].whatcli, k, n);
+ if ((buff[5] == AF_S_MESSAGE) && (buff[6] == AF_S_LOGIN) && (buff[7] == AF_S_MESSAGE)) {
+ aflog(2, " WARNING: got packet similiar to udp");
+ }
+ buff[0] = AF_S_MESSAGE; /* sending message */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, n+5);
+ }
+ else {
+ aflog(1, " realm[%d]: client[%d]: user[%d]: CLOSED", j, pointer->contable[i].whatcli, k);
+ aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
pointer->contable[i].portbuf);
- close(pointer->contable[i].connfd);
- FD_CLR(pointer->contable[i].connfd, &allset);
- FD_CLR(pointer->contable[i].connfd, &wset);
- pointer->contable[i].state = S_STATE_CLOSING;
- freebuflist(&pointer->contable[i].head);
- buff[0] = AF_S_CONCLOSED; /* closing connection */
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- }
- else { /* when forwarding udp packets */
- n = readn(pointer->contable[i].connfd, buff, 5 );
- if (n != 5) {
- n = 0;
- }
- if (n) {
- if ((buff[0] == AF_S_MESSAGE) && (buff[1] == AF_S_LOGIN)
- && (buff[2] == AF_S_MESSAGE)) {
- length = buff[3];
- length = length << 8;
- length += buff[4]; /* this is length of message */
- if ((n = readn(pointer->contable[i].connfd, &buff[5], length)) != 0) {
- aflog(2, " realm[%d]: FROM user[%d]: MESSAGE length=%d", j, i, n);
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, n+5);
- }
- }
- else {
- n = 0;
- }
- }
-
- if (n == 0) {
- aflog(1, " realm[%d]: user[%d]: CLOSED", j, i);
- aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
+ close(pointer->contable[i].connfd);
+ FD_CLR(pointer->contable[i].connfd, &allset);
+ FD_CLR(pointer->contable[i].connfd, &wset);
+ pointer->contable[i].state = S_STATE_CLOSING;
+ freebuflist(&pointer->contable[i].head);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, 5);
+ }
+ }
+ else { /* when forwarding udp packets */
+ n = readn(pointer->contable[i].connfd, buff, 5 );
+ if (n != 5) {
+ n = 0;
+ }
+ if (n) {
+ if ((buff[0] == AF_S_MESSAGE) && (buff[1] == AF_S_LOGIN) && (buff[2] == AF_S_MESSAGE)) {
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is length of message */
+ if ((n = readn(pointer->contable[i].connfd, &buff[5], length)) != 0) {
+ aflog(2, " realm[%d]: client[%d]: FROM user[%d]: MESSAGE length=%d", j,
+ pointer->contable[i].whatcli, k, n);
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn,
+ buff, n+5);
+ }
+ }
+ else {
+ n = 0;
+ }
+ }
+
+ if (n == 0) {
+ aflog(1, " realm[%d]: client[%d]: user[%d]: CLOSED (udp mode)", j,
+ pointer->contable[i].whatcli, k);
+ aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
pointer->contable[i].portbuf);
- close(pointer->contable[i].connfd);
- FD_CLR(pointer->contable[i].connfd, &allset);
- FD_CLR(pointer->contable[i].connfd, &wset);
- pointer->contable[i].state = S_STATE_CLOSING;
- freebuflist(&pointer->contable[i].head);
- buff[0] = AF_S_CONCLOSED; /* closing connection */
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
-
- }
- }
- }
+ close(pointer->contable[i].connfd);
+ FD_CLR(pointer->contable[i].connfd, &allset);
+ FD_CLR(pointer->contable[i].connfd, &wset);
+ pointer->contable[i].state = S_STATE_CLOSING;
+ freebuflist(&pointer->contable[i].head);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, 5);
+ }
+
+ }
+ }
+ }
/* ------------------------------------ */
for (i = 0; i <pointer->usernum; ++i) {
- if (pointer->contable[i].state == S_STATE_STOPPED)
- if (FD_ISSET(pointer->contable[i].connfd, &tmpset)) {
- aflog(3, " realm[%d]: user[%d]: FD_ISSET - WRITE", j, i);
- n = pointer->contable[i].head->msglen - pointer->contable[i].head->actptr;
- sent = write(pointer->contable[i].connfd,
- &(pointer->contable[i].head->buff[pointer->contable[i].head->actptr]), n);
- if ((sent > 0) && (sent != n)) {
- pointer->contable[i].head->actptr+=sent;
- }
- else if ((sent == -1) && (errno == EAGAIN)) {
- }
- else if (sent == -1) {
- aflog(1, " realm[%d]: user[%d]: CLOSED", j, i);
- aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
- pointer->contable[i].portbuf);
- close(pointer->contable[i].connfd);
- FD_CLR(pointer->contable[i].connfd, &allset);
- FD_CLR(pointer->contable[i].connfd, &wset);
- pointer->contable[i].state = S_STATE_CLOSING;
- freebuflist(&pointer->contable[i].head);
- buff[0] = AF_S_CONCLOSED; /* closing connection */
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- else {
- deleteblnode(&pointer->contable[i].head);
- if (pointer->contable[i].head == NULL) {
- pointer->contable[i].state = S_STATE_OPEN;
- FD_CLR(pointer->contable[i].connfd, &wset);
- buff[0] = AF_S_CAN_SEND; /* stopping transfer */
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE ENDED", j, i);
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- }
- }
- }
+ if (pointer->contable[i].state == S_STATE_STOPPED)
+ if (FD_ISSET(pointer->contable[i].connfd, &tmpset)) {
+ k = eval_usernum(&(pointer->clitable[pointer->contable[i].whatcli]), i);
+ aflog(3, " realm[%d]: client[%d]: user[%d]: FD_ISSET - WRITE", j, pointer->contable[i].whatcli,
+ k);
+ n = pointer->contable[i].head->msglen - pointer->contable[i].head->actptr;
+ sent = write(pointer->contable[i].connfd,
+ &(pointer->contable[i].head->buff[pointer->contable[i].head->actptr]), n);
+ if ((sent > 0) && (sent != n)) {
+ pointer->contable[i].head->actptr+=sent;
+ }
+ else if ((sent == -1) && (errno == EAGAIN)) {
+ }
+ else if (sent == -1) {
+ aflog(1, " realm[%d]: client[%d]: user[%d]: CLOSED", j, pointer->contable[i].whatcli, k);
+ aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf, pointer->contable[i].portbuf);
+ close(pointer->contable[i].connfd);
+ FD_CLR(pointer->contable[i].connfd, &allset);
+ FD_CLR(pointer->contable[i].connfd, &wset);
+ pointer->contable[i].state = S_STATE_CLOSING;
+ freebuflist(&pointer->contable[i].head);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, 5);
+ }
+ else {
+ deleteblnode(&pointer->contable[i].head);
+ if (pointer->contable[i].head == NULL) {
+ pointer->contable[i].state = S_STATE_OPEN;
+ FD_CLR(pointer->contable[i].connfd, &wset);
+ buff[0] = AF_S_CAN_SEND; /* stopping transfer */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ aflog(3, " realm[%d]: client[%d]: TO user[%d]: BUFFERING MESSAGE ENDED", j,
+ pointer->contable[i].whatcli, k);
+ send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, 5);
+ }
+ }
+ }
+ }
/* ------------------------------------ */
if (FD_ISSET(pointer->listenfd, &rset)) {
len = pointer->addrlen;
@@ -523,49 +614,59 @@ main(int argc, char **argv)
flags = fcntl(sent, F_GETFL, 0);
fcntl(sent, F_SETFL, flags | O_NONBLOCK);
aflog(3, " realm[%d]: listenfd: FD_ISSET", j);
- if (pointer->ready == 3) {
+ k = find_client(pointer, pointer->climode);
+ if (pointer->clitable[k].ready == 3) {
if (pointer->usercon == pointer->usernum) {
close(sent);
- aflog(3, " realm[%d]: user limit EXCEEDED", j);
- }
- else {
- for (i = 0; i < pointer->usernum; ++i) {
- if (pointer->contable[i].state == S_STATE_CLEAR) {
- aflog(2, " realm[%d]: new user[%d]: CONNECTING", j, i);
- pointer->contable[i].connfd = sent;
- pointer->contable[i].state = S_STATE_OPENING;
- pointer->usercon++;
- aflog(1, " user IP:%s",sock_ntop(pointer->cliaddr, len,
- pointer->contable[i].namebuf, pointer->contable[i].portbuf));
- memcpy(&buff[5], pointer->contable[i].namebuf, 128);
- memcpy(&buff[133], pointer->contable[i].portbuf, 7);
- n = 135;
- buff[0] = AF_S_CONOPEN; /* opening connection */
- buff[1] = i >> 8; /* high bits of user number */
- buff[2] = i; /* low bits of user number */
- buff[3] = n >> 8; /* high bits of message length */
- buff[4] = n; /* low bits of message length */
- send_message(pointer->type, pointer->cliconn, buff, n+5);
- break;
- }
- }
- }
- }
- else {
- close(sent);
- aflog(3, " realm[%d]: client is NOT CONNECTED", j);
- }
- }
- if (pointer->ready != 0) /* Command file descriptor */
- if (FD_ISSET(pointer->cliconn.commfd, &rset)) {
- if (pointer->ready == 1) {
- if (SSL_set_fd(pointer->cliconn.ssl, pointer->cliconn.commfd) != 1) {
+ aflog(3, " realm[%d]: user limit EXCEEDED", j);
+ }
+ else if(pointer->clitable[k].usercon == pointer->clitable[k].usernum) {
+ close(sent);
+ aflog(3, " realm[%d]: client[%d]: usrpcli limit EXCEEDED", j, k);
+ }
+ else {
+ for (i = 0; i < pointer->usernum; ++i) {
+ if (pointer->contable[i].state == S_STATE_CLEAR) {
+ aflog(2, " realm[%d]: client[%d]: new user: CONNECTING", j, k);
+ pointer->contable[i].connfd = sent;
+ pointer->contable[i].state = S_STATE_OPENING;
+ pointer->contable[i].whatcli = k;
+ pointer->usercon++;
+ pointer->clitable[k].usercon++;
+ aflog(1, " user IP:%s",sock_ntop(pointer->cliaddr, len,
+ pointer->contable[i].namebuf, pointer->contable[i].portbuf));
+ memcpy(&buff[5], pointer->contable[i].namebuf, 128);
+ memcpy(&buff[133], pointer->contable[i].portbuf, 7);
+ n = 135;
+ i = find_usernum(&(pointer->clitable[k]), i);
+ buff[0] = AF_S_CONOPEN; /* opening connection */
+ buff[1] = i >> 8; /* high bits of user number */
+ buff[2] = i; /* low bits of user number */
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, n+5);
+ break;
+ }
+ }
+ }
+ }
+ else {
+ close(sent);
+ aflog(3, " realm[%d]: client[%d] is NOT CONNECTED", j, k);
+ }
+ }
+ /* ------------------------------------ */
+ for (k = 0; k < pointer->clinum; ++k)
+ if (pointer->clitable[k].ready != 0) /* Command file descriptor */
+ if (FD_ISSET(pointer->clitable[k].cliconn.commfd, &rset)) {
+ if (pointer->clitable[k].ready == 1) {
+ if (SSL_set_fd(pointer->clitable[k].cliconn.ssl, pointer->clitable[k].cliconn.commfd) != 1) {
aflog(0, "Problem with initializing ssl... exiting");
exit(1);
}
aflog(2, " realm[%d]: new client: SSL_accept", j);
- if ((n = SSL_accept(pointer->cliconn.ssl)) != 1) {
- flags = SSL_get_error(pointer->cliconn.ssl, n);
+ if ((n = SSL_accept(pointer->clitable[k].cliconn.ssl)) != 1) {
+ flags = SSL_get_error(pointer->clitable[k].cliconn.ssl, n);
switch (flags) {
case SSL_ERROR_NONE : {
aflog(2, " SSL_accept has failed(%d)...none", n);
@@ -604,349 +705,290 @@ main(int argc, char **argv)
}
if (flags == SSL_ERROR_WANT_READ)
continue;
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
+ close (pointer->clitable[k].cliconn.commfd);
+ FD_CLR(pointer->clitable[k].cliconn.commfd, &allset);
FD_SET(pointer->managefd, &allset);
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
+ SSL_clear(pointer->clitable[k].cliconn.ssl);
+ pointer->clitable[k].ready = 0;
manconnecting--;
- aflog(1, " realm[%d]: new client: DENIED by SSL_accept", j);
+ pointer->clicon--;
+ aflog(1, " realm[%d]: new client[%d]: DENIED by SSL_accept", j, k);
}
else {
- aflog(1, " realm[%d]: new client: ACCEPTED by SSL_accept", j);
- pointer->ready = 2;
+ aflog(1, " realm[%d]: new client[%d]: ACCEPTED by SSL_accept", j, k);
+ pointer->clitable[k].ready = 2;
}
continue; /* in the case this is not our client */
}
- aflog(3, " realm[%d]: commfd: FD_ISSET", j);
- if (pointer->ready == 2) {
- n = get_message(pointer->type | TYPE_SSL, pointer->cliconn, buff, -5);
+ aflog(3, " realm[%d]: client[%d]: commfd: FD_ISSET", j, k);
+ if (pointer->clitable[k].ready == 2) {
+ n = get_message(pointer->type | TYPE_SSL, pointer->clitable[k].cliconn, buff, -5);
}
else {
- n = get_message(pointer->type, pointer->cliconn, buff, -5);
+ n = get_message(pointer->type, pointer->clitable[k].cliconn, buff, -5);
}
if (n == -1) {
if (errno == EAGAIN) {
+ aflog(4, " realm[%d]: client[%d]: commfd: EAGAIN", j, k);
continue;
}
else {
+ aflog(4, " realm[%d]: client[%d]: commfd: ERROR: %d", j, k, errno);
n = 0;
}
}
else if (n != 5) {
n = 0;
}
- if (n==0) {
- close(pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- maxfdp1 = (maxfdp1 > (pointer->managefd+1)) ? maxfdp1 : (pointer->managefd+1);
- if (pointer->ready == 3) {
- for (i = 0; i < pointer->usernum; ++i) {
- if (pointer->contable[i].state != S_STATE_CLEAR) {
- pointer->contable[i].state = S_STATE_CLEAR;
- FD_CLR(pointer->contable[i].connfd, &allset);
- FD_CLR(pointer->contable[i].connfd, &wset);
- close(pointer->contable[i].connfd);
- }
- }
- }
- pointer->usercon = 0;
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
- aflog(1, " realm[%d]: commfd: CLOSED", j);
+ if (n==0) {
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
+ aflog(1, " realm[%d]: client[%d]: commfd: CLOSED", j, k);
continue;
}
- numofcon = buff[1];
- numofcon = numofcon << 8;
- numofcon += buff[2]; /* this is id of user */
- length = buff[3];
- length = length << 8;
- length += buff[4]; /* this is length of message */
+
+ numofcon = buff[1];
+ numofcon = numofcon << 8;
+ numofcon += buff[2]; /* this is id of user */
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is length of message */
+
switch (buff[0]) {
case AF_S_CONCLOSED : {
- if ((numofcon>=0) &&
- (numofcon<=(pointer->usernum)) &&
- ((pointer->ready)==3)) {
- (pointer->usercon)--;
- if (pointer->contable[numofcon].state ==
- S_STATE_CLOSING) {
- pointer->contable[numofcon].state =
- S_STATE_CLEAR;
- }
- else if ((pointer->contable[numofcon].state == S_STATE_OPEN) ||
- (pointer->contable[numofcon].state == S_STATE_STOPPED)) {
- aflog(1, " realm[%d]: user[%d]: KICKED", j, numofcon);
- aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
- pointer->contable[numofcon].portbuf);
- close(pointer->contable[numofcon].connfd);
- FD_CLR(pointer->contable[numofcon].connfd, &allset);
- FD_CLR(pointer->contable[numofcon].connfd, &wset);
- pointer->contable[numofcon].state = S_STATE_CLEAR;
- freebuflist(&pointer->contable[numofcon].head);
- buff[0] = AF_S_CONCLOSED; /* closing connection */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- }
- else {
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- if (pointer->ready == 2)
- manconnecting--;
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
- }
- break;
- }
+ n = numofcon;
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(pointer->usernum)) && ((pointer->clitable[k].ready)==3)) {
+ pointer->usercon--;
+ pointer->clitable[k].usercon--;
+ pointer->clitable[k].users[n] = -1;
+ if (pointer->contable[numofcon].state == S_STATE_CLOSING) {
+ pointer->contable[numofcon].state = S_STATE_CLEAR;
+ }
+ else if ((pointer->contable[numofcon].state == S_STATE_OPEN) ||
+ (pointer->contable[numofcon].state == S_STATE_STOPPED)) {
+ aflog(1, " realm[%d]: user[%d]: KICKED", j, numofcon);
+ aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
+ pointer->contable[numofcon].portbuf);
+ close(pointer->contable[numofcon].connfd);
+ FD_CLR(pointer->contable[numofcon].connfd, &allset);
+ FD_CLR(pointer->contable[numofcon].connfd, &wset);
+ pointer->contable[numofcon].state = S_STATE_CLEAR;
+ freebuflist(&pointer->contable[numofcon].head);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ }
+ else {
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
+ }
+ break;
+ }
case AF_S_CONOPEN : {
- if ((numofcon>=0) &&
- (numofcon<=(pointer->usernum)) &&
- ((pointer->ready)==3)) {
- if (pointer->contable[numofcon].state ==
- S_STATE_OPENING) {
- aflog(2, " realm[%d]: user[%d]: NEW", j, numofcon);
- FD_SET(pointer->contable[numofcon].connfd, &allset);
- maxfdp1 = (maxfdp1 > (pointer->contable[numofcon].connfd+1)) ?
- maxfdp1 : (pointer->contable[numofcon].connfd+1);
- pointer->contable[numofcon].state =
- S_STATE_OPEN;
- }
- }
- else {
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- if (pointer->ready == 2)
- manconnecting--;
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
- }
- break;
- }
-
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(pointer->usernum)) && ((pointer->clitable[k].ready)==3)) {
+ if (pointer->contable[numofcon].state == S_STATE_OPENING) {
+ aflog(2, " realm[%d]: user[%d]: NEW", j, numofcon);
+ FD_SET(pointer->contable[numofcon].connfd, &allset);
+ maxfdp1 = (maxfdp1 > (pointer->contable[numofcon].connfd+1)) ?
+ maxfdp1 : (pointer->contable[numofcon].connfd+1);
+ pointer->contable[numofcon].state = S_STATE_OPEN;
+ }
+ }
+ else {
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
+ }
+ break;
+ }
case AF_S_CANT_OPEN : {
- if ((numofcon>=0) &&
- (numofcon<=(pointer->usernum)) &&
- ((pointer->ready)==3)) {
- if (pointer->contable[numofcon].state ==
- S_STATE_OPENING) {
- aflog(2, " realm[%d]: user[%d]: DROPPED",j, numofcon);
- (pointer->usercon)--;
- close(pointer->contable[numofcon].connfd);
- pointer->contable[numofcon].state =
- S_STATE_CLEAR;
- }
- }
- else {
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- if (pointer->ready == 2)
- manconnecting--;
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
- }
- break;
- }
-
-
-
+ n = numofcon;
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(pointer->usernum)) && ((pointer->clitable[k].ready)==3)) {
+ if (pointer->contable[numofcon].state == S_STATE_OPENING) {
+ aflog(2, " realm[%d]: user[%d]: DROPPED", j, numofcon);
+ pointer->usercon--;
+ pointer->clitable[k].usercon--;
+ pointer->clitable[k].users[n] = -1;
+ close(pointer->contable[numofcon].connfd);
+ pointer->contable[numofcon].state = S_STATE_CLEAR;
+ }
+ }
+ else {
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
+ }
+ break;
+ }
case AF_S_MESSAGE : {
- if ((pointer->ready) != 3) {
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- manconnecting--;
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
+ if ((pointer->clitable[k].ready) != 3) {
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
break;
- }
- if (TYPE_IS_UDP(pointer->type)) { /* udp */
- n = get_message(pointer->type, pointer->cliconn, &buff[5], length);
- }
- else {
- n = get_message(pointer->type, pointer->cliconn, buff, length);
- }
- if ((numofcon>=0) &&
- (numofcon<=(pointer->usernum))) {
- if (pointer->contable[numofcon].state ==
- S_STATE_OPEN) {
- aflog(2, " realm[%d]: TO user[%d]: MESSAGE length=%d", j, numofcon, n);
- if (TYPE_IS_UDP(pointer->type)) { /* udp */
- buff[1] = AF_S_LOGIN;
- buff[2] = AF_S_MESSAGE;
- buff[3] = n >> 8; /* high bits of message length */
- buff[4] = n; /* low bits of message length */
- sent = write(pointer->contable[numofcon].connfd, buff, n+5);
- if ((sent > 0) && (sent != n)) {
- insertblnode(&(pointer->contable[numofcon].head), sent, n, buff);
- pointer->contable[numofcon].state = S_STATE_STOPPED;
- FD_SET(pointer->contable[numofcon].connfd, &wset);
- buff[0] = AF_S_DONT_SEND; /* stopping transfer */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED", j, numofcon);
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- else if ((sent == -1) && (errno == EAGAIN)) {
- insertblnode(&(pointer->contable[numofcon].head), 0, n, buff);
- pointer->contable[numofcon].state = S_STATE_STOPPED;
- FD_SET(pointer->contable[numofcon].connfd, &wset);
- buff[0] = AF_S_DONT_SEND; /* stopping transfer */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED", j, numofcon);
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- else if (sent == -1) {
- aflog(1, " realm[%d]: user[%d]: CLOSED", j, numofcon);
- aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
- pointer->contable[numofcon].portbuf);
- close(pointer->contable[numofcon].connfd);
- FD_CLR(pointer->contable[numofcon].connfd, &allset);
- FD_CLR(pointer->contable[numofcon].connfd, &wset);
- pointer->contable[numofcon].state = S_STATE_CLOSING;
- freebuflist(&pointer->contable[numofcon].head);
- buff[0] = AF_S_CONCLOSED; /* closing connection */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- }
- else { /* tcp */
- sent = write(pointer->contable[numofcon].connfd, buff, n);
- if ((sent > 0) && (sent != n)) {
- insertblnode(&(pointer->contable[numofcon].head), sent, n, buff);
- pointer->contable[numofcon].state = S_STATE_STOPPED;
- FD_SET(pointer->contable[numofcon].connfd, &wset);
- buff[0] = AF_S_DONT_SEND; /* stopping transfer */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED", j, numofcon);
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- else if ((sent == -1) && (errno == EAGAIN)) {
- insertblnode(&(pointer->contable[numofcon].head), 0, n, buff);
- pointer->contable[numofcon].state = S_STATE_STOPPED;
- FD_SET(pointer->contable[numofcon].connfd, &wset);
- buff[0] = AF_S_DONT_SEND; /* stopping transfer */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED", j, numofcon);
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- else if (sent == -1) {
- aflog(1, " realm[%d]: user[%d]: CLOSED", j, numofcon);
- aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
- pointer->contable[numofcon].portbuf);
- close(pointer->contable[numofcon].connfd);
- FD_CLR(pointer->contable[numofcon].connfd, &allset);
- FD_CLR(pointer->contable[numofcon].connfd, &wset);
- pointer->contable[numofcon].state = S_STATE_CLOSING;
- freebuflist(&pointer->contable[numofcon].head);
- buff[0] = AF_S_CONCLOSED; /* closing connection */
- buff[1] = numofcon >> 8; /* high bits of user number */
- buff[2] = numofcon; /* low bits of user number */
- send_message(pointer->type, pointer->cliconn, buff, 5);
- }
- }
- }
- else if (pointer->contable[numofcon].state ==
- S_STATE_STOPPED) {
- aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE", j, numofcon);
- if (TYPE_IS_UDP(pointer->type)) { /* udp */
- buff[1] = AF_S_LOGIN;
- buff[2] = AF_S_MESSAGE;
- buff[3] = n >> 8; /* high bits of message length */
- buff[4] = n; /* low bits of message length */
- insertblnode(&(pointer->contable[numofcon].head), 0, n+5, buff);
- }
- else {
- insertblnode(&(pointer->contable[numofcon].head), 0, n, buff);
- }
- }
- }
- break;
- }
+ }
+ if (TYPE_IS_UDP(pointer->type)) { /* udp */
+ n = get_message(pointer->type, pointer->clitable[k].cliconn, &buff[5], length);
+ }
+ else {
+ n = get_message(pointer->type, pointer->clitable[k].cliconn, buff, length);
+ }
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(pointer->usernum))) {
+ if (pointer->contable[numofcon].state == S_STATE_OPEN) {
+ aflog(2, " realm[%d]: TO user[%d]: MESSAGE length=%d", j, numofcon, n);
+ if (TYPE_IS_UDP(pointer->type)) { /* udp */
+ buff[1] = AF_S_LOGIN;
+ buff[2] = AF_S_MESSAGE;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ sent = write(pointer->contable[numofcon].connfd, buff, n+5);
+ if ((sent > 0) && (sent != n)) {
+ insertblnode(&(pointer->contable[numofcon].head), sent, n, buff);
+ pointer->contable[numofcon].state = S_STATE_STOPPED;
+ FD_SET(pointer->contable[numofcon].connfd, &wset);
+ buff[0] = AF_S_DONT_SEND; /* stopping transfer */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)", j, numofcon,
+ sent, n);
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ else if ((sent == -1) && (errno == EAGAIN)) {
+ insertblnode(&(pointer->contable[numofcon].head), 0, n, buff);
+ pointer->contable[numofcon].state = S_STATE_STOPPED;
+ FD_SET(pointer->contable[numofcon].connfd, &wset);
+ buff[0] = AF_S_DONT_SEND; /* stopping transfer */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)", j, numofcon,
+ sent, n);
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ else if (sent == -1) {
+ aflog(1, " realm[%d]: user[%d]: CLOSED (write-udp)", j, numofcon);
+ aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
+ pointer->contable[numofcon].portbuf);
+ close(pointer->contable[numofcon].connfd);
+ FD_CLR(pointer->contable[numofcon].connfd, &allset);
+ FD_CLR(pointer->contable[numofcon].connfd, &wset);
+ pointer->contable[numofcon].state = S_STATE_CLOSING;
+ freebuflist(&pointer->contable[numofcon].head);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ }
+ else { /* tcp */
+ sent = write(pointer->contable[numofcon].connfd, buff, n);
+ if ((sent > 0) && (sent != n)) {
+ insertblnode(&(pointer->contable[numofcon].head), sent, n, buff);
+ pointer->contable[numofcon].state = S_STATE_STOPPED;
+ FD_SET(pointer->contable[numofcon].connfd, &wset);
+ buff[0] = AF_S_DONT_SEND; /* stopping transfer */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)", j, numofcon,
+ sent, n);
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ else if ((sent == -1) && (errno == EAGAIN)) {
+ insertblnode(&(pointer->contable[numofcon].head), 0, n, buff);
+ pointer->contable[numofcon].state = S_STATE_STOPPED;
+ FD_SET(pointer->contable[numofcon].connfd, &wset);
+ buff[0] = AF_S_DONT_SEND; /* stopping transfer */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)", j, numofcon,
+ sent, n);
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ else if (sent == -1) {
+ aflog(1, " realm[%d]: user[%d]: CLOSED (write-tcp)", j, numofcon);
+ aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
+ pointer->contable[numofcon].portbuf);
+ close(pointer->contable[numofcon].connfd);
+ FD_CLR(pointer->contable[numofcon].connfd, &allset);
+ FD_CLR(pointer->contable[numofcon].connfd, &wset);
+ pointer->contable[numofcon].state = S_STATE_CLOSING;
+ freebuflist(&pointer->contable[numofcon].head);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = numofcon >> 8; /* high bits of user number */
+ buff[2] = numofcon; /* low bits of user number */
+ send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
+ }
+ }
+ }
+ else if (pointer->contable[numofcon].state == S_STATE_STOPPED) {
+ aflog(3, " realm[%d]: TO user[%d]: BUFFERING MESSAGE (%d)", j, numofcon, n);
+ if (TYPE_IS_UDP(pointer->type)) { /* udp */
+ buff[1] = AF_S_LOGIN;
+ buff[2] = AF_S_MESSAGE;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ insertblnode(&(pointer->contable[numofcon].head), 0, n+5, buff);
+ }
+ else {
+ insertblnode(&(pointer->contable[numofcon].head), 0, n, buff);
+ }
+ }
+ }
+ break;
+ }
case AF_S_LOGIN : {
- if ((pointer->ready == 2)&&
- (numofcon==(pointer->pass[0]*256+pointer->pass[1]))&&
- (length==(pointer->pass[2]*256+pointer->pass[3]))) {
- pointer->ready = 3;
- aflog(1, " realm[%d]: pass ok - ACCESS GRANTED", j);
- buff[0] = AF_S_LOGIN; /* sending message */
- buff[1] = pointer->usernum >> 8;/* high bits of user number */
- buff[2] = pointer->usernum; /* low bits of user number */
- buff[3] = pointer->type; /* type of connection */
- send_message(pointer->type | TYPE_SSL, pointer->cliconn, buff, 5);
- manconnecting--;
- }
- else {
- aflog(1, " realm[%d]: Wrong password - CLOSING", j);
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- if (pointer->ready == 2)
- manconnecting--;
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
- }
- break;
- }
- case AF_S_DONT_SEND: {
- FD_CLR(pointer->contable[numofcon].connfd, &allset);
- break;
- }
- case AF_S_CAN_SEND: {
- FD_SET(pointer->contable[numofcon].connfd, &allset);
- break;
- }
-
+ if ((pointer->clitable[k].ready == 2) && (numofcon==(pointer->pass[0]*256+pointer->pass[1])) &&
+ (length==(pointer->pass[2]*256+pointer->pass[3]))) {
+ pointer->clitable[k].ready = 3;
+ aflog(1, " realm[%d]: pass ok - ACCESS GRANTED", j);
+ buff[0] = AF_S_LOGIN; /* sending message */
+ buff[1] = pointer->clitable[k].usernum >> 8;/* high bits of user number */
+ buff[2] = pointer->clitable[k].usernum; /* low bits of user number */
+ buff[3] = pointer->type; /* type of connection */
+ send_message(pointer->type | TYPE_SSL, pointer->clitable[k].cliconn, buff, 5);
+ manconnecting--;
+ }
+ else {
+ aflog(1, " realm[%d]: Wrong password - CLOSING", j);
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
+ }
+ break;
+ }
+ case AF_S_DONT_SEND: {
+ FD_CLR(pointer->contable[numofcon].connfd, &allset);
+ break;
+ }
+ case AF_S_CAN_SEND: {
+ FD_SET(pointer->contable[numofcon].connfd, &allset);
+ break;
+ }
default : {
- aflog(1, " realm[%d]: Unrecognized message - CLOSING", j);
- close (pointer->cliconn.commfd);
- FD_CLR(pointer->cliconn.commfd, &allset);
- FD_SET(pointer->managefd, &allset);
- if (pointer->ready == 2)
- manconnecting--;
- if (pointer->ready == 3) {
- for (i = 0; i < pointer->usernum; ++i) {
- if (pointer->contable[i].state != S_STATE_CLEAR) {
- pointer->contable[i].state = S_STATE_CLEAR;
- FD_CLR(pointer->contable[i].connfd, &allset);
- FD_CLR(pointer->contable[i].connfd, &wset);
- close(pointer->contable[i].connfd);
- }
- }
- }
- SSL_clear(pointer->cliconn.ssl);
- pointer->ready = 0;
- }
- }
- }
-
- if (FD_ISSET(pointer->managefd, &rset)) {
- aflog(3, " realm[%d]: managefd: FD_ISSET", j);
- len = pointer->addrlen;
- if (!(pointer->ready)) {
- aflog(2, " realm[%d]: new client: CONNECTING", j);
- pointer->cliconn.commfd = accept(pointer->managefd, pointer->cliaddr, &len);
- flags = fcntl(pointer->cliconn.commfd, F_GETFL, 0);
- fcntl(pointer->cliconn.commfd, F_SETFL, flags | O_NONBLOCK);
- aflog(1, " realm[%d]: Client IP:%s", j, sock_ntop(pointer->cliaddr, len, NULL, NULL));
- FD_SET(pointer->cliconn.commfd, &allset);
- maxfdp1 = (maxfdp1 > (pointer->cliconn.commfd+1)) ? maxfdp1 : (pointer->cliconn.commfd+1);
- FD_CLR(pointer->managefd, &allset);
- pointer->tv.tv_sec = 5;
- manconnecting++;
- pointer->ready = 1;
- }
- }
- } /* realms loop */
- }
+ aflog(1, " realm[%d]: Unrecognized message - CLOSING", j);
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
+ }
+ }
+ }
+ if (FD_ISSET(pointer->managefd, &rset)) {
+ aflog(3, " realm[%d]: managefd: FD_ISSET", j);
+ len = pointer->addrlen;
+ for (k = 0; k < pointer->clinum; ++k)
+ if (!(pointer->clitable[k].ready)) {
+ aflog(2, " realm[%d]: new client[%d]: CONNECTING", j, k);
+ pointer->clitable[k].cliconn.commfd = accept(pointer->managefd, pointer->cliaddr, &len);
+ flags = fcntl(pointer->clitable[k].cliconn.commfd, F_GETFL, 0);
+ fcntl(pointer->clitable[k].cliconn.commfd, F_SETFL, flags | O_NONBLOCK);
+ aflog(1, " realm[%d]: Client[%d] IP:%s", j, k, sock_ntop(pointer->cliaddr, len, NULL, NULL));
+ FD_SET(pointer->clitable[k].cliconn.commfd, &allset);
+ maxfdp1 = (maxfdp1 > (pointer->clitable[k].cliconn.commfd+1)) ?
+ maxfdp1 : (pointer->clitable[k].cliconn.commfd+1);
+ pointer->clicon++;
+ if (pointer->clicon == pointer->clinum)
+ FD_CLR(pointer->managefd, &allset);
+ pointer->clitable[k].tv.tv_sec = pointer->tmout;
+ manconnecting++;
+ pointer->clitable[k].ready = 1;
+ break;
+ }
+ }
+ } /* realms loop */
+ }
}
static void
@@ -954,15 +996,22 @@ usage(char* info)
{
printf("\n%s\n\n", info);
printf(" Options:\n");
- printf(" -h, --help - prints this help\n");
printf(" -n, --hostname - it's used when creating listening sockets\n");
printf(" (default: name returned by hostname function)\n");
printf(" -l, --listenport - listening port number - users connect\n");
printf(" to it (default: 50127)\n");
printf(" -m, --manageport - manage port number - second part of the active\n");
printf(" port forwarder connects to it (default: 50126)\n");
+ printf(" -t, --timeout - the timeout value for the client's connection\n");
+ printf(" (default: 5)\n");
printf(" -u, --users - the amount of users allowed to use this server\n");
printf(" (default: 5)\n");
+ printf(" -C, --clients - the number of allowed clients to use this server\n");
+ printf(" (default: 1)\n");
+ printf(" -U, --usrpcli - the number of allowed users per client (default: $users)\n");
+ printf(" -M, --climode - strategy used for connecting users with clients (default: 1)\n");
+ printf(" Available strategies:\n");
+ printf(" 1. fill first client before go to next\n\n");
printf(" -c, --cerfile - the name of the file with certificate\n");
printf(" (default: cacert.pem)\n");
printf(" -k, --keyfile - the name of the file with RSA key (default: server.rsa)\n");
@@ -973,28 +1022,136 @@ usage(char* info)
printf(" -O, --heavylog - logging everything to a logfile\n");
printf(" -o, --lightlog - logging some data to a logfile\n");
printf(" -v, --verbose - to be verbose - program won't enter the daemon mode\n");
- printf(" (use several times for greater effect)\n");
+ printf(" (use several times for greater effect)\n\n");
printf(" --nossl - ssl is not used for transfering data (but it's still\n");
printf(" used to establish a connection) (default: ssl is used)\n");
printf(" --nozlib - zlib is not used for compressing data (default:\n");
printf(" zlib is used)\n");
printf(" --pass - set the password used for client identification\n");
- printf(" (default: no password)\n");
+ printf(" (default: no password)\n\n");
printf(" -4, --ipv4 - use ipv4 only\n");
printf(" -6, --ipv6 - use ipv6 only\n\n");
+ printf(" -h, --help - prints this help\n\n");
exit(0);
}
static void
sig_int(int signo)
{
- int j;
+ int i, j;
unsigned char buff[5];
for (j = 0; j < config.size; ++j) {
buff[0] = AF_S_CLOSING; /* closing */
- send_message(config.realmtable[j].type, config.realmtable[j].cliconn, buff, 5);
+ for (i = 0; i < config.realmtable[j].clinum; ++i) {
+ if (config.realmtable[j].clitable[i].ready == 3) {
+ send_message(config.realmtable[j].type, config.realmtable[j].clitable[i].cliconn, buff, 5);
+ }
+ }
}
aflog(1, "SERVER CLOSED cg: %ld bytes", getcg());
exit(0);
}
+static void
+remove_client(RealmT* ptr, int client, fd_set* set, fd_set* wset, int* con)
+{
+ int i;
+ if (ptr->clitable[client].ready == 3) {
+ for (i = 0; i < ptr->usernum; ++i) {
+ if (ptr->contable[i].whatcli == client) {
+ if (ptr->contable[i].state != S_STATE_CLEAR) {
+ ptr->contable[i].state = S_STATE_CLEAR;
+ FD_CLR(ptr->contable[i].connfd, set);
+ FD_CLR(ptr->contable[i].connfd, wset);
+ close(ptr->contable[i].connfd);
+ ptr->usercon--;
+ }
+ }
+ }
+ }
+ ptr->clitable[client].usercon = 0;
+ close(ptr->clitable[client].cliconn.commfd);
+ FD_CLR(ptr->clitable[client].cliconn.commfd, set);
+ FD_SET(ptr->managefd, set);
+ if (ptr->clitable[client].ready == 2)
+ (*con)--;
+ SSL_clear(ptr->clitable[client].cliconn.ssl);
+ ptr->clitable[client].ready = 0;
+ ptr->clicon--;
+}
+
+static int
+find_client(RealmT* ptr, char mode)
+{
+ int i;
+ switch(mode) {
+ case 1: { /* fill first client before go to next */
+ for (i = 0; i < ptr->clinum; ++i) {
+ if (ptr->clitable[i].ready == 3) {
+ if (ptr->clitable[i].usercon < ptr->clitable[i].usernum) {
+ return i;
+ }
+ }
+ }
+ break;
+ }
+ default: {
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static int
+eval_numofcon(RealmT* ptr, int client, int numofcon)
+{
+ if ((numofcon >= 0) && (numofcon < ptr->clitable[client].usernum)) {
+ numofcon = ptr->clitable[client].users[numofcon];
+ }
+ else {
+ numofcon = -1;
+ }
+ return numofcon;
+}
+
+static int
+eval_usernum(ConnectclientT* ptr, int usernum)
+{
+ int i;
+ for (i = 0; i < ptr->usernum; ++i) {
+ if (ptr->users[i] == usernum)
+ return i;
+ }
+ return -1;
+}
+
+static int
+find_usernum(ConnectclientT* ptr, int usernum)
+{
+ int i;
+ for (i = 0; i < ptr->usernum; ++i) {
+ if (ptr->users[i] == -1) {
+ ptr->users[i] = usernum;
+ return i;
+ }
+ }
+ return -1;
+}
+
+static void
+check_value(int* where, char* what, char* info)
+{
+ char* znak;
+ if ((( (*where) = strtol(what, &znak, 10)) == LONG_MAX) || ((*where) == LONG_MIN)) {
+ printf("%s: %s\n", info, what);
+ exit(1);
+ }
+ if (((*what) == '\0') || (*znak != '\0')) {
+ printf("%s: %s\n", info, what);
+ exit(1);
+ }
+ if ((*where) <= 0) {
+ printf("%s: %d\n", info, *where);
+ exit(1);
+ }
+}