Skip to content

Commit a2fd56b

Browse files
committed
fix: nil pointer when sonyflake is not properly configured
1 parent 828e0c9 commit a2fd56b

File tree

3 files changed

+61
-10
lines changed

3 files changed

+61
-10
lines changed

internal/server/server.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/jsiebens/ionscale/internal/service"
1818
"github.com/jsiebens/ionscale/internal/stunserver"
1919
"github.com/jsiebens/ionscale/internal/templates"
20+
"github.com/jsiebens/ionscale/internal/util"
2021
"github.com/labstack/echo-contrib/echoprometheus"
2122
"github.com/labstack/echo-contrib/pprof"
2223
"github.com/labstack/echo/v4"
@@ -53,6 +54,8 @@ func Start(ctx context.Context, c *config.Config) error {
5354
return err
5455
}
5556

57+
util.EnsureIDProvider()
58+
5659
derpMap, err := derp.LoadDERPSources(c)
5760
if err != nil {
5861
logger.Warn("not all derp sources are read successfully", zap.Error(err))

internal/util/id.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package util
22

33
import (
4+
"errors"
45
"fmt"
56
"github.com/sony/sonyflake"
7+
"go.uber.org/zap"
68
"net"
79
"os"
810
"strconv"
@@ -11,28 +13,64 @@ import (
1113
)
1214

1315
var (
14-
sf *sonyflake.Sonyflake
16+
sf provider
1517
sfOnce sync.Once
1618
)
1719

1820
func NextID() uint64 {
19-
ensureProvider()
20-
id, _ := sf.NextID()
21+
EnsureIDProvider()
22+
id, err := sf.NextID()
23+
if err != nil {
24+
panic(err)
25+
}
2126
return id
2227
}
2328

24-
func ensureProvider() {
29+
type provider interface {
30+
NextID() (uint64, error)
31+
}
32+
33+
type errorProvider struct {
34+
err error
35+
}
36+
37+
func (e errorProvider) NextID() (uint64, error) {
38+
return 0, fmt.Errorf("unable to generate ID, sonyflake not configured properly: %w", e.err)
39+
}
40+
41+
func EnsureIDProvider() {
2542
sfOnce.Do(func() {
26-
sfInstance, err := sonyflake.New(sonyflake.Settings{
27-
MachineID: machineID(),
28-
StartTime: time.Date(2022, 05, 01, 00, 0, 0, 0, time.UTC),
43+
sf = createIDProvider()
44+
})
45+
}
46+
47+
func createIDProvider() provider {
48+
startTime := time.Date(2022, 05, 01, 00, 0, 0, 0, time.UTC)
49+
50+
sfInstance, err := sonyflake.New(sonyflake.Settings{
51+
MachineID: machineID(),
52+
StartTime: startTime,
53+
})
54+
55+
if err != nil && errors.Is(err, sonyflake.ErrNoPrivateAddress) {
56+
id := RandUint16()
57+
zap.L().Warn("failed to generate sonyflake machine id from private ip address, using a random machine id", zap.Uint16("id", id))
58+
59+
sfInstance, err = sonyflake.New(sonyflake.Settings{
60+
MachineID: func() (uint16, error) { return id, nil },
61+
StartTime: startTime,
2962
})
63+
3064
if err != nil {
31-
panic("unable to initialize sonyflake: " + err.Error())
65+
return errorProvider{err}
3266
}
67+
}
3368

34-
sf = sfInstance
35-
})
69+
if err != nil {
70+
return errorProvider{err}
71+
}
72+
73+
return sfInstance
3674
}
3775

3876
func machineID() func() (uint16, error) {

internal/util/util.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/md5"
55
"crypto/rand"
66
"crypto/rsa"
7+
"encoding/binary"
78
"encoding/hex"
89
"encoding/json"
910
"math/big"
@@ -31,6 +32,15 @@ func RandUint64(n uint64) uint64 {
3132
return val.Uint64()
3233
}
3334

35+
func RandUint16() uint16 {
36+
var randomBytes [2]byte
37+
_, err := rand.Read(randomBytes[:])
38+
if err != nil {
39+
panic(err)
40+
}
41+
return binary.BigEndian.Uint16(randomBytes[:])
42+
}
43+
3444
func RandomBytes(size int) ([]byte, error) {
3545
buf := make([]byte, size)
3646
if _, err := rand.Read(buf); err != nil {

0 commit comments

Comments
 (0)