/*
Copyright 2009 Nathan Phillip Brink
This file is a part of DistRen.
DistRen is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DistRen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with DistRen. If not, see .
*/
#include "listen.h"
#include
#include
#include
#include
#include
#include
#include
#include
/* local */
struct distrend_clientset
{
LIST *clients;
/*
for select()
*/
fd_set readfds;
fd_set writefds;
int nfds;
};
int distrend_client_new(struct distrend_client **client, int sock, enum distrend_client_state state);
int distrend_client_free(struct distrend_client *client);
int distrend_listen(struct distrend_config *config, struct distrend_clientset **clients)
{
int tmp;
struct sockaddr_in6 sockaddr =
{
.sin6_family = AF_INET6,
.sin6_port = 0,
.sin6_flowinfo = 0,
.sin6_addr = IN6ADDR_ANY_INIT,
.sin6_scope_id = 0
};
*clients = malloc(sizeof(struct distrend_clientset));
(*clients)->clients = list_init();
sockaddr.sin6_port = htonl(4050);
config->listens->sock = socket(AF_INET6, SOCK_STREAM, 0);
tmp = bind(config->listens->sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if(tmp == -1)
{
perror("bind");
free(*clients);
return 1;
}
tmp = listen(config->listens->sock, 1);
FD_ZERO(&(*clients)->readfds);
FD_ZERO(&(*clients)->writefds);
/** accept()able sockets are considered ``readable'' */
FD_SET(config->listens->sock, &(*clients)->readfds);
return 0;
}
int distrend_handleread(struct distrend_config *config,
struct distrend_client *client)
{
fprintf(stderr, "%s:%d: STUB: I'm supposed to read data from the client\n",
__FILE__, __LINE__);
return 0;
}
struct distrend_accept_client_proc_data
{
fd_set *fdset;
struct distrend_config *config;
};
int distrend_accept_client_proc(struct distrend_accept_client_proc_data *data,
struct distrend_client *client)
{
if(!FD_ISSET(client->sock, data->fdset))
/** continue iteration through the list */
return TRUE;
fprintf(stderr, "%s:%d: My traversal says that sock %d has data waiting\n",
__FILE__, __LINE__, client->sock);
distrend_handleread(data->config, client);
/** continue iteration through the list */
return TRUE;
}
int distrend_accept(struct distrend_config *config, struct distrend_clientset *clients)
{
int tmp;
fd_set readfds;
fd_set writefds;
memcpy(&readfds, &clients->readfds, sizeof(fd_set));
memcpy(&writefds, &clients->writefds, sizeof(fd_set));
tmp = select(clients->nfds, &readfds, &writefds, NULL, (struct timeval *)NULL);
if(tmp == -1)
{
perror("select");
return 1;
}
/**
deal with all sockets that have data waiting
*/
list_traverse(clients->clients, &readfds, (list_traverse_func_t)&distrend_accept_client_proc, LIST_FRNT | LIST_ALTR);
return 0;
}
int distrend_unlisten(struct distrend_listen *listens, struct distrend_clientset *clients)
{
fprintf(stderr, "%s:%d: I am a stub that needn't be implemented 'til later\n", __FILE__, __LINE__);
return 1;
}
/**
This is probably just NOT a placeholder for remotio
*/
void remotio_send_to_client(struct distrend_client *client, const char *msg, size_t len)
{
fprintf(stderr, "%s:%d: STUB I should queue data for writing to a client\n", __FILE__, __LINE__);
}
int distrend_client_new(struct distrend_client **client, int sock, enum distrend_client_state state)
{
*client = malloc(sizeof(struct distrend_client));
if(!*client)
{
fprintf(stderr, "OOM\n");
return 1;
}
(*client)->sock = sock;
(*client)->state = state;
(*client)->inmsgs = list_init();
(*client)->outmsgs = list_init();
return 0;
}
int distrend_client_free(struct distrend_client *client)
{
list_free(client->inmsgs, (void *)LIST_DEALLOC);
list_free(client->outmsgs, (void *)LIST_DEALLOC);
fprintf(stderr, "%s:%d: stub!", __FILE__, __LINE__);
return 1;
}