Skip to content

Commit

Permalink
Update C measurement lib and add example
Browse files Browse the repository at this point in the history
  • Loading branch information
mirokuratczyk committed Jun 15, 2018
1 parent 4045955 commit 7f59151
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ AndroidLibrary/psi.aar
*.o
*.a
*.so
*.dylib

# Folders
_obj
Expand Down
5 changes: 0 additions & 5 deletions Bindings/CXX/.gitignore

This file was deleted.

8 changes: 0 additions & 8 deletions Bindings/CXX/Makefile

This file was deleted.

8 changes: 8 additions & 0 deletions MeasurementClient/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
shared:
go build -buildmode=c-shared -o PsiphonTunnel.dylib PsiphonTunnel.go
.PHONY: shared

static:
go build -buildmode=c-archive -o PsiphonTunnel.a PsiphonTunnel.go

.PHONY: static
99 changes: 53 additions & 46 deletions Bindings/CXX/main.go → MeasurementClient/PsiphonTunnel.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package main


import "C"

import (
"context"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"time"

"github.com/Psiphon-Labs/psiphon-tunnel-core/MobileLibrary/psi"
Expand All @@ -22,21 +18,32 @@ type NoticeEvent struct {

type PsiphonProvider struct {
connected chan bool
err chan error
stopped chan bool
networkID string
}

func (pp PsiphonProvider) Notice(noticeJSON string) {
var event NoticeEvent

err := json.Unmarshal([]byte(noticeJSON), &event)
if err != nil {
fmt.Printf("Failed to unmarshal: %v", err)
select {
case pp.err <- err:
default:
}
return
}

if event.NoticeType == "Tunnels" {
count := event.Data["count"].(float64)
if count > 0 {
pp.connected <- true
select {
case pp.connected <- true:
default:
}
}
}
fmt.Printf("notice: %s\n", noticeJSON)
}

func (pp PsiphonProvider) HasNetworkConnectivity() int {
Expand All @@ -60,83 +67,83 @@ func (pp PsiphonProvider) GetSecondaryDnsServer() string {
}

func (pp PsiphonProvider) GetNetworkID() string {
return ""
return pp.networkID
}

const runtimeTimeout = 90 * time.Second

var provider PsiphonProvider

type StartResult struct {
BootstrapTime float64 `json:"bootstrap_time"`
ErrorString string `json:"error"`
ErrorString string `json:"error,omitempty"`
}

//export Start
func Start(configJSON,
embeddedServerEntryList string) *C.char {

provider.connected = make(chan bool)
embeddedServerEntryList, networkID string, timeout int64) *C.char {

var result StartResult

provider.connected = make(chan bool)
provider.stopped = make(chan bool)
provider.err = make(chan error)

runtimeTimeout := time.Duration(timeout) * time.Second
startTime := time.Now().UTC()

connectedCtx, cancel := context.WithTimeout(context.Background(), runtimeTimeout)
defer cancel()

fmt.Printf("Passing: %s\n", configJSON)

err := psi.Start(configJSON, embeddedServerEntryList, "", provider, false, false)
if err != nil {
fmt.Println(err)
return errorJsonForC(err)
}

select {
case <-connectedCtx.Done():
result.BootstrapTime = bootstrapTime(startTime)
err = connectedCtx.Err()
if err != nil {
result.ErrorString = err.Error()
Stop()
}
delta := time.Now().UTC().Sub(startTime)
result.BootstrapTime = delta.Seconds()
case <-provider.connected:
delta := time.Now().UTC().Sub(startTime)
result.BootstrapTime = delta.Seconds()
result.BootstrapTime = bootstrapTime(startTime)
cancel()
case <-provider.stopped:
result.BootstrapTime = bootstrapTime(startTime)
result.ErrorString = "stop signalled before client connected"
cancel()
case err := <-provider.err:
result.BootstrapTime = bootstrapTime(startTime)
result.ErrorString = err.Error()
cancel()
}

b, err := json.Marshal(result)
resultJSON, err := json.Marshal(result)
if err != nil {
fmt.Printf("Error in marshal: %s", err.Error())
return C.CString("error")
return errorJsonForC(err)
}
retStr := string(b)
fmt.Printf("retStr: %s\n", retStr)
return C.CString(retStr)
}

//export Stop
func Stop() bool {
psi.Stop()
return true
return C.CString(string(resultJSON))
}

func main() {
var configFilename string
flag.StringVar(&configFilename, "config", "", "configuration input file")
flag.Parse()
func bootstrapTime(startTime time.Time) float64 {
delta := time.Now().UTC().Sub(startTime)
return delta.Seconds()
}

if configFilename == "" {
fmt.Println("A config file is required")
os.Exit(1)
}
func errorJsonForC(err error) *C.char {
return C.CString(fmt.Sprintf("{\"error\": \"%s\"}", err.Error()))
}

configFileContents, err := ioutil.ReadFile(configFilename)
if err != nil {
fmt.Printf("Invalid config file: %s\n", err.Error())
os.Exit(1)
//export Stop
func Stop() bool {
psi.Stop()
select {
case provider.stopped <- true:
default:
}

Start(string(configFileContents), "")
return true
}

func main() {} // stub required by cgo
1 change: 1 addition & 0 deletions MeasurementClient/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main
12 changes: 12 additions & 0 deletions MeasurementClient/example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
main: main.o PsiphonTunnel.dylib
gcc PsiphonTunnel.dylib -o main main.o

main.o: main.c
gcc -I.. -c main.c

PsiphonTunnel.dylib: ../PsiphonTunnel.go
go build -buildmode=c-shared -o PsiphonTunnel.dylib ../PsiphonTunnel.go

clean:
rm PsiphonTunnel.dylib PsiphonTunnel.h main main.o

Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "C" {
#endif


extern char* Start(GoString p0, GoString p1);
extern char* Start(GoString p0, GoString p1, GoString p2, GoInt64 p3);

extern GoUint8 Stop();

Expand Down
68 changes: 68 additions & 0 deletions MeasurementClient/example/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "PsiphonTunnel.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *read_file(char *filename) {
char *buffer = NULL;
size_t size = 0;

FILE *fp = fopen(filename, "r");

if (!fp) {
return NULL;
}

fseek(fp, 0, SEEK_END);
size = ftell(fp);

rewind(fp);
buffer = malloc((size + 1) * sizeof(*buffer));

fread(buffer, size, 1, fp);
buffer[size] = '\0';

return buffer;
}

int main(int argc, char *argv[]) {

// load config
char * const default_config = "psiphon_config";

char * config = argv[1];

if (!config) {
config = default_config;
printf("Using default config file: %s\n", default_config);
}

char *file_contents = read_file(config);
if (!file_contents) {
printf("Could not find config file: %s\n", config);
return 1;
}

GoString psiphon_config = {file_contents, strlen(file_contents)};

// set server list
GoString serverList = {};

// set timout
long long timeout = 10;

// set network ID
char * const test_network_id = "TEST";
GoString network_id = {test_network_id, strlen(test_network_id)};

// start will return once Psiphon connects or does not connect for timeout seconds
char *result = Start(psiphon_config, serverList, network_id, timeout);
Stop();

// print results
printf("Result: %s\n", result);

// cleanup
free(result);
}

0 comments on commit 7f59151

Please sign in to comment.