wodVPN ActiveX Control - Fast notifications interface
 

* VB mediator code (using wodVPN itself)

* PHP mediator code

* C mediator code

 

wodVPN code (example in VB)



Since version 1.0.2, wodVPN can also perform as the mediator. You can use simple code like this to run mediator on port 8000
 

wodVPN1.Mediator.Start SrchUDPSingle, 8000

and then you should check in MediatorConnected, MediatorDisconnected and MediatorExchangeData events to see who is connecting.

Private Sub wodVPN1_MediatorConnected(ByVal IP As String, ByVal Port As Long, ByVal FromID As String, ByVal ToID As String, ByVal Data As String, Allow As Boolean)
    Debug.Print
FromID & " searching for " & ToID
End Sub

Private Sub wodVPN1_MediatorDisconnected(ByVal FromID As String, ByVal ToID As String)
    Debug.Print
FromID & " left"
End Sub

Private Sub wodVPN1_MediatorExchangeData(ByVal FromID As String, ByVal ToID As String)
    Debug.Print FromID & " found " & ToID
End Sub

 

 

 

PHP code



This is script for SrchUDPSingle/SrchUDPDouble Search types. You can run it on any computer that has public IP address, and is able to run PHP code. You should paste this code into new file mediator.php, and then run it as

php -q mediator.php

and that's it. If you want to change IP address or Port value, you should change socket_bind call (5th nonempty line in the script).

 
<?php
    
    error_reporting
(E_ALL);

    
    
// first we'll bind socket
    
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
    if (!
socket_bind($sock, "0.0.0.0", 8000))
        die(
"Could not bind socket\n");

    
$ip = '';
    
$port = 0;

    
socket_set_nonblock($sock);

    
$users = array();
    
$ips = array();
    
$ports = array();
    
$dates = array();
    
$data = array();

    do
    {
        
$suxref[] =& $sock;
        
socket_select($suxref, $write = NULL, $except = NULL, 5);
        
$z = @socket_recvfrom($sock, $buf, 9999, 0, $ip, $port);
        if (
$z)
        {
            
$ar = split("\r\n", $buf);
            if (
count($ar) ==
3)
            {
                echo
$ar[0] . " --> ". $ar[1] . "\r\n";

                
// locate this user
                
$i = finduser($ar[0]);
                if (
$i>=0)
                {
                    
// user found, update it
                    
$ips[$i] = $ip;
                    
$ports[$i] = $port;
                    
$dates[$i] = time();
                    
$data[$i] = $ar[
2];
                }
                else
                {
                    
// now found, add it
                    
array_push($users, $ar[0]);
                    
array_push($ips, $ip);
                    
array_push($data, $ar[
2]);
                    
array_push($ports, $port);
                    
array_push($dates, time());
                    echo
"Elements in array " . count($users) . "\r\n";
                }

                
// now check if remote peer is here too
                
$i = finduser($ar[1]); // ovdje ide $ar[1]
                
if ($i>=0)
                {
                    
$out = "\000\000". $ips[$i] . "\r\n" . $ports[$i] . "\r\n" . $data[$i];
                    
$len = strlen($out);                
                    echo
"Sending to $ip $port, total=" . socket_sendto($sock, $out, $len, 0, $ip, $port) . "\r\n";
                }
            }
        }

        for (
$i=0;$i<count($users);$i++)
        {
            if (
time() - $dates[$i] > 15)
            {
                echo
"Removing " . $users[$i] . "\r\n";
                unset(
$dates[$i]);
                
$dates = array_values($dates);
                unset(
$users[$i]);
                
$users = array_values($users);
                unset(
$ips[$i]);
                
$ips = array_values($ips);
                unset(
$ports[$i]);
                
$ports = array_values($ports);
                unset(
$data[$i]);
                
$data = array_values($data);
                
$i--;
            }
        }
        echo
"Waiting..., elements in array " . count($users) . "\r\n";
        
    } while(
true);


    function
finduser($name)
    {
        global
$users;
        
        for (
$i=0;$i<count($users);$i++)
        {
            if (
$users[$i] == $name)
            {
                return
$i;
            }
        }

        return -
1;
    }
    

?>

 

 

 

C code



This is source code for SrchUDPSingle/SrchUDPDouble Search types. You can run it on any computer that has public IP address, but make sure you compile it to appropriate architecture. We have tested it on Windows and Linux, but code is pretty-much straightforward to work on any other system too. You should paste this code into new file mediator.c, compile it, and then run as

./mediator IP:port

where both IP and port are optional arguments. If not specified, application will bind port 8000 on all interfaces.

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
#include <winsock.h>
#define _CRT_SECURE_NO_WARNINGS
#else
#include <netinet/in.h>
#include <sys/socket.h>
#endif


typedef struct medpeer
{
    char *frompeer;
    char *topeer;
    int tolen;
    char *data;
    struct sockaddr_in sock;
    unsigned long time;
    void *nextpeer;
} medpeer;

int sock;
struct sockaddr_in saddr_local;
medpeer *peers = NULL;

int error(int err)
{
    switch (err)
    {
    case 1:
        printf("Unable to bind to specified port.\n");
    }

    return err;
}

int parse_cmdline(int argc, char *argv[])
{
    char *IP = NULL, *sport = NULL;
    int port = 8000;

    if (argc>1)
    {
        sport = (char *)strchr(argv[1], ':');
        if (sport)
        {
            IP = argv[1];
            *sport = 0;
            sport++;
        }
        else
        {
            IP = NULL;
            sport = argv[1];
        }
        port = atol(sport);
    }

    saddr_local.sin_family = AF_INET;
    if (IP)
    {
        saddr_local.sin_addr.s_addr = inet_addr(IP);
        if (saddr_local.sin_addr.s_addr == INADDR_NONE)
        {
            return error(-1);
        }
    }
    else
        saddr_local.sin_addr.s_addr = INADDR_ANY;
    saddr_local.sin_port = htons((unsigned short)port);

    return 0;
}

int init_socket()
{
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    if (sock == -1)
        return 1;

    if (bind(sock, (struct sockaddr *) &saddr_local, sizeof(saddr_local)) < 0)
        return 1;

    return 0;
}

int start_mediation()
{
    int len = 0;
    char buff[32768];
    time_t t;
    struct sockaddr_in saddr_from;
    int addrlen = sizeof(struct sockaddr_in);
    medpeer *prev, *p;
    int count;

    char *frompeer, *topeer, *data;
    int found;

    int jlen;
    char *jdata;

    while (1)
    {
        len = recvfrom(sock,  buff, 32768, 0, (struct sockaddr *) &saddr_from, &addrlen);

        /* let's perform cleanup */
        t = time(NULL);
        prev = NULL;
        p = peers;
        count = 0;
        while (p)
        {
            count++;
            if (t - p->time > 15)
            {
                if (prev)
                    prev->nextpeer = p->nextpeer;
                else
                {
                    peers = (medpeer *)p->nextpeer;
                }

                printf("* Removing %s\n", p->frompeer);
                free(p->frompeer);
                free(p->topeer);
                free(p);

                count = 0;
                p = peers;
                prev = NULL;
                continue;
            }
            prev = p;
            p = (medpeer *)p->nextpeer;
        }

        printf("* Total %d peers listed\n", count);

        if (len)
        {
            frompeer = buff;
            topeer = strchr(buff, '\n');
            if (topeer && topeer > buff)
            {
                if (*(topeer-1) == '\r')
                    *(topeer-1) = 0;
                *topeer++ = 0;
                data = strchr(topeer, '\n');
                if (data && data > topeer)
                {
                    if (*(data-1) == '\r')
                        *(data-1) = 0;
                    *data++ = 0;

                    printf("%s -> %s\n", frompeer, topeer);
                    /* do we have this peer? */
                    found = 0;
                    p = peers;

                    jlen = strlen(topeer);
                    jdata = strchr(topeer, '*');
                    if (jdata)
                    {
                        if (jdata-topeer>0 && jdata-topeer<jlen)
                            jlen = jdata-topeer;
                    }

                    while (p)
                    {
                        if (!strcmp(p->frompeer, frompeer) && !strncmp(p->topeer, topeer, jlen))
                        {
                            memcpy(&p->sock, &saddr_from, sizeof(saddr_from));
                            p->time = (unsigned long)time(NULL);
                            found = 1;
                            break;
                        }
                        p = (medpeer *)p->nextpeer;
                    }

                    if (!found)
                    {
                        /* add this peer */
                        p = (medpeer *)malloc(sizeof(medpeer));
                        p->frompeer = (char *)malloc(len);
                        memcpy(p->frompeer, buff, len);
                        p->topeer = (char *)malloc(strlen(topeer)+1);
                        p->tolen = jlen;
                        strcpy(p->topeer, topeer);
                        p->data = p->frompeer + (data - frompeer);
                        memcpy(&p->sock, &saddr_from, sizeof(saddr_from));
                        p->time = (unsigned long)time(NULL);

                        p->nextpeer = peers;
                        peers = p;
                        printf("* Adding %s\n", p->frompeer);
                    }

                    if (p) /* this MUST be valid, but doesn't hurt to check */
                    {
                        medpeer *other = peers;
                        while (other)
                        {
                            if (!strncmp(topeer, other->frompeer, jlen) && !strncmp(frompeer, other->topeer, other->tolen))
                            {
                                // replace 'topeer'
                                if (strncmp(frompeer, other->topeer, other->tolen))
                                {
                                    free(other->topeer);
                                    other->topeer = (char *)malloc(strlen(frompeer)+1);
                                    strcpy(other->topeer, frompeer);
                                    other->tolen = strlen(frompeer);
                                }
                                unsigned char *ad= (unsigned char *)&other->sock.sin_addr;
                                printf("Reply to %s, IP %u.%u.%u.%u, port %d\n", frompeer, ad[0], ad[1], ad[2], ad[3], htons(other->sock.sin_port));
                                buff[0] = buff[1] = 0;
                                sprintf(buff+2, "%u.%u.%u.%u\r\n%d\r\n%s", ad[0], ad[1], ad[2], ad[3], htons(other->sock.sin_port), other->data);
                                sendto(sock, buff, strlen(buff+2)+2, 0, (struct sockaddr *) &saddr_from, sizeof(saddr_from));
                                break;
                            }
                            other = (medpeer *)other->nextpeer;
                        }
                    }
                }
            }
        }
  }
  return 1;
}

int main(int argc, char *argv[])
{
#ifdef WIN32
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,0), &wsaData);
#endif

    if (parse_cmdline(argc, argv))
        return error(2);

    if (init_socket())
        return error(1);

    start_mediation();

#ifdef WIN32
    WSACleanup();
#endif

    return 0;
}