2

To make a long story short, i am implementing a mix-net in C. To do this i'm creating several individual daemons which listen on a section of TCP ports (say 31001-31008), receive data on those ports and put it into a buffer (say TCP port 31002 --> char *data[2]), and then eventually write the data out on another set of ports (say 51001-51008) to the next daemon in the list.

With that out of the way, here's my confusion! I did a lot of reading on here and elsewhere and decided that the easiest way to accomplish this would be using libevent2. I basically am starting with this (at the bottom of the page): http://www.wangafu.net/~nickm/libevent-book/Ref8_listener.html ... except i am opening 8 ports instead of 1.

QUESTION: I've read through the manual but i'm a little confused on how to determine which port the data came from. For example, if i receive data on port 31004, i want to know to write it into data[4].

I thought about creating a different callback for each port i open, but that gets ugly. Is there an easier way?

Here is some psuedo-code of what i am trying to accomplish, feel free to make suggestions! I also looked into doing this in something like python, but it seems like python has the same issues with events.

define baseport 31000
define numports 8

public char *data[numports];

callback:
    /* a connection was made */
    received_data = recv(blah)

    databin = port_received_on % baseport
    ////// How do i know what port it was received on? /////
    strncpy(data[databin], received_data, sizeof(data[databin]));

main:
    for (i = 1; i <= numports; i++)
            data[i] = malloc 

    struct event_base *base;
    //setup base event, etc.

    for (int i = 1; i <= numports; i++) {
            //setup localhost connection, open 8 ports
            sin.sin_port = htons(baseport + i);

    //configure listener with callback to "callback"
    }

    dispatch
Chris C
  • 259
  • 2
  • 15
  • That's where C++ is much better than C. You could easily use an `std::bind()` where one of the parameters is `i` (or `baseport + i`). Since 2012, hopefully you switched to C++. – Alexis Wilke Jul 17 '21 at 16:48

1 Answers1

2

You could use one callback for each port, but that callback is only acting as a proxy calling the real callback with the correct array index.

It can even by somewhat automated with a macro:

#define DEF_CALLBACK(idx)      \
    void callback_ ## idx()    \
    {                          \
        real_callback(idx);    \
    }

void real_callback(int idx)
{
    /* ... */
}

DEF_CALLBACK(1)
DEF_CALLBACK(2)
/* etc. */

Now you have the real callback function real_callback as well as a set of functions named callback_1, callback_2, etc.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • That's a much cleaner approach than what i had in mind, thanks! I am curious if there's a built-in way to do this, though. I'll play around with implementing what you're suggesting and see how it goes. – Chris C Oct 08 '12 at 14:51
  • Sorry it took me a while to get back to this thread. I ended up implementing this as you suggested and it works great. Thanks again! – Chris C Oct 13 '12 at 22:13