Various fixes, the admin tool at least compiles and runs.

This commit is contained in:
Jan Vidar Krey 2009-08-28 18:05:58 +02:00
parent 5203ecdadc
commit 4ca5caa52b
5 changed files with 266 additions and 105 deletions

View File

@ -187,8 +187,6 @@ admin_OBJECTS := $(admin_SOURCES:.c=.o)
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS) all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
LIBUHUB=libuhub.a
LIBUCADC=libucadc.a
uhub_BINARY=uhub$(BIN_EXT) uhub_BINARY=uhub$(BIN_EXT)
adcrush_BINARY=adcrush$(BIN_EXT) adcrush_BINARY=adcrush$(BIN_EXT)
admin_BINARY=uhub-admin$(BIN_EXT) admin_BINARY=uhub-admin$(BIN_EXT)
@ -238,7 +236,7 @@ dist-clean:
@rm -rf $(all_OBJECTS) *~ core @rm -rf $(all_OBJECTS) *~ core
clean: clean:
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(LIBUHUB) $(all_OBJECTS) && \ @rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) autotest.c && \
echo $(MSG_CLEAN) echo $(MSG_CLEAN)

View File

@ -197,6 +197,11 @@ void net_con_update(struct net_connection* con, int ev)
net_con_flag_set(con, NET_EVENT_WRITE); net_con_flag_set(con, NET_EVENT_WRITE);
else else
net_con_flag_unset(con, NET_EVENT_WRITE); net_con_flag_unset(con, NET_EVENT_WRITE);
if (!net_con_flag_get(con, NET_PROCESSING_BUSY))
{
net_con_set(con);
}
} }
void net_con_close(struct net_connection* con) void net_con_close(struct net_connection* con)
@ -437,7 +442,7 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
return handle_openssl_error(con, ret); return handle_openssl_error(con, ret);
} }
return ret; return ret;
} // }
ssize_t net_con_ssl_handshake(struct net_connection* con, int ssl_mode) ssize_t net_con_ssl_handshake(struct net_connection* con, int ssl_mode)
{ {

View File

@ -19,11 +19,18 @@
#include "tools/adcclient.h" #include "tools/adcclient.h"
#define ADC_HANDSHAKE "HSUP ADBASE ADTIGR\n" #define ADC_HANDSHAKE "HSUP ADBASE ADTIGR ADPING\n"
#define ADC_CID_SIZE 39 #define ADC_CID_SIZE 39
#define BIG_BUFSIZE 32768 #define BIG_BUFSIZE 32768
#define TIGERSIZE 24 #define TIGERSIZE 24
static ssize_t ADC_client_recv(struct ADC_client* client);
static void ADC_client_send_info(struct ADC_client* client);
static void ADC_client_on_connected(struct ADC_client* client);
static void ADC_client_on_disconnected(struct ADC_client* client);
static void ADC_client_on_login(struct ADC_client* client);
static int ADC_client_parse_address(struct ADC_client* client, const char* arg);
static void ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length);
static void ADC_client_debug(struct ADC_client* client, const char* format, ...) static void ADC_client_debug(struct ADC_client* client, const char* format, ...)
{ {
@ -40,12 +47,6 @@ static void ADC_client_set_state(struct ADC_client* client, enum ADC_client_stat
client->state = state; client->state = state;
} }
static ssize_t ADC_client_recv(struct ADC_client* client);
static void ADC_client_send_info(struct ADC_client* client);
static void ADC_client_on_connected(struct ADC_client* client);
static void ADC_client_on_disconnected(struct ADC_client* client);
static void ADC_client_on_login(struct ADC_client* client);
static int ADC_client_parse_address(struct ADC_client* client, const char* arg);
static void adc_cid_pid(struct ADC_client* client) static void adc_cid_pid(struct ADC_client* client)
{ {
@ -82,11 +83,9 @@ static void timer_callback(struct net_timer* t, void* arg)
static void event_callback(struct net_connection* con, int events, void *arg) static void event_callback(struct net_connection* con, int events, void *arg)
{ {
struct ADC_client* client = (struct ADC_client*) arg; struct ADC_client* client = (struct ADC_client*) arg;
ADC_client_debug(client, "event_callback. events=%d", events);
if (events == NET_EVENT_SOCKERROR || events == NET_EVENT_CLOSED) if (events == NET_EVENT_SOCKERROR || events == NET_EVENT_CLOSED)
{ {
client->callbacks.connection(client, -1, "Closed/socket error"); client->callback(client, ADC_CLIENT_DISCONNECTED, 0);
return; return;
} }
@ -94,7 +93,7 @@ static void event_callback(struct net_connection* con, int events, void *arg)
{ {
if (client->state == ps_conn) if (client->state == ps_conn)
{ {
client->callbacks.connection(client, -2, "Connection timed out"); client->callback(client, ADC_CLIENT_DISCONNECTED, 0);
} }
} }
@ -119,34 +118,27 @@ static void event_callback(struct net_connection* con, int events, void *arg)
} }
} }
static ssize_t ADC_client_recv(struct ADC_client* client) static void ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length)
{ {
ssize_t size = net_con_recv(client->con, &client->recvbuf[client->r_offset], ADC_BUFSIZE - client->r_offset); #ifdef ADC_CLIENT_DEBUG_PROTO
if (size <= 0) ADC_client_debug(client, "- LINE: '%s'", start);
return size; #endif
client->recvbuf[client->r_offset + size] = 0; /* Parse message */
struct adc_message* msg = adc_msg_parse(line, length);
char* start = client->recvbuf; if (!msg)
char* pos;
char* lastPos = 0;
while ((pos = strchr(start, '\n')))
{ {
lastPos = pos; ADC_client_debug(client, "WARNING: Message cannot be decoded: \"%s\"", line);
pos[0] = 0; return;
ADC_client_debug(client, "- RECV: '%s'", start);
fourcc_t cmd = 0;
if (strlen(start) < 4)
{
ADC_client_debug(client, "Unexpected response from hub: '%s'", start);
start = &pos[1];
continue;
} }
cmd = FOURCC(start[0], start[1], start[2], start[3]); if (length < 4)
switch (cmd) {
ADC_client_debug(client, "Unexpected response from hub: '%s'", line);
return;
}
switch (msg->cmd)
{ {
case ADC_CMD_ISUP: case ADC_CMD_ISUP:
break; break;
@ -154,61 +146,125 @@ static ssize_t ADC_client_recv(struct ADC_client* client)
case ADC_CMD_ISID: case ADC_CMD_ISID:
if (client->state == ps_protocol) if (client->state == ps_protocol)
{ {
client->sid = string_to_sid(&start[5]); client->sid = string_to_sid(&line[5]);
client->callback(client, ADC_CLIENT_LOGGING_IN, 0);
ADC_client_set_state(client, ps_identify); ADC_client_set_state(client, ps_identify);
ADC_client_send_info(client); ADC_client_send_info(client);
} }
break; break;
case ADC_CMD_IINF: case ADC_CMD_BMSG:
case ADC_CMD_EMSG:
case ADC_CMD_DMSG:
case ADC_CMD_IMSG:
{
struct ADC_chat_message chat;
chat.from_sid = msg->source;
chat.to_sid = msg->target;
char* message = adc_msg_get_argument(msg, 0);
chat.message = adc_msg_unescape(message);
hub_free(message);
struct ADC_client_callback_data data;
data.chat = &chat;
client->callback(client, ADC_CLIENT_MESSAGE, &data);
hub_free(chat.message);
break; break;
}
case ADC_CMD_IINF:
{
struct ADC_hub_info hubinfo;
char* name = adc_msg_get_named_argument(msg, "NI");
hubinfo.name = name ? adc_msg_unescape(name) : 0;
hub_free(name);
char* desc = adc_msg_get_named_argument(msg, "DE");
hubinfo.description = desc ? adc_msg_unescape(desc) : 0;
hub_free(desc);
char* vers = adc_msg_get_named_argument(msg, "VE");
hubinfo.version = vers ? adc_msg_unescape(vers) : 0 ;
hub_free(vers);
struct ADC_client_callback_data data;
data.hubinfo = &hubinfo;
client->callback(client, ADC_CLIENT_HUB_INFO, &data);
hub_free(hubinfo.name);
hub_free(hubinfo.description);
hub_free(hubinfo.version);
break;
}
case ADC_CMD_BSCH: case ADC_CMD_BSCH:
case ADC_CMD_FSCH: case ADC_CMD_FSCH:
{ {
client->callback(client, ADC_CLIENT_SEARCH_REQ, 0);
break; break;
} }
case ADC_CMD_BINF: case ADC_CMD_BINF:
{ {
if (strlen(start) > 9) if (msg->source == client->sid)
{
char t = start[9]; start[9] = 0; sid_t sid = string_to_sid(&start[5]); start[9] = t;
if (sid == client->sid)
{ {
if (client->state == ps_verify || client->state == ps_identify) if (client->state == ps_verify || client->state == ps_identify)
{ {
ADC_client_on_login(client); ADC_client_on_login(client);
} }
} }
else
{
client->callback(client, ADC_CLIENT_USER_JOIN, 0);
} }
break;
} }
case ADC_CMD_ISTA: case ADC_CMD_ISTA:
if (strncmp(start, "ISTA 000", 8)) /*
if (strncmp(line, "ISTA 000", 8))
{ {
ADC_client_debug(client, "status: '%s'\n", (start + 9)); ADC_client_debug(client, "status: '%s'\n", (start + 9));
} }
*/
break; break;
default: default:
break; break;
} }
start = &pos[1]; adc_msg_free(msg);
}
static ssize_t ADC_client_recv(struct ADC_client* client)
{
ssize_t size = net_con_recv(client->con, &client->recvbuf[client->r_offset], ADC_BUFSIZE - client->r_offset);
if (size <= 0)
return size;
client->r_offset += size;
client->recvbuf[client->r_offset] = 0;
char* start = client->recvbuf;
char* pos;
char* lastPos = 0;
size_t remaining = client->r_offset;
while ((pos = memchr(start, '\n', remaining)))
{
pos[0] = 0;
ADC_client_on_recv_line(client, start, pos - start);
pos++;
remaining -= (pos - start);
start = pos;
lastPos = pos;
} }
if (lastPos) if (lastPos)
{ {
client->r_offset = strlen(lastPos); memmove(client->recvbuf, lastPos, remaining);
memmove(client->recvbuf, lastPos, strlen(lastPos)); client->r_offset = remaining;
memset(&client->recvbuf[client->r_offset], 0, ADC_BUFSIZE-client->r_offset);
}
else
{
// client->r_offset = size;
} }
return 0; return 0;
} }
@ -270,7 +326,6 @@ void ADC_client_send_info(struct ADC_client* client)
int ADC_client_create(struct ADC_client* client, const char* nickname, const char* description) int ADC_client_create(struct ADC_client* client, const char* nickname, const char* description)
{ {
ADC_client_debug(client, "ADC_client_create: %s", nickname);
memset(client, 0, sizeof(struct ADC_client)); memset(client, 0, sizeof(struct ADC_client));
int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP); int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP);
@ -304,6 +359,8 @@ int ADC_client_connect(struct ADC_client* client, const char* address)
{ {
if (!ADC_client_parse_address(client, address)) if (!ADC_client_parse_address(client, address))
return 0; return 0;
client->callback(client, ADC_CLIENT_CONNECTING, 0);
} }
int ret = net_connect(client->con->sd, (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in)); int ret = net_connect(client->con->sd, (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
@ -317,7 +374,6 @@ int ADC_client_connect(struct ADC_client* client, const char* address)
{ {
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE); net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
ADC_client_set_state(client, ps_conn); ADC_client_set_state(client, ps_conn);
ADC_client_debug(client, "connecting...");
} }
} }
else else
@ -331,9 +387,9 @@ int ADC_client_connect(struct ADC_client* client, const char* address)
static void ADC_client_on_connected(struct ADC_client* client) static void ADC_client_on_connected(struct ADC_client* client)
{ {
net_con_update(client->con, NET_EVENT_READ); net_con_update(client->con, NET_EVENT_READ);
client->callback(client, ADC_CLIENT_CONNECTED, 0);
ADC_client_send(client, ADC_HANDSHAKE); ADC_client_send(client, ADC_HANDSHAKE);
ADC_client_set_state(client, ps_protocol); ADC_client_set_state(client, ps_protocol);
ADC_client_debug(client, "connected.");
} }
static void ADC_client_on_disconnected(struct ADC_client* client) static void ADC_client_on_disconnected(struct ADC_client* client)
@ -341,14 +397,13 @@ static void ADC_client_on_disconnected(struct ADC_client* client)
net_con_close(client->con); net_con_close(client->con);
hub_free(client->con); hub_free(client->con);
client->con = 0; client->con = 0;
ADC_client_debug(client, "disconnected.");
ADC_client_set_state(client, ps_none); ADC_client_set_state(client, ps_none);
} }
static void ADC_client_on_login(struct ADC_client* client) static void ADC_client_on_login(struct ADC_client* client)
{ {
ADC_client_debug(client, "logged in.");
ADC_client_set_state(client, ps_normal); ADC_client_set_state(client, ps_normal);
client->callback(client, ADC_CLIENT_LOGGED_IN, 0);
} }
void ADC_client_disconnect(struct ADC_client* client) void ADC_client_disconnect(struct ADC_client* client)
@ -356,7 +411,6 @@ void ADC_client_disconnect(struct ADC_client* client)
if (client->con->sd != -1) if (client->con->sd != -1)
{ {
net_con_close(client->con); net_con_close(client->con);
ADC_client_debug(client, "disconnected.");
} }
} }
@ -407,7 +461,11 @@ static int ADC_client_parse_address(struct ADC_client* client, const char* arg)
memset(&client->addr, 0, sizeof(client->addr)); memset(&client->addr, 0, sizeof(client->addr));
client->addr.sin_family = AF_INET; client->addr.sin_family = AF_INET;
client->addr.sin_port = htons(port); client->addr.sin_port = htons(port);
memcpy(&client->addr.sin_addr, &addr, sizeof(struct in_addr)); memcpy(&client->addr.sin_addr, addr, sizeof(struct in_addr));
return 1; return 1;
} }
void ADC_client_set_callback(struct ADC_client* client, adc_client_cb cb)
{
client->callback = cb;
}

View File

@ -36,17 +36,58 @@ enum ADC_client_state
struct ADC_client; struct ADC_client;
typedef void (*adc_client_connection_status_cb)(struct ADC_client*, int code, const char* data); enum ADC_client_callback_type
typedef void (*adc_client_message_cb)(struct ADC_client*, const char* msg, int flags);
typedef void (*adc_client_status_cb)(struct ADC_client*, const char* status, int code);
struct ADC_client_callbacks
{ {
adc_client_connection_status_cb connection; ADC_CLIENT_CONNECTING = 1001,
adc_client_message_cb message; ADC_CLIENT_CONNECTED = 1002,
adc_client_status_cb status; ADC_CLIENT_DISCONNECTED = 1003,
ADC_CLIENT_LOGGING_IN = 2001,
ADC_CLIENT_PASSWORD_REQ = 2002,
ADC_CLIENT_LOGGED_IN = 2003,
ADC_CLIENT_LOGIN_ERROR = 2004,
ADC_CLIENT_PROTOCOL_STATUS = 3001,
ADC_CLIENT_MESSAGE = 3002,
ADC_CLIENT_CONNECT_REQ = 3003,
ADC_CLIENT_REVCONNECT_REQ = 3004,
ADC_CLIENT_SEARCH_REQ = 3005,
ADC_CLIENT_SEARCH_REP = 3006,
ADC_CLIENT_USER_JOIN = 4001,
ADC_CLIENT_USER_QUIT = 4002,
ADC_CLIENT_USER_UPDATE = 4003,
ADC_CLIENT_HUB_INFO = 5001,
}; };
struct ADC_hub_info
{
char* name;
char* description;
char* version;
};
struct ADC_chat_message
{
sid_t from_sid;
sid_t to_sid;
char* message;
int flags;
};
struct ADC_client_callback_data
{
union {
struct ADC_hub_info* hubinfo;
struct ADC_chat_message* chat;
};
};
typedef int (*adc_client_cb)(struct ADC_client*, enum ADC_client_callback_type, struct ADC_client_callback_data* data);
struct ADC_client struct ADC_client
{ {
sid_t sid; sid_t sid;
@ -54,12 +95,13 @@ struct ADC_client
char info[ADC_BUFSIZE]; char info[ADC_BUFSIZE];
char recvbuf[ADC_BUFSIZE]; char recvbuf[ADC_BUFSIZE];
char sendbuf[ADC_BUFSIZE]; char sendbuf[ADC_BUFSIZE];
adc_client_cb callback;
size_t s_offset; size_t s_offset;
size_t r_offset; size_t r_offset;
size_t timeout; size_t timeout;
struct net_connection* con; struct net_connection* con;
struct net_timer* timer; struct net_timer* timer;
struct ADC_client_callbacks callbacks;
struct sockaddr_in addr; struct sockaddr_in addr;
char* hub_address; char* hub_address;
char* nick; char* nick;
@ -67,6 +109,7 @@ struct ADC_client
}; };
int ADC_client_create(struct ADC_client* client, const char* nickname, const char* description); int ADC_client_create(struct ADC_client* client, const char* nickname, const char* description);
void ADC_client_set_callback(struct ADC_client* client, adc_client_cb);
void ADC_client_destroy(struct ADC_client* client); void ADC_client_destroy(struct ADC_client* client);
int ADC_client_connect(struct ADC_client* client, const char* address); int ADC_client_connect(struct ADC_client* client, const char* address);
void ADC_client_disconnect(struct ADC_client* client); void ADC_client_disconnect(struct ADC_client* client);

