Commit 3d5852d7 authored by petrak's avatar petrak Committed by xHire
Browse files

TCP Listening

parent 85a8165a
......@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <event2/event.h>
#include "p2p.h"
......@@ -40,9 +40,13 @@ int main(void)
* - terminate on SIGTERM
*/
struct event_base *base;
int r;
if ((r = listen_init()) != 0)
if ((r = listen_init(&base)) != 0)
return r;
event_base_dispatch(base);
return 0;
}
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
......@@ -8,16 +10,36 @@
#include "p2p.h"
/**
* @brief callback for reading an input buffer
* @param bev buffer to read data from
* @param ctx optional programmer-defined data to be passed into this callback
*/
static void read_cb(struct bufferevent *bev, void *ctx)
{
struct evbuffer *input = bufferevent_get_input(bev);
struct evbuffer *output = bufferevent_get_output(bev);
/* Copy all the data from the input buffer to the output buffer. */
/* FOR TESTING PURPOSES */
/* Display the input data */
size_t len = evbuffer_get_length(input);
char *data = (char *) malloc(len * sizeof(char));
evbuffer_copyout(input, data, len);
printf("Sending back: %s", data);
free(data);
/* Copy all the data from the input buffer to the output buffer */
evbuffer_add_buffer(output, input);
}
/**
* @brief callback for bufferevent event detection
* @param bev bufferevent on which the event occured
* @param events flags of the events occured
* @param ctx optional programmer-defined data to be passed into this callback
*/
static void event_cb(struct bufferevent *bev, short events, void *ctx)
{
......@@ -29,11 +51,19 @@ static void event_cb(struct bufferevent *bev, short events, void *ctx)
}
}
/**
* @brief callback for accepting a new connection
* @param listener incoming connection
* @param fd file descriptor for the new connection
* @param address routing information
* @param socklen size of address
* @param ctx optional programmer-defined data to be passed into this callback
*/
static void accept_conn_cb(struct evconnlistener *listener,
evutil_socket_t fd, struct sockaddr *address, int socklen,
void *ctx)
{
/* Set up a bufferevent for a new connection. */
/* Set up a bufferevent for a new connection */
struct event_base *base = evconnlistener_get_base(listener);
struct bufferevent *bev = bufferevent_socket_new(
base, fd, BEV_OPT_CLOSE_ON_FREE);
......@@ -41,8 +71,37 @@ static void accept_conn_cb(struct evconnlistener *listener,
bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL);
bufferevent_enable(bev, EV_READ|EV_WRITE);
/* Display IP address of the one connecting to us */
char *s = NULL;
switch (address->sa_family) {
case AF_INET: {
struct sockaddr_in *addr_in = (struct sockaddr_in *) address;
s = malloc(INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN);
break;
}
case AF_INET6: {
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *) address;
s = malloc(INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN);
break;
}
default:
break;
}
printf("%s has connected to you.\n", s);
free(s);
}
/**
* @brief callback for listener error detection
* @param listener listener on which the error occured
* @param ctx optional programmer-defined data to be passed into this callback
*/
static void accept_error_cb(struct evconnlistener *listener, void *ctx)
{
struct event_base *base = evconnlistener_get_base(listener);
......@@ -53,17 +112,16 @@ static void accept_error_cb(struct evconnlistener *listener, void *ctx)
event_base_loopexit(base, NULL);
}
int listen_init()
int listen_init(struct event_base **base)
{
struct event_base *base;
struct evconlistener *listener;
struct evconnlistener *listener;
struct sockaddr_in sin;
int port = 31070;
base = event_base_new();
if (!base) {
*base = event_base_new();
if (!*base) {
puts("Couldn't open event base");
return 1;
}
......@@ -73,7 +131,7 @@ int listen_init()
sin.sin_addr.s_addr = htonl(0);
sin.sin_port = htons(port);
listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
listener = evconnlistener_new_bind(*base, accept_conn_cb, NULL,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
(struct sockaddr*)&sin, sizeof(sin));
if (!listener) {
......@@ -81,8 +139,6 @@ int listen_init()
return 1;
}
evconnlistener_set_error_cb(listener, accept_error_cb);
event_base_dispatch(base);
return 0;
}
#ifndef P2P_H
#define P2P_H
int listen_init();
#include <event2/event.h>
/**
* @brief initialize listening and set up callbacks
* @param base event loop
* @return 1 if an error occured
* @return 0 if successfully initialized
*/
int listen_init(struct event_base **base);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment