Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compression, fixes, wording changes #18

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pkg/rest/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ func (c *Context) vpnSetupHandler(w http.ResponseWriter, r *http.Request) {
c.returnError(w, fmt.Errorf("could write vpn config: %s", err), http.StatusBadRequest)
return
}
err = wireguard.ReloadVPNServerConfig()
if err != nil {
c.returnError(w, fmt.Errorf("unable to reload server config: %s", err), http.StatusBadRequest)
return
}
}
if rewriteClientConfigs {
// rewrite client configs
Expand Down
46 changes: 41 additions & 5 deletions pkg/rest/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package rest
import (
"bufio"
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io"
"math"
"net/http"
"path"
Expand Down Expand Up @@ -282,13 +284,19 @@ func (c *Context) packetLogsHandler(w http.ResponseWriter, r *http.Request) {
Data: []LogRow{},
}
// logs
statsFiles := []string{
path.Join(wireguard.VPN_STATS_DIR, wireguard.VPN_PACKETLOGGER_DIR, userID+"-"+date.Format("2006-01-02")+".log"),
statsFiles := []string{}
if offset > 0 {
statsFiles = append(statsFiles, path.Join(wireguard.VPN_STATS_DIR, wireguard.VPN_PACKETLOGGER_DIR, userID+"-"+date.AddDate(0, 0, -1).Format("2006-01-02")+".log"))
}
statsFiles = append(statsFiles, path.Join(wireguard.VPN_STATS_DIR, wireguard.VPN_PACKETLOGGER_DIR, userID+"-"+date.Format("2006-01-02")+".log"))
if !dateutils.DateEqual(time.Now(), date) { // date is in local timezone, and we are UTC, so also read next file
statsFiles = append(statsFiles, path.Join(wireguard.VPN_STATS_DIR, wireguard.VPN_PACKETLOGGER_DIR, userID+"-"+date.AddDate(0, 0, 1).Format("2006-01-02")+".log"))
}
statsFiles = filterNonExistentFiles(c.Storage.Client, statsFiles)
statsFiles, err = getCompressedFilesAndRemoveNonExistent(c.Storage.Client, statsFiles)
if err != nil {
c.returnError(w, fmt.Errorf("unable to get files for reading: %s", err), http.StatusBadRequest)
return
}
fileReaders, err := c.Storage.Client.OpenFilesFromPos(statsFiles, pos)
if err != nil {
c.returnError(w, fmt.Errorf("error while reading files: %s", err), http.StatusBadRequest)
Expand Down Expand Up @@ -353,14 +361,42 @@ func (c *Context) packetLogsHandler(w http.ResponseWriter, r *http.Request) {
c.write(w, out)
}

func filterNonExistentFiles(storage storage.Iface, files []string) []string {
func getCompressedFilesAndRemoveNonExistent(storage storage.Iface, files []string) ([]string, error) {
res := []string{}
for _, file := range files {
tmpFile := path.Join(wireguard.VPN_PACKETLOGGER_TMP_DIR, path.Base(file))
if storage.FileExists(file) {
res = append(res, file)
} else if storage.FileExists(tmpFile) { // temporary file exists
res = append(res, tmpFile)
} else if storage.FileExists(file + ".gz") { // uncompress log file for random access
err := storage.EnsurePath(wireguard.VPN_PACKETLOGGER_TMP_DIR)
if err != nil {
return res, fmt.Errorf("ensure path error: %s", err)
}
compressedFile, err := storage.OpenFile(file + ".gz")
if err != nil {
return res, fmt.Errorf("unable to open compress filed (%s): %s", file+".gz", err)
}
gzipReader, err := gzip.NewReader(compressedFile)
if err != nil {
return res, fmt.Errorf("unable to open gzip reader (%s): %s", file+".gz", err)
}
fileWriter, err := storage.OpenFileForWriting(tmpFile)
if err != nil {
return res, fmt.Errorf("unable to open tmp file writer (%s): %s", tmpFile, err)
}
_, err = io.Copy(fileWriter, gzipReader)
if err != nil {
return res, fmt.Errorf("unable to uncompress to file (%s): %s", tmpFile, err)
}
fileWriter.Close()
gzipReader.Close()
compressedFile.Close()
res = append(res, tmpFile)
}
}
return res
return res, nil
}

func getColor(i int) string {
Expand Down
43 changes: 43 additions & 0 deletions pkg/rest/stats_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package rest

import (
"bytes"
"compress/gzip"
"encoding/json"
"io"
"net/http/httptest"
"path"
"strings"
Expand Down Expand Up @@ -78,3 +81,43 @@ func TestFilterLogRecord(t *testing.T) {
}
}
}

func TestGetCompressedFilesAndRemoveNonExistent(t *testing.T) {
now := time.Now()
storage := &memorystorage.MockMemoryStorage{}
testData := now.Format(wireguard.TIMESTAMP_FORMAT) + ",3df97301-5f73-407a-a26b-91829f1e7f48,1,12729136,24348520,2024-08-23T18:30:42\n"
files := []string{
path.Join(wireguard.VPN_STATS_DIR, wireguard.VPN_PACKETLOGGER_DIR, "1-2-3-4-"+now.AddDate(0, 0, -1).Format("2006-01-02")+".log"),
path.Join(wireguard.VPN_STATS_DIR, wireguard.VPN_PACKETLOGGER_DIR, "1-2-3-4-"+now.Format("2006-01-02")+".log"),
}
for k, file := range files {
if k != len(files)-1 { // only the last file is not compressed
fileWriter, err := storage.OpenFileForWriting(file + ".gz")
if err != nil {
t.Fatalf("open file for wring error: %s", err)
}
writer := gzip.NewWriter(fileWriter)
io.Copy(writer, bytes.NewReader([]byte(testData)))
writer.Close()
fileWriter.Close()
} else {
storage.WriteFile(file, []byte(testData))
}
}
outFiles, err := getCompressedFilesAndRemoveNonExistent(storage, files)
if err != nil {
t.Fatalf("get files error: %s", err)
}
if len(outFiles) != 2 {
t.Fatalf("expected 2 files, got: %d", len(outFiles))
}
for _, file := range outFiles {
body, err := storage.ReadFile(file)
if err != nil {
t.Fatalf("readfile error: %s", err)
}
if string(body) != string(testData) {
t.Fatalf("mismatch: got: %s vs expected: %s\n", string(body), string(testData))
}
}
}
1 change: 1 addition & 0 deletions pkg/storage/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Iface interface {
Rename(oldName, newName string) error
AppendFile(name string, data []byte) error
EnsurePermissions(name string, mode fs.FileMode) error
FileInfo(name string) (fs.FileInfo, error)
ReadWriter
Seeker
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/storage/local/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@ func (l *LocalStorage) Rename(oldName, newName string) error {
func (l *LocalStorage) EnsurePermissions(name string, mode fs.FileMode) error {
return os.Chmod(path.Join(l.path, name), mode)
}

func (l *LocalStorage) FileInfo(name string) (fs.FileInfo, error) {
return os.Stat(name)
}
34 changes: 34 additions & 0 deletions pkg/storage/memory/fileinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package memorystorage

import (
"io/fs"
"time"
)

type FileInfo struct {
NameOut string // base name of the file
SizeOut int64 // length in bytes for regular files; system-dependent for others
ModeOut fs.FileMode // file mode bits
ModTimeOut time.Time // modification time
IsDirOut bool // abbreviation for Mode().IsDir()
SysOut any // underlying data source (can return nil)
}

func (f FileInfo) Name() string {
return f.NameOut
}
func (f FileInfo) Size() int64 {
return f.SizeOut
}
func (f FileInfo) Mode() fs.FileMode {
return f.ModeOut
}
func (f FileInfo) ModTime() time.Time {
return f.ModTimeOut
}
func (f FileInfo) IsDir() bool {
return f.IsDirOut
}
func (f FileInfo) Sys() any {
return nil
}
19 changes: 9 additions & 10 deletions pkg/storage/memory/storage.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package memorystorage

import (
"bufio"
"bytes"
"fmt"
"io"
Expand All @@ -11,14 +10,6 @@ import (
"strings"
)

type MyWriteCloser struct {
*bufio.Writer
}

func (mwc *MyWriteCloser) Close() error {
return nil
}

type MockReadWriterData []byte

func (m *MockReadWriterData) Close() error {
Expand All @@ -30,7 +21,8 @@ func (m *MockReadWriterData) Write(p []byte) (nn int, err error) {
}

type MockMemoryStorage struct {
Data map[string]*MockReadWriterData
FileInfoData map[string]*FileInfo
Data map[string]*MockReadWriterData
}

func (m *MockMemoryStorage) ConfigPath(filename string) string {
Expand Down Expand Up @@ -160,3 +152,10 @@ func (m *MockMemoryStorage) OpenFileForAppending(name string) (io.WriteCloser, e
func (m *MockMemoryStorage) EnsurePermissions(name string, mode fs.FileMode) error {
return nil
}
func (m *MockMemoryStorage) FileInfo(name string) (fs.FileInfo, error) {
val, ok := m.FileInfoData[name]
if !ok {
return FileInfo{}, fmt.Errorf("couldn't get file info for: %s", name)
}
return val, nil
}
1 change: 1 addition & 0 deletions pkg/wireguard/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const IP_LIST_PATH = "config/iplist.json"
const VPN_CLIENTS_DIR = "clients"
const VPN_STATS_DIR = "stats"
const VPN_PACKETLOGGER_DIR = "packetlogs"
const VPN_PACKETLOGGER_TMP_DIR = "tmp"
const VPN_SERVER_SECRETS_PATH = "secrets"
const VPN_PRIVATE_KEY_FILENAME = "priv.key"
const PRESHARED_KEY_FILENAME = "preshared.key"
Expand Down
Loading
Loading