2024-06-29 00:23:55 -04:00
|
|
|
package reseed
|
|
|
|
|
|
|
|
import (
|
2024-06-30 23:14:48 -04:00
|
|
|
"io"
|
2024-06-29 00:23:55 -04:00
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2024-06-29 00:36:11 -04:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2024-06-29 00:23:55 -04:00
|
|
|
|
2024-11-21 17:16:48 -05:00
|
|
|
"github.com/go-i2p/logger"
|
2025-02-26 19:22:48 -05:00
|
|
|
"github.com/samber/oops"
|
2024-10-22 17:37:17 -04:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
|
2024-06-29 00:23:55 -04:00
|
|
|
"github.com/eyedeekay/go-unzip/pkg/unzip"
|
|
|
|
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
|
|
|
"github.com/go-i2p/go-i2p/lib/config"
|
|
|
|
"github.com/go-i2p/go-i2p/lib/su3"
|
|
|
|
)
|
|
|
|
|
2024-10-23 00:06:06 -04:00
|
|
|
var log = logger.GetGoI2PLogger()
|
2024-10-18 22:54:08 -04:00
|
|
|
|
2024-06-29 00:23:55 -04:00
|
|
|
const (
|
2024-06-30 23:14:48 -04:00
|
|
|
I2pUserAgent = "Wget/1.11.4"
|
2024-06-29 00:23:55 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
type Reseed struct {
|
|
|
|
net.Dialer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r Reseed) SingleReseed(uri string) ([]router_info.RouterInfo, error) {
|
2024-10-18 22:54:08 -04:00
|
|
|
log.WithField("uri", uri).Debug("Starting single reseed operation")
|
|
|
|
|
2024-06-30 23:14:48 -04:00
|
|
|
transport := http.Transport{
|
2024-06-29 00:23:55 -04:00
|
|
|
DialContext: r.DialContext,
|
|
|
|
}
|
2024-06-30 23:14:48 -04:00
|
|
|
client := http.Client{
|
2024-06-29 00:23:55 -04:00
|
|
|
Transport: &transport,
|
|
|
|
}
|
|
|
|
URL, err := url.Parse(uri)
|
|
|
|
if err != nil {
|
2024-10-18 22:54:08 -04:00
|
|
|
log.WithError(err).Error("Failed to parse reseed URI")
|
2024-06-29 00:23:55 -04:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
header := http.Header{}
|
|
|
|
header.Add("user-agent", "Wget/1.11.4")
|
2024-06-30 23:14:48 -04:00
|
|
|
request := http.Request{
|
|
|
|
URL: URL,
|
2024-06-29 00:23:55 -04:00
|
|
|
Header: header,
|
|
|
|
}
|
|
|
|
response, err := client.Do(&request)
|
|
|
|
if err != nil {
|
2024-10-18 22:54:08 -04:00
|
|
|
log.WithError(err).Error("Failed to perform HTTP request")
|
2024-06-29 00:23:55 -04:00
|
|
|
return nil, err
|
|
|
|
}
|
2024-10-18 22:54:08 -04:00
|
|
|
|
|
|
|
log.Debug("Successfully received response from reseed server")
|
|
|
|
|
2024-06-29 00:23:55 -04:00
|
|
|
su3file, err := su3.Read(response.Body)
|
|
|
|
if err != nil {
|
2024-10-18 22:54:08 -04:00
|
|
|
log.WithError(err).Error("Failed to read SU3 file")
|
2024-06-29 00:23:55 -04:00
|
|
|
return nil, err
|
|
|
|
}
|
2024-10-18 22:54:08 -04:00
|
|
|
|
|
|
|
log.WithFields(logrus.Fields{
|
|
|
|
"file_type": su3file.FileType,
|
|
|
|
"content_type": su3file.ContentType,
|
|
|
|
}).Debug("Successfully read SU3 file")
|
|
|
|
|
2024-06-29 00:23:55 -04:00
|
|
|
if su3file.FileType == su3.ZIP {
|
|
|
|
if su3file.ContentType == su3.RESEED {
|
2024-11-03 01:52:48 -05:00
|
|
|
content, err := io.ReadAll(su3file.Content(""))
|
2024-06-29 00:23:55 -04:00
|
|
|
if err == nil {
|
2024-11-03 01:52:48 -05:00
|
|
|
signature, err := io.ReadAll(su3file.Signature())
|
2024-06-29 00:36:11 -04:00
|
|
|
if err != nil {
|
2024-11-03 01:52:48 -05:00
|
|
|
log.WithError(err).Error("Failed to read SU3 file signature")
|
2024-06-29 00:36:11 -04:00
|
|
|
return nil, err
|
|
|
|
}
|
2024-11-03 01:52:48 -05:00
|
|
|
log.Println("warning: this doesn't validate the signature yet", signature)
|
|
|
|
log.Warn("Doesn't validate the signature yet", logrus.Fields{"signature": signature})
|
|
|
|
}
|
|
|
|
zip := filepath.Join(config.RouterConfigProperties.NetDb.Path, "reseed.zip")
|
|
|
|
err = os.WriteFile(zip, content, 0o644)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("Failed to write reseed zip file")
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// content is a zip file, unzip it and get the files
|
|
|
|
files, err := unzip.New().Extract(zip, config.RouterConfigProperties.NetDb.Path)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("Failed to extract reseed zip file")
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if len(files) <= 0 {
|
|
|
|
log.Error("Reseed appears to have no content")
|
2025-02-26 19:22:48 -05:00
|
|
|
return nil, oops.Errorf("error: reseed appears to have no content")
|
2024-11-03 01:52:48 -05:00
|
|
|
}
|
2024-10-18 22:54:08 -04:00
|
|
|
|
2024-11-03 01:52:48 -05:00
|
|
|
log.WithField("file_count", len(files)).Debug("Successfully extracted reseed files")
|
2024-10-18 22:54:08 -04:00
|
|
|
|
2024-11-03 01:52:48 -05:00
|
|
|
var ris []router_info.RouterInfo
|
|
|
|
for _, f := range files {
|
|
|
|
riB, err := os.ReadFile(f)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).WithField("file", f).Warn("Failed to read router info file")
|
|
|
|
continue
|
2024-06-29 00:36:11 -04:00
|
|
|
}
|
2024-11-03 01:52:48 -05:00
|
|
|
ri, _, err := router_info.ReadRouterInfo(riB)
|
2024-10-18 22:54:08 -04:00
|
|
|
if err != nil {
|
2024-11-03 01:52:48 -05:00
|
|
|
log.WithError(err).WithField("file", f).Warn("Failed to parse router info")
|
|
|
|
continue
|
2024-10-18 22:54:08 -04:00
|
|
|
}
|
2024-11-03 01:52:48 -05:00
|
|
|
ris = append(ris, ri)
|
|
|
|
}
|
|
|
|
err = os.Remove(zip)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Warn("Failed to remove reseed zip file")
|
2024-06-29 00:23:55 -04:00
|
|
|
}
|
2024-11-03 01:52:48 -05:00
|
|
|
log.WithField("router_info_count", len(ris)).Debug("Successfully processed reseed data")
|
|
|
|
return ris, err
|
2024-06-30 23:14:48 -04:00
|
|
|
}
|
2024-06-29 00:23:55 -04:00
|
|
|
}
|
2024-10-18 22:54:08 -04:00
|
|
|
log.Error("Undefined reseed error")
|
2025-02-26 19:22:48 -05:00
|
|
|
return nil, oops.Errorf("error: undefined reseed error")
|
2024-06-29 00:23:55 -04:00
|
|
|
}
|