diff options
Diffstat (limited to 'server/rpki.go')
-rw-r--r-- | server/rpki.go | 137 |
1 files changed, 99 insertions, 38 deletions
diff --git a/server/rpki.go b/server/rpki.go index 53a56e04..dc8a94cc 100644 --- a/server/rpki.go +++ b/server/rpki.go @@ -19,12 +19,14 @@ import ( "bufio" "bytes" "fmt" + log "github.com/Sirupsen/logrus" "github.com/armon/go-radix" "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet" "github.com/osrg/gobgp/table" "net" + "time" ) type roa struct { @@ -48,12 +50,12 @@ func (r *roa) toApiStruct() *api.ROA { } type roaClient struct { - url string roas map[bgp.RouteFamily]*radix.Tree - outgoing chan *roa + outgoing chan []byte + config config.RpkiServers } -func (c *roaClient) recieveROA() chan *roa { +func (c *roaClient) recieveROA() chan []byte { return c.outgoing } @@ -65,33 +67,91 @@ func roa2key(r *roa) string { return buffer.String()[:r.PrefixLen] } -func (c *roaClient) handleRTRMsg(r *roa) { - if r.Prefix.To4() != nil { - c.roas[bgp.RF_IPv4_UC].Insert(roa2key(r), r) +func (c *roaClient) handleRTRMsg(buf []byte) { + received := &c.config.RpkiServerList[0].RpkiServerState.RpkiMessages.RpkiReceived + + m, _ := bgp.ParseRTR(buf) + if m != nil { + switch msg := m.(type) { + case *bgp.RTRSerialNotify: + received.SerialNotify++ + case *bgp.RTRSerialQuery: + case *bgp.RTRResetQuery: + case *bgp.RTRCacheResponse: + received.CacheResponse++ + case *bgp.RTRIPPrefix: + p := make([]byte, len(msg.Prefix)) + copy(p, msg.Prefix) + r := &roa{ + AS: msg.AS, + PrefixLen: msg.PrefixLen, + MaxLen: msg.MaxLen, + Prefix: p, + } + if r.Prefix.To4() != nil { + received.Ipv4Prefix++ + c.roas[bgp.RF_IPv4_UC].Insert(roa2key(r), r) + } else { + received.Ipv6Prefix++ + c.roas[bgp.RF_IPv6_UC].Insert(roa2key(r), r) + } + case *bgp.RTREndOfData: + received.EndOfData++ + case *bgp.RTRCacheReset: + received.CacheReset++ + case *bgp.RTRErrorReport: + } } else { - c.roas[bgp.RF_IPv6_UC].Insert(roa2key(r), r) + received.Error++ } } func (c *roaClient) handleGRPC(grpcReq *GrpcRequest) { - if tree, ok := c.roas[grpcReq.RouteFamily]; ok { + switch grpcReq.RequestType { + case REQ_RPKI: results := make([]*GrpcResponse, 0) - tree.Walk(func(s string, v interface{}) bool { - r, _ := v.(*roa) + for _, s := range c.config.RpkiServerList { + state := &s.RpkiServerState + rpki := &api.RPKI{ + Conf: &api.RPKIConf{ + Address: s.RpkiServerConfig.Address.String(), + }, + State: &api.RPKIState{ + Uptime: state.Uptime, + ReceivedIpv4: int32(c.roas[bgp.RF_IPv4_UC].Len()), + ReceivedIpv6: int32(c.roas[bgp.RF_IPv6_UC].Len()), + }, + } result := &GrpcResponse{} - result.Data = r.toApiStruct() + result.Data = rpki results = append(results, result) - return false - }) + } go sendMultipleResponses(grpcReq, results) + + case REQ_ROA: + if len(c.config.RpkiServerList) == 0 || c.config.RpkiServerList[0].RpkiServerConfig.Address.String() != grpcReq.Name { + result := &GrpcResponse{} + result.ResponseErr = fmt.Errorf("RPKI server that has %v doesn't exist.", grpcReq.Name) + + grpcReq.ResponseCh <- result + break + } + + if tree, ok := c.roas[grpcReq.RouteFamily]; ok { + results := make([]*GrpcResponse, 0) + tree.Walk(func(s string, v interface{}) bool { + r, _ := v.(*roa) + result := &GrpcResponse{} + result.Data = r.toApiStruct() + results = append(results, result) + return false + }) + go sendMultipleResponses(grpcReq, results) + } } } func (c *roaClient) validate(pathList []*table.Path) { - if c.url == "" { - return - } - for _, path := range pathList { if tree, ok := c.roas[path.GetRouteFamily()]; ok { _, n, _ := net.ParseCIDR(path.GetNlri().String()) @@ -115,16 +175,28 @@ func (c *roaClient) validate(pathList []*table.Path) { } } -func newROAClient(url string) (*roaClient, error) { +func newROAClient(conf config.RpkiServers) (*roaClient, error) { + var url string + c := &roaClient{ - url: url, - roas: make(map[bgp.RouteFamily]*radix.Tree), + roas: make(map[bgp.RouteFamily]*radix.Tree), + config: conf, } c.roas[bgp.RF_IPv4_UC] = radix.New() c.roas[bgp.RF_IPv6_UC] = radix.New() - if url == "" { + if len(conf.RpkiServerList) == 0 { return c, nil + } else { + if len(conf.RpkiServerList) > 1 { + log.Warn("currently only one RPKI server is supposed") + } + if conf.RpkiServerList[0].RpkiServerConfig.Address.To16() == nil { + url = fmt.Sprintf("%s", conf.RpkiServerList[0].RpkiServerConfig.Address) + } else { + url = fmt.Sprintf("[%s]", conf.RpkiServerList[0].RpkiServerConfig.Address) + } + url += fmt.Sprintf(":%d", conf.RpkiServerList[0].RpkiServerConfig.Port) } conn, err := net.Dial("tcp", url) @@ -132,33 +204,22 @@ func newROAClient(url string) (*roaClient, error) { return c, err } + state := &conf.RpkiServerList[0].RpkiServerState + state.Uptime = time.Now().Unix() r := bgp.NewRTRResetQuery() data, _ := r.Serialize() conn.Write(data) + state.RpkiMessages.RpkiSent.ResetQuery++ reader := bufio.NewReader(conn) scanner := bufio.NewScanner(reader) scanner.Split(bgp.SplitRTR) - ch := make(chan *roa) + ch := make(chan []byte) c.outgoing = ch - go func(ch chan *roa) { + go func(ch chan []byte) { for scanner.Scan() { - m, _ := bgp.ParseRTR(scanner.Bytes()) - if m != nil { - switch msg := m.(type) { - case *bgp.RTRIPPrefix: - p := make([]byte, len(msg.Prefix)) - copy(p, msg.Prefix) - ch <- &roa{ - AS: msg.AS, - PrefixLen: msg.PrefixLen, - MaxLen: msg.MaxLen, - Prefix: p, - } - } - - } + ch <- scanner.Bytes() } }(ch) |