diff options
Diffstat (limited to 'exports/servers.go')
| -rw-r--r-- | exports/servers.go | 342 |
1 files changed, 0 insertions, 342 deletions
diff --git a/exports/servers.go b/exports/servers.go deleted file mode 100644 index 73b8b6c..0000000 --- a/exports/servers.go +++ /dev/null @@ -1,342 +0,0 @@ -package main - -/* -// for free and size_t -#include <stdlib.h> -#include "error.h" -#include "server.h" -*/ -import "C" - -import ( - "unsafe" - - "github.com/eduvpn/eduvpn-common/client" - "github.com/eduvpn/eduvpn-common/internal/server" -) - -// Get the pointer to the C struct for the profile -// We allocate the struct, the profile ID and the display name -func getCPtrProfile(profile *server.Profile) *C.serverProfile { - // Allocate the struct using malloc and the size of the struct - cProfile := (*C.serverProfile)(C.malloc(C.size_t(unsafe.Sizeof(C.serverProfile{})))) - cProfile.id = C.CString(profile.ID) - cProfile.display_name = C.CString(profile.DisplayName) - if profile.DefaultGateway { - cProfile.default_gateway = C.int(1) - } else { - cProfile.default_gateway = C.int(0) - } - - return cProfile -} - -// Get the pointer to the C struct for the profiles -// We allocate the struct and the struct inside it for the profiles -func getCPtrProfiles(serverProfiles *server.ProfileInfo) *C.serverProfiles { - goProfiles := serverProfiles.Info.ProfileList - // Allocate the profles struct using malloc and the size of a pointer - cProfiles := (*C.serverProfiles)(C.malloc(C.size_t(uintptr(0)))) - totalProfiles := C.size_t(len(goProfiles)) - // Defaults if we have no profiles - cProfiles.current = C.int(0) - cProfiles.profiles = nil - cProfiles.total_profiles = totalProfiles - // If we have profiles (which we should), we allocate the struct with malloc and the size of a pointer - // We then fill the struct by converting it to a go slice and get a C pointer for each profile - if totalProfiles > 0 { - profilesPtr := (**C.serverProfile)(C.malloc(totalProfiles * C.size_t(unsafe.Sizeof(uintptr(0))))) - profiles := unsafe.Slice(profilesPtr, totalProfiles) - index := 0 - for _, profile := range goProfiles { - profiles[index] = getCPtrProfile(&profile) - index++ - } - cProfiles.current = C.int(serverProfiles.CurrentProfileIndex()) - cProfiles.profiles = (**C.serverProfile)(profilesPtr) - } - return cProfiles -} - -// Free the profiles by looping through them if there are any -// Also free the pointer itself -// -//export FreeProfiles -func FreeProfiles(profiles *C.serverProfiles) { - // We should only free the profiles if we have them (which we should) - if profiles.total_profiles > 0 { - // Convert it to a go slice - profilesSlice := unsafe.Slice(profiles.profiles, profiles.total_profiles) - // Loop through the pointers and free th allocated strings and the struct itself - for i := C.size_t(0); i < profiles.total_profiles; i++ { - C.free(unsafe.Pointer(profilesSlice[i].id)) - C.free(unsafe.Pointer(profilesSlice[i].display_name)) - C.free(unsafe.Pointer(profilesSlice[i])) - } - // Free the inner profiles struct - C.free(unsafe.Pointer(profiles.profiles)) - } - // Free the profiles struct itself - C.free(unsafe.Pointer(profiles)) -} - -// Get a list of strings with a size as a c structure -// Returns the size in size_t and the list of strings as a double pointer char -func getCPtrListStrings(allStrings []string) (C.size_t, **C.char) { - // Get the total strings in size_t - totalStrings := C.size_t(len(allStrings)) - - // If we have strings - // Allocate memory for the strings array - if totalStrings > 0 { - stringsPtr := (**C.char)(C.malloc(totalStrings * C.size_t(unsafe.Sizeof(uintptr(0))))) - // Go slice conversion - cStrings := unsafe.Slice(stringsPtr, totalStrings) - - // Loop through and allocate the string for each contact - for index, string := range allStrings { - cStrings[index] = C.CString(string) - } - return totalStrings, (**C.char)(stringsPtr) - } - - // No strings then the length is zero and the char array is nil - return C.size_t(0), nil -} - -// Function for freeing an array/list of strings -// It takes the strings as a pointer to a string and the total strings in size_t -func freeCListStrings(allStrings **C.char, totalStrings C.size_t) { - // If we have strings we should free them - // By converting to a Go slice, and freeing them ony by one - // At last free the pointer itself - if totalStrings > 0 { - stringsSlice := unsafe.Slice(allStrings, totalStrings) - for i := C.size_t(0); i < totalStrings; i++ { - C.free(unsafe.Pointer(stringsSlice[i])) - } - C.free(unsafe.Pointer(allStrings)) - } -} - -// Function for getting the server, -// It gets the main state as a pointer as we need to convert some string maps to localized strings -// It gets the base information for a server as well -func getCPtrServer(state *client.Client, base *client.ServerBase) *C.server { - // Allocation using malloc and the size of the struct - cServer := (*C.server)(C.malloc(C.size_t(unsafe.Sizeof(C.server{})))) - // String allocation and translate the display name - identifier := base.URL - countryCode := "" - // A secure internet server has multiple locations - locations := []string{} - if base.Type == "secure_internet" { - identifier = state.Servers.SecureInternetHomeServer.HomeOrganizationID - countryCode = state.Servers.SecureInternetHomeServer.CurrentLocation - locations = state.Discovery.SecureLocationList() - } - - cServer.identifier = C.CString(identifier) - cServer.display_name = C.CString(state.GetTranslated(base.DisplayName)) - cServer.country_code = C.CString(countryCode) - cServer.server_type = C.CString(base.Type) - // Call the helper to get the list of support contacts - cServer.total_support_contact, cServer.support_contact = getCPtrListStrings( - base.SupportContact, - ) - locationsStruct := (*C.serverLocations)(C.malloc(C.size_t(unsafe.Sizeof(C.servers{})))) - locationsStruct.total_locations, locationsStruct.locations = getCPtrListStrings(locations) - cServer.locations = locationsStruct - - profiles := base.ValidProfiles(state.SupportsWireguard) - cServer.profiles = getCPtrProfiles(&profiles) - // No endtime is given if we get servers when it has been partially initialised - if base.EndTime.IsZero() { - cServer.expire_time = C.ulonglong(0) - } else { - // The expire time should be stored as an unsigned long long in unix time - cServer.expire_time = C.ulonglong(base.EndTime.Unix()) - } - return cServer -} - -// Function for freeing a single server -// Gets the pointer to C struct -// -//export FreeServer -func FreeServer(info *C.server) { - // Free strings - C.free(unsafe.Pointer(info.identifier)) - C.free(unsafe.Pointer(info.display_name)) - C.free(unsafe.Pointer(info.country_code)) - C.free(unsafe.Pointer(info.server_type)) - - // Free arrays - freeCListStrings(info.support_contact, info.total_support_contact) - FreeSecureLocations(info.locations) - FreeProfiles(info.profiles) - - // Free the struct itself - C.free(unsafe.Pointer(info)) -} - -// Get the C ptr to the servers, returns the length in size_t and the double pointer to the struct -func getCPtrServers( - state *client.Client, - serverMap map[string]*server.InstituteAccessServer, -) (C.size_t, **C.server) { - totalServers := C.size_t(len(serverMap)) - // If we have servers, which is not always the case - if totalServers > 0 { - serversPtr := (**C.server)(C.malloc(totalServers * C.size_t(unsafe.Sizeof(uintptr(0))))) - servers := unsafe.Slice(serversPtr, totalServers) - index := 0 - for _, currentServer := range serverMap { - cServer := getCPtrServer(state, ¤tServer.Basic) - servers[index] = cServer - index++ - } - return totalServers, serversPtr - } - return C.size_t(0), nil -} - -// This function takes the servers as a C struct pointer as input -// It frees all allocated memory for the server -// -//export FreeServers -func FreeServers(cServers *C.servers) { - // Free the custom servers if there are any - if cServers.total_custom > 0 { - customServers := unsafe.Slice(cServers.custom_servers, cServers.total_custom) - for i := C.size_t(0); i < cServers.total_custom; i++ { - FreeServer(customServers[i]) - } - C.free(unsafe.Pointer(cServers.custom_servers)) - } - // Free the institute access servers if there are any - if cServers.total_institute > 0 { - instituteServers := unsafe.Slice(cServers.institute_servers, cServers.total_institute) - - for i := C.size_t(0); i < cServers.total_institute; i++ { - FreeServer(instituteServers[i]) - } - C.free(unsafe.Pointer(cServers.institute_servers)) - } - // Free the secure internet server if there is one - if cServers.secure_internet_server != nil { - FreeServer(cServers.secure_internet_server) - } - // Free the structure itself - C.free(unsafe.Pointer(cServers)) -} - -// Return the servers as a C struct pointer -// It takes the state as a pointer as we need to translate some strings -// It also takes the servers as a pointer that belongs to the main state or gathered from the callback -func getSavedServersWithOptions(state *client.Client, servers *server.Servers) *C.servers { - // Allocate the struct that we will return - // With the size of the c struct - returnedStruct := (*C.servers)(C.malloc(C.size_t(unsafe.Sizeof(C.servers{})))) - - // Get the different categories of servers - totalCustom, customPtr := getCPtrServers(state, servers.CustomServers.Map) - totalInstitute, institutePtr := getCPtrServers(state, servers.InstituteServers.Map) - var secureServerPtr *C.server - secureInternetBase, secureInternetBaseErr := servers.SecureInternetHomeServer.Base() - if secureInternetBaseErr == nil && secureInternetBase != nil { - // FIXME: log error? - secureServerPtr = getCPtrServer(state, secureInternetBase) - // Give a new identifier - C.free(unsafe.Pointer(secureServerPtr.identifier)) - secureServerPtr.identifier = C.CString(servers.SecureInternetHomeServer.HomeOrganizationID) - secureServerPtr.country_code = C.CString(servers.SecureInternetHomeServer.CurrentLocation) - } - - // Fill the struct and return - returnedStruct.custom_servers = customPtr - returnedStruct.total_custom = totalCustom - returnedStruct.institute_servers = institutePtr - returnedStruct.total_institute = totalInstitute - returnedStruct.secure_internet_server = secureServerPtr - return returnedStruct -} - -// This function takes the name as input which is the name of the client -// It gets the state by name and then returns the saved servers as a c struct belonging to it -// -//export GetSavedServers -func GetSavedServers(name *C.char) (*C.servers, *C.error) { - nameStr := C.GoString(name) - state, stateErr := GetVPNState(nameStr) - if stateErr != nil { - return nil, getError(stateErr) - } - servers := getSavedServersWithOptions(state, &state.Servers) - return servers, nil -} - -// This function takes the name as input which is the name of the client -// It gets the state by name and then returns the current server as a c struct belonging to it -// -//export GetCurrentServer -func GetCurrentServer(name *C.char) (*C.server, *C.error) { - nameStr := C.GoString(name) - state, stateErr := GetVPNState(nameStr) - if stateErr != nil { - return nil, getError(stateErr) - } - server, serverErr := state.Servers.GetCurrentServer() - if serverErr != nil { - return nil, getError(serverErr) - } - base, baseErr := server.Base() - if baseErr != nil { - return nil, getError(baseErr) - } - cServer := getCPtrServer(state, base) - return cServer, nil -} - -// This function takes the state as input which is the main state -// It also takes the data as an interface and if it has the servers type gets the data as a c struct otherwise nil -func getTransitionDataServers(state *client.Client, data interface{}) *C.servers { - if converted, ok := data.(server.Servers); ok { - return getSavedServersWithOptions(state, &converted) - } - return nil -} - -//export FreeSecureLocations -func FreeSecureLocations(locations *C.serverLocations) { - freeCListStrings(locations.locations, locations.total_locations) - C.free(unsafe.Pointer(locations)) -} - -func getTransitionSecureLocations(data interface{}) *C.serverLocations { - if locations, ok := data.([]string); ok { - returnedStruct := (*C.serverLocations)(C.malloc(C.size_t(unsafe.Sizeof(C.servers{})))) - returnedStruct.total_locations, returnedStruct.locations = getCPtrListStrings(locations) - return returnedStruct - } - return nil -} - -func getTransitionProfiles(data interface{}) *C.serverProfiles { - if profiles, ok := data.(*server.ProfileInfo); ok { - return getCPtrProfiles(profiles) - } - return nil -} - -func getTransitionServer(state *client.Client, data interface{}) *C.server { - if server, ok := data.(server.Server); ok { - base, baseErr := server.Base() - if baseErr != nil { - // TODO: LOG - return nil - } - return getCPtrServer(state, base) - } - return nil -} |