View File

@ -4,17 +4,74 @@
#include "adcclient.h" #include "adcclient.h"
static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data)
{
switch (type)
{
case ADC_CLIENT_CONNECTING:
puts("*** Connecting...");
break;
case ADC_CLIENT_CONNECTED:
puts("*** Connected.");
break;
case ADC_CLIENT_DISCONNECTED:
puts("*** Disconnected.");
break;
case ADC_CLIENT_LOGGING_IN:
puts("*** Logging in...");
break;
case ADC_CLIENT_PASSWORD_REQ:
puts("*** Requesting password.");
case ADC_CLIENT_LOGGED_IN:
puts("*** Logged in.");
break;
case ADC_CLIENT_LOGIN_ERROR:
puts("*** Login error");
break;
case ADC_CLIENT_MESSAGE:
printf(" <%s> %s\n", sid_to_string(data->chat->from_sid), data->chat->message);
break;
case ADC_CLIENT_USER_JOIN:
break;
case ADC_CLIENT_USER_QUIT:
break;
case ADC_CLIENT_SEARCH_REQ:
break;
case ADC_CLIENT_HUB_INFO:
printf(" Hub: \"%s\" [%s]\n"
" \"%s\"\n", data->hubinfo->name, data->hubinfo->version, data->hubinfo->description);
break;
default:
printf("Not handled event=%d\n", (int) type);
return 0;
break;
}
return 1;
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
struct ADC_client client; struct ADC_client client;
net_initialize(); net_initialize();
ADC_client_create(&client, "uhub-admin", "stresstester"); ADC_client_create(&client, "uhub-admin", "stresstester");
ADC_client_set_callback(&client, handle);
ADC_client_connect(&client, "adc://adc.extatic.org:1511"); ADC_client_connect(&client, "adc://adc.extatic.org:1511");
printf("START\n");
event_dispatch(); event_dispatch();
printf("STOP\n");
ADC_client_destroy(&client); ADC_client_destroy(&client);
net_destroy(); net_destroy();