blob: e6b38d0282f9c4a5591298bdd6a976579f1e8fe5 [file] [log] [blame]
Sergiusz Bazanski1fad2e52019-08-01 20:16:27 +02001package model
2
3import (
4 "context"
5 "database/sql"
6 "fmt"
7 "net"
8 "time"
9)
10
11func (s *sqlModel) UpdateAllowedPrefixes(ctx context.Context, asn int64, prefixes []*AllowedPrefix) error {
12 tx := s.db.MustBeginTx(ctx, &sql.TxOptions{})
13 defer tx.Rollback()
14
15 timestamp := time.Now().UnixNano()
16
17 for _, prefix := range prefixes {
18 q := `
19 INSERT INTO allowed_prefixes
20 (peer_id, timestamp, prefix, max_length, ta)
21 SELECT
22 peers.id, :timestamp, :prefix, :max_length, :ta
23 FROM peers
24 WHERE peers.asn = :asn
25 ON CONFLICT (peer_id, prefix)
26 DO UPDATE SET
27 timestamp = :timestamp,
28 max_length = :max_length,
29 ta = :ta
30 `
31 ap := sqlAllowedPrefix{
32 Timestamp: timestamp,
33 Prefix: prefix.Prefix.String(),
34 MaxLength: prefix.MaxLength,
35 TA: prefix.TA,
36 ASN: fmt.Sprintf("%d", asn),
37 }
38
39 if _, err := tx.NamedExecContext(ctx, q, ap); err != nil {
40 return fmt.Errorf("INSERT allowed_prefixes: %v", err)
41 }
42 }
43
44 q := `
45 DELETE FROM allowed_prefixes
46 WHERE timestamp != $1
47 AND peer_id = (SELECT peers.id FROM peers WHERE peers.asn = $2)
48 `
49 if _, err := tx.ExecContext(ctx, q, timestamp, asn); err != nil {
50 return fmt.Errorf("DELETE FROM allowed_prefixes: %v", err)
51 }
52
53 return tx.Commit()
54}
55
56func (s *sqlModel) GetAllowedPrefixes(ctx context.Context, asn int64) ([]*AllowedPrefix, error) {
57 q := `
58 SELECT
59 allowed_prefixes.prefix,
60 allowed_prefixes.max_length,
61 allowed_prefixes.ta
62 FROM
63 allowed_prefixes
64 LEFT JOIN peers
65 ON peers.id = allowed_prefixes.peer_id
66 WHERE peers.asn = $1
67 `
68 data := []sqlAllowedPrefix{}
69 if err := s.db.SelectContext(ctx, &data, q, asn); err != nil {
70 return nil, fmt.Errorf("SELECT allowed_prefixes: %v", err)
71 }
72
73 res := make([]*AllowedPrefix, len(data))
74 for i, d := range data {
75 _, prefix, err := net.ParseCIDR(d.Prefix)
76 if err != nil {
77 return nil, fmt.Errorf("corrupted CIDR in database: %v", err)
78 }
79 res[i] = &AllowedPrefix{
80 Prefix: *prefix,
81 MaxLength: d.MaxLength,
82 TA: d.TA,
83 }
84 }
85
86 return res, nil
87}