Update github.com/google/safebrowsing and block on database health (#2837)
Update github.com/google/safebrowsing and block on database health before starting VA before starting `boulder-va`. ``` $ go test . ok github.com/google/safebrowsing 4.510s $ go test . ok github.com/golang/protobuf/ptypes 0.002s ``` Fixes #2742.
This commit is contained in:
		
							parent
							
								
									71f8ae0e87
								
							
						
					
					
						commit
						f5bc9e892a
					
				| 
						 | 
					@ -114,6 +114,10 @@
 | 
				
			||||||
			"ImportPath": "github.com/golang/protobuf/proto",
 | 
								"ImportPath": "github.com/golang/protobuf/proto",
 | 
				
			||||||
			"Rev": "c9c7427a2a70d2eb3bafa0ab2dc163e45f143317"
 | 
								"Rev": "c9c7427a2a70d2eb3bafa0ab2dc163e45f143317"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "github.com/golang/protobuf/ptypes/duration",
 | 
				
			||||||
 | 
								"Rev": "c9c7427a2a70d2eb3bafa0ab2dc163e45f143317"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/google/certificate-transparency-go",
 | 
								"ImportPath": "github.com/google/certificate-transparency-go",
 | 
				
			||||||
			"Rev": "0dac42a6ed448ba220ee315abfaa6d26fd5fc9bb"
 | 
								"Rev": "0dac42a6ed448ba220ee315abfaa6d26fd5fc9bb"
 | 
				
			||||||
| 
						 | 
					@ -144,11 +148,11 @@
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/google/safebrowsing",
 | 
								"ImportPath": "github.com/google/safebrowsing",
 | 
				
			||||||
			"Rev": "fc74adc270b82ff5a2f288fa84e40213eae713c5"
 | 
								"Rev": "a8c029efb52bae66853e05241150ab338e98fbc7"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/google/safebrowsing/internal/safebrowsing_proto",
 | 
								"ImportPath": "github.com/google/safebrowsing/internal/safebrowsing_proto",
 | 
				
			||||||
			"Rev": "fc74adc270b82ff5a2f288fa84e40213eae713c5"
 | 
								"Rev": "a8c029efb52bae66853e05241150ab338e98fbc7"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
 | 
								"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,11 @@
 | 
				
			||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	safebrowsingv4 "github.com/google/safebrowsing"
 | 
						safebrowsingv4 "github.com/google/safebrowsing"
 | 
				
			||||||
	"github.com/letsencrypt/boulder/cmd"
 | 
						"github.com/letsencrypt/boulder/cmd"
 | 
				
			||||||
| 
						 | 
					@ -119,6 +121,12 @@ func newGoogleSafeBrowsingV4(gsb *cmd.GoogleSafeBrowsingConfig, logger blog.Logg
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ctx, cancel := context.WithTimeout(context.Background(), time.Second*60)
 | 
				
			||||||
 | 
						defer cancel() // avoid leak
 | 
				
			||||||
 | 
						err = sb.WaitUntilReady(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return gsbAdapter{sb}, nil
 | 
						return gsbAdapter{sb}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,114 @@
 | 
				
			||||||
 | 
					// Code generated by protoc-gen-go.
 | 
				
			||||||
 | 
					// source: github.com/golang/protobuf/ptypes/duration/duration.proto
 | 
				
			||||||
 | 
					// DO NOT EDIT!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Package duration is a generated protocol buffer package.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is generated from these files:
 | 
				
			||||||
 | 
						github.com/golang/protobuf/ptypes/duration/duration.proto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It has these top-level messages:
 | 
				
			||||||
 | 
						Duration
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					package duration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import proto "github.com/golang/protobuf/proto"
 | 
				
			||||||
 | 
					import fmt "fmt"
 | 
				
			||||||
 | 
					import math "math"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
 | 
					var _ = proto.Marshal
 | 
				
			||||||
 | 
					var _ = fmt.Errorf
 | 
				
			||||||
 | 
					var _ = math.Inf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is a compile-time assertion to ensure that this generated file
 | 
				
			||||||
 | 
					// is compatible with the proto package it is being compiled against.
 | 
				
			||||||
 | 
					// A compilation error at this line likely means your copy of the
 | 
				
			||||||
 | 
					// proto package needs to be updated.
 | 
				
			||||||
 | 
					const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Duration represents a signed, fixed-length span of time represented
 | 
				
			||||||
 | 
					// as a count of seconds and fractions of seconds at nanosecond
 | 
				
			||||||
 | 
					// resolution. It is independent of any calendar and concepts like "day"
 | 
				
			||||||
 | 
					// or "month". It is related to Timestamp in that the difference between
 | 
				
			||||||
 | 
					// two Timestamp values is a Duration and it can be added or subtracted
 | 
				
			||||||
 | 
					// from a Timestamp. Range is approximately +-10,000 years.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example 1: Compute Duration from two Timestamps in pseudo code.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     Timestamp start = ...;
 | 
				
			||||||
 | 
					//     Timestamp end = ...;
 | 
				
			||||||
 | 
					//     Duration duration = ...;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     duration.seconds = end.seconds - start.seconds;
 | 
				
			||||||
 | 
					//     duration.nanos = end.nanos - start.nanos;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     if (duration.seconds < 0 && duration.nanos > 0) {
 | 
				
			||||||
 | 
					//       duration.seconds += 1;
 | 
				
			||||||
 | 
					//       duration.nanos -= 1000000000;
 | 
				
			||||||
 | 
					//     } else if (durations.seconds > 0 && duration.nanos < 0) {
 | 
				
			||||||
 | 
					//       duration.seconds -= 1;
 | 
				
			||||||
 | 
					//       duration.nanos += 1000000000;
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     Timestamp start = ...;
 | 
				
			||||||
 | 
					//     Duration duration = ...;
 | 
				
			||||||
 | 
					//     Timestamp end = ...;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     end.seconds = start.seconds + duration.seconds;
 | 
				
			||||||
 | 
					//     end.nanos = start.nanos + duration.nanos;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     if (end.nanos < 0) {
 | 
				
			||||||
 | 
					//       end.seconds -= 1;
 | 
				
			||||||
 | 
					//       end.nanos += 1000000000;
 | 
				
			||||||
 | 
					//     } else if (end.nanos >= 1000000000) {
 | 
				
			||||||
 | 
					//       end.seconds += 1;
 | 
				
			||||||
 | 
					//       end.nanos -= 1000000000;
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					type Duration struct {
 | 
				
			||||||
 | 
						// Signed seconds of the span of time. Must be from -315,576,000,000
 | 
				
			||||||
 | 
						// to +315,576,000,000 inclusive.
 | 
				
			||||||
 | 
						Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
 | 
				
			||||||
 | 
						// Signed fractions of a second at nanosecond resolution of the span
 | 
				
			||||||
 | 
						// of time. Durations less than one second are represented with a 0
 | 
				
			||||||
 | 
						// `seconds` field and a positive or negative `nanos` field. For durations
 | 
				
			||||||
 | 
						// of one second or more, a non-zero value for the `nanos` field must be
 | 
				
			||||||
 | 
						// of the same sign as the `seconds` field. Must be from -999,999,999
 | 
				
			||||||
 | 
						// to +999,999,999 inclusive.
 | 
				
			||||||
 | 
						Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Duration) Reset()                    { *m = Duration{} }
 | 
				
			||||||
 | 
					func (m *Duration) String() string            { return proto.CompactTextString(m) }
 | 
				
			||||||
 | 
					func (*Duration) ProtoMessage()               {}
 | 
				
			||||||
 | 
					func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 | 
				
			||||||
 | 
					func (*Duration) XXX_WellKnownType() string   { return "Duration" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						proto.RegisterFile("github.com/golang/protobuf/ptypes/duration/duration.proto", fileDescriptor0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var fileDescriptor0 = []byte{
 | 
				
			||||||
 | 
						// 189 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x4c, 0xcf, 0x2c, 0xc9,
 | 
				
			||||||
 | 
						0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
 | 
				
			||||||
 | 
						0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0x29,
 | 
				
			||||||
 | 
						0x2d, 0x4a, 0x2c, 0xc9, 0xcc, 0xcf, 0x83, 0x33, 0xf4, 0xc0, 0x2a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3,
 | 
				
			||||||
 | 
						0xd3, 0x73, 0x52, 0xf5, 0x60, 0xea, 0x95, 0xac, 0xb8, 0x38, 0x5c, 0xa0, 0x4a, 0x84, 0x24, 0xb8,
 | 
				
			||||||
 | 
						0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60,
 | 
				
			||||||
 | 
						0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d, 0xd6,
 | 
				
			||||||
 | 
						0x20, 0x08, 0xc7, 0xa9, 0x86, 0x4b, 0x38, 0x39, 0x3f, 0x57, 0x0f, 0xcd, 0x48, 0x27, 0x5e, 0x98,
 | 
				
			||||||
 | 
						0x81, 0x01, 0x20, 0x91, 0x00, 0xc6, 0x28, 0x2d, 0xe2, 0xdd, 0xbb, 0x80, 0x91, 0x71, 0x11, 0x13,
 | 
				
			||||||
 | 
						0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xb9, 0x01, 0x50, 0xa5, 0x7a, 0xe1, 0xa9,
 | 
				
			||||||
 | 
						0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x2d, 0x49, 0x6c, 0x60, 0x33, 0x8c, 0x01,
 | 
				
			||||||
 | 
						0x01, 0x00, 0x00, 0xff, 0xff, 0x62, 0xfb, 0xb1, 0x51, 0x0e, 0x01, 0x00, 0x00,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					// Protocol Buffers - Google's data interchange format
 | 
				
			||||||
 | 
					// Copyright 2008 Google Inc.  All rights reserved.
 | 
				
			||||||
 | 
					// https://developers.google.com/protocol-buffers/
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					// modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					// met:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					// notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					//     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					// copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					// in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					// distribution.
 | 
				
			||||||
 | 
					//     * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					// contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					// this software without specific prior written permission.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					syntax = "proto3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package google.protobuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 | 
				
			||||||
 | 
					option go_package = "github.com/golang/protobuf/ptypes/duration";
 | 
				
			||||||
 | 
					option java_package = "com.google.protobuf";
 | 
				
			||||||
 | 
					option java_outer_classname = "DurationProto";
 | 
				
			||||||
 | 
					option java_multiple_files = true;
 | 
				
			||||||
 | 
					option java_generate_equals_and_hash = true;
 | 
				
			||||||
 | 
					option objc_class_prefix = "GPB";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Duration represents a signed, fixed-length span of time represented
 | 
				
			||||||
 | 
					// as a count of seconds and fractions of seconds at nanosecond
 | 
				
			||||||
 | 
					// resolution. It is independent of any calendar and concepts like "day"
 | 
				
			||||||
 | 
					// or "month". It is related to Timestamp in that the difference between
 | 
				
			||||||
 | 
					// two Timestamp values is a Duration and it can be added or subtracted
 | 
				
			||||||
 | 
					// from a Timestamp. Range is approximately +-10,000 years.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example 1: Compute Duration from two Timestamps in pseudo code.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     Timestamp start = ...;
 | 
				
			||||||
 | 
					//     Timestamp end = ...;
 | 
				
			||||||
 | 
					//     Duration duration = ...;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     duration.seconds = end.seconds - start.seconds;
 | 
				
			||||||
 | 
					//     duration.nanos = end.nanos - start.nanos;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     if (duration.seconds < 0 && duration.nanos > 0) {
 | 
				
			||||||
 | 
					//       duration.seconds += 1;
 | 
				
			||||||
 | 
					//       duration.nanos -= 1000000000;
 | 
				
			||||||
 | 
					//     } else if (durations.seconds > 0 && duration.nanos < 0) {
 | 
				
			||||||
 | 
					//       duration.seconds -= 1;
 | 
				
			||||||
 | 
					//       duration.nanos += 1000000000;
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     Timestamp start = ...;
 | 
				
			||||||
 | 
					//     Duration duration = ...;
 | 
				
			||||||
 | 
					//     Timestamp end = ...;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     end.seconds = start.seconds + duration.seconds;
 | 
				
			||||||
 | 
					//     end.nanos = start.nanos + duration.nanos;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     if (end.nanos < 0) {
 | 
				
			||||||
 | 
					//       end.seconds -= 1;
 | 
				
			||||||
 | 
					//       end.nanos += 1000000000;
 | 
				
			||||||
 | 
					//     } else if (end.nanos >= 1000000000) {
 | 
				
			||||||
 | 
					//       end.seconds += 1;
 | 
				
			||||||
 | 
					//       end.nanos -= 1000000000;
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					message Duration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Signed seconds of the span of time. Must be from -315,576,000,000
 | 
				
			||||||
 | 
					  // to +315,576,000,000 inclusive.
 | 
				
			||||||
 | 
					  int64 seconds = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Signed fractions of a second at nanosecond resolution of the span
 | 
				
			||||||
 | 
					  // of time. Durations less than one second are represented with a 0
 | 
				
			||||||
 | 
					  // `seconds` field and a positive or negative `nanos` field. For durations
 | 
				
			||||||
 | 
					  // of one second or more, a non-zero value for the `nanos` field must be
 | 
				
			||||||
 | 
					  // of the same sign as the `seconds` field. Must be from -999,999,999
 | 
				
			||||||
 | 
					  // to +999,999,999 inclusive.
 | 
				
			||||||
 | 
					  int32 nanos = 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
language: go
 | 
					language: go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go:
 | 
					go:
 | 
				
			||||||
  - 1.6
 | 
					 | 
				
			||||||
  - 1.7
 | 
					  - 1.7
 | 
				
			||||||
 | 
					  - 1.8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
script:
 | 
					script:
 | 
				
			||||||
  - test -z "$(gofmt -s -l $(find . -name '*.go' -type f -print) | tee /dev/stderr)"
 | 
					  - test -z "$(gofmt -s -l $(find . -name '*.go' -type f -print) | tee /dev/stderr)"
 | 
				
			||||||
  - go test -v ./...
 | 
					  - go test -v $(go list ./... | grep -v vendor)
 | 
				
			||||||
  - go test -race -v ./...
 | 
					  - go test -race -v $(go list ./... | grep -v vendor)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@ import (
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pb "github.com/google/safebrowsing/internal/safebrowsing_proto"
 | 
						pb "github.com/google/safebrowsing/internal/safebrowsing_proto"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,14 +41,14 @@ type api interface {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// netAPI is an api object that talks to the server over HTTP.
 | 
					// netAPI is an api object that talks to the server over HTTP.
 | 
				
			||||||
type netAPI struct {
 | 
					type netAPI struct {
 | 
				
			||||||
	client http.Client
 | 
						client *http.Client
 | 
				
			||||||
	url    *url.URL
 | 
						url    *url.URL
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newNetAPI creates a new netAPI object pointed at the provided root URL.
 | 
					// newNetAPI creates a new netAPI object pointed at the provided root URL.
 | 
				
			||||||
// For every request, it will use the provided API key.
 | 
					// For every request, it will use the provided API key.
 | 
				
			||||||
// If the protocol is not specified in root, then this defaults to using HTTPS.
 | 
					// If the protocol is not specified in root, then this defaults to using HTTPS.
 | 
				
			||||||
func newNetAPI(root string, key string) (*netAPI, error) {
 | 
					func newNetAPI(root string, key string, timeout time.Duration) (*netAPI, error) {
 | 
				
			||||||
	if !strings.Contains(root, "://") {
 | 
						if !strings.Contains(root, "://") {
 | 
				
			||||||
		root = "https://" + root
 | 
							root = "https://" + root
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -60,7 +61,7 @@ func newNetAPI(root string, key string) (*netAPI, error) {
 | 
				
			||||||
	q.Set("key", key)
 | 
						q.Set("key", key)
 | 
				
			||||||
	q.Set("alt", "proto")
 | 
						q.Set("alt", "proto")
 | 
				
			||||||
	u.RawQuery = q.Encode()
 | 
						u.RawQuery = q.Encode()
 | 
				
			||||||
	return &netAPI{url: u}, nil
 | 
						return &netAPI{url: u, client: &http.Client{Timeout: timeout}}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// doRequests performs a POST to requestPath. It uses the marshaled form of req
 | 
					// doRequests performs a POST to requestPath. It uses the marshaled form of req
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,12 @@ func (c *cache) Update(req *pb.FindFullHashesRequest, resp *pb.FindFullHashesRes
 | 
				
			||||||
		if c.pttls[fullHash] == nil {
 | 
							if c.pttls[fullHash] == nil {
 | 
				
			||||||
			c.pttls[fullHash] = make(map[ThreatDescriptor]time.Time)
 | 
								c.pttls[fullHash] = make(map[ThreatDescriptor]time.Time)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		dur := time.Duration(tm.GetCacheDuration().Seconds) * time.Second
 | 
							var dur time.Duration
 | 
				
			||||||
 | 
							if tmCacheDur := tm.GetCacheDuration(); tmCacheDur != nil {
 | 
				
			||||||
 | 
								dur = time.Duration(tm.GetCacheDuration().Seconds) * time.Second
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								dur = 0
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		td := ThreatDescriptor{
 | 
							td := ThreatDescriptor{
 | 
				
			||||||
			ThreatType:      ThreatType(tm.ThreatType),
 | 
								ThreatType:      ThreatType(tm.ThreatType),
 | 
				
			||||||
			PlatformType:    PlatformType(tm.PlatformType),
 | 
								PlatformType:    PlatformType(tm.PlatformType),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ import (
 | 
				
			||||||
	"encoding/gob"
 | 
						"encoding/gob"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
| 
						 | 
					@ -30,7 +31,11 @@ import (
 | 
				
			||||||
// jitter is the maximum amount of time that we expect an API list update to
 | 
					// jitter is the maximum amount of time that we expect an API list update to
 | 
				
			||||||
// actually take. We add this time to the update period time to give some
 | 
					// actually take. We add this time to the update period time to give some
 | 
				
			||||||
// leeway before declaring the database as stale.
 | 
					// leeway before declaring the database as stale.
 | 
				
			||||||
const jitter = 30 * time.Second
 | 
					const (
 | 
				
			||||||
 | 
						maxRetryDelay  = 24 * time.Hour
 | 
				
			||||||
 | 
						baseRetryDelay = 15 * time.Minute
 | 
				
			||||||
 | 
						jitter         = 30 * time.Second
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// database tracks the state of the threat lists published by the Safe Browsing
 | 
					// database tracks the state of the threat lists published by the Safe Browsing
 | 
				
			||||||
// API. Since the global blacklist is constantly changing, the contents of the
 | 
					// API. Since the global blacklist is constantly changing, the contents of the
 | 
				
			||||||
| 
						 | 
					@ -64,7 +69,9 @@ type database struct {
 | 
				
			||||||
	ml  sync.RWMutex // Protects tfl, err, and last
 | 
						ml  sync.RWMutex // Protects tfl, err, and last
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err             error         // Last error encountered
 | 
						err             error         // Last error encountered
 | 
				
			||||||
 | 
						readyCh         chan struct{} // Used for waiting until not in an error state.
 | 
				
			||||||
	last            time.Time     // Last time the threat list were synced
 | 
						last            time.Time     // Last time the threat list were synced
 | 
				
			||||||
 | 
						updateAPIErrors uint          // Number of times we attempted to contact the api and failed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log *log.Logger
 | 
						log *log.Logger
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -94,11 +101,14 @@ type databaseFormat struct {
 | 
				
			||||||
// Init initializes the database from the specified file in config.DBPath.
 | 
					// Init initializes the database from the specified file in config.DBPath.
 | 
				
			||||||
// It reports true if the database was successfully loaded.
 | 
					// It reports true if the database was successfully loaded.
 | 
				
			||||||
func (db *database) Init(config *Config, logger *log.Logger) bool {
 | 
					func (db *database) Init(config *Config, logger *log.Logger) bool {
 | 
				
			||||||
 | 
						db.mu.Lock()
 | 
				
			||||||
 | 
						defer db.mu.Unlock()
 | 
				
			||||||
 | 
						db.setError(errors.New("not intialized"))
 | 
				
			||||||
	db.config = config
 | 
						db.config = config
 | 
				
			||||||
	db.log = logger
 | 
						db.log = logger
 | 
				
			||||||
	if db.config.DBPath == "" {
 | 
						if db.config.DBPath == "" {
 | 
				
			||||||
		db.log.Printf("no database file specified")
 | 
							db.log.Printf("no database file specified")
 | 
				
			||||||
		db.setError(errStale)
 | 
							db.setError(errors.New("no database loaded"))
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dbf, err := loadDatabase(db.config.DBPath)
 | 
						dbf, err := loadDatabase(db.config.DBPath)
 | 
				
			||||||
| 
						 | 
					@ -112,7 +122,9 @@ func (db *database) Init(config *Config, logger *log.Logger) bool {
 | 
				
			||||||
	// superset of the specified configuration.
 | 
						// superset of the specified configuration.
 | 
				
			||||||
	if db.config.now().Sub(dbf.Time) > (db.config.UpdatePeriod + jitter) {
 | 
						if db.config.now().Sub(dbf.Time) > (db.config.UpdatePeriod + jitter) {
 | 
				
			||||||
		db.log.Printf("database loaded is stale")
 | 
							db.log.Printf("database loaded is stale")
 | 
				
			||||||
		db.setError(errStale)
 | 
							db.ml.Lock()
 | 
				
			||||||
 | 
							defer db.ml.Unlock()
 | 
				
			||||||
 | 
							db.setStale()
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tfuNew := make(threatsForUpdate)
 | 
						tfuNew := make(threatsForUpdate)
 | 
				
			||||||
| 
						 | 
					@ -120,8 +132,8 @@ func (db *database) Init(config *Config, logger *log.Logger) bool {
 | 
				
			||||||
		if row, ok := dbf.Table[td]; ok {
 | 
							if row, ok := dbf.Table[td]; ok {
 | 
				
			||||||
			tfuNew[td] = row
 | 
								tfuNew[td] = row
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			db.log.Printf("database configuration mismatch")
 | 
								db.log.Printf("database configuration mismatch, missing %v", td)
 | 
				
			||||||
			db.setError(errStale)
 | 
								db.setError(errors.New("database configuration mismatch"))
 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -140,15 +152,39 @@ func (db *database) Status() error {
 | 
				
			||||||
		return db.err
 | 
							return db.err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if db.config.now().Sub(db.last) > (db.config.UpdatePeriod + jitter) {
 | 
						if db.config.now().Sub(db.last) > (db.config.UpdatePeriod + jitter) {
 | 
				
			||||||
		return errStale
 | 
							db.setStale()
 | 
				
			||||||
 | 
							return db.err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateLag reports the amount of time in between when we expected to run
 | 
				
			||||||
 | 
					// a database update and the current time
 | 
				
			||||||
 | 
					func (db *database) UpdateLag() time.Duration {
 | 
				
			||||||
 | 
						lag := db.SinceLastUpdate()
 | 
				
			||||||
 | 
						if lag < db.config.UpdatePeriod {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return lag - db.config.UpdatePeriod
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SinceLastUpdate gives the duration since the last database update
 | 
				
			||||||
 | 
					func (db *database) SinceLastUpdate() time.Duration {
 | 
				
			||||||
 | 
						db.ml.RLock()
 | 
				
			||||||
 | 
						defer db.ml.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return db.config.now().Sub(db.last)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ready returns a channel that's closed when the database is ready for queries.
 | 
				
			||||||
 | 
					func (db *database) Ready() <-chan struct{} {
 | 
				
			||||||
 | 
						return db.readyCh
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Update synchronizes the local threat lists with those maintained by the
 | 
					// Update synchronizes the local threat lists with those maintained by the
 | 
				
			||||||
// global Safe Browsing API servers. If the update is successful, Status should
 | 
					// global Safe Browsing API servers. If the update is successful, Status should
 | 
				
			||||||
// report a nil error.
 | 
					// report a nil error.
 | 
				
			||||||
func (db *database) Update(api api) {
 | 
					func (db *database) Update(api api) (time.Duration, bool) {
 | 
				
			||||||
	db.mu.Lock()
 | 
						db.mu.Lock()
 | 
				
			||||||
	defer db.mu.Unlock()
 | 
						defer db.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,23 +219,42 @@ func (db *database) Update(api api) {
 | 
				
			||||||
	last := db.config.now()
 | 
						last := db.config.now()
 | 
				
			||||||
	resp, err := api.ListUpdate(req)
 | 
						resp, err := api.ListUpdate(req)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		db.log.Printf("ListUpdate failure: %v", err)
 | 
							db.log.Printf("ListUpdate failure (%d): %v", db.updateAPIErrors+1, err)
 | 
				
			||||||
		db.setError(err)
 | 
							db.setError(err)
 | 
				
			||||||
		return
 | 
							// backoff strategy: MIN((2**N-1 * 15 minutes) * (RAND + 1), 24 hours)
 | 
				
			||||||
 | 
							n := 1 << db.updateAPIErrors
 | 
				
			||||||
 | 
							delay := time.Duration(float64(n) * (rand.Float64() + 1) * float64(baseRetryDelay))
 | 
				
			||||||
 | 
							if delay > maxRetryDelay {
 | 
				
			||||||
 | 
								delay = maxRetryDelay
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							db.updateAPIErrors++
 | 
				
			||||||
 | 
							return delay, false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						db.updateAPIErrors = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// add jitter to wait time to avoid all servers lining up
 | 
				
			||||||
 | 
						nextUpdateWait := db.config.UpdatePeriod + time.Duration(rand.Int31n(60)-30)*time.Second
 | 
				
			||||||
 | 
						if resp.MinimumWaitDuration != nil {
 | 
				
			||||||
 | 
							serverMinWait := time.Duration(resp.MinimumWaitDuration.Seconds)*time.Second + time.Duration(resp.MinimumWaitDuration.Nanos)
 | 
				
			||||||
 | 
							if serverMinWait > nextUpdateWait {
 | 
				
			||||||
 | 
								nextUpdateWait = serverMinWait
 | 
				
			||||||
 | 
								db.log.Printf("Server requested next update in %v", nextUpdateWait)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(resp.ListUpdateResponses) != numTypes {
 | 
						if len(resp.ListUpdateResponses) != numTypes {
 | 
				
			||||||
 | 
							db.setError(errors.New("safebrowsing: threat list count mismatch"))
 | 
				
			||||||
		db.log.Printf("invalid server response: got %d, want %d threat lists",
 | 
							db.log.Printf("invalid server response: got %d, want %d threat lists",
 | 
				
			||||||
			len(resp.ListUpdateResponses), numTypes)
 | 
								len(resp.ListUpdateResponses), numTypes)
 | 
				
			||||||
		db.setError(errors.New("safebrowsing: threat list count mismatch"))
 | 
							return nextUpdateWait, false
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update the threat database with the response.
 | 
						// Update the threat database with the response.
 | 
				
			||||||
	db.generateThreatsForUpdate()
 | 
						db.generateThreatsForUpdate()
 | 
				
			||||||
	if err := db.tfu.update(resp); err != nil {
 | 
						if err := db.tfu.update(resp); err != nil {
 | 
				
			||||||
		db.log.Printf("update failure: %v", err)
 | 
					 | 
				
			||||||
		db.setError(err)
 | 
							db.setError(err)
 | 
				
			||||||
		return
 | 
							db.log.Printf("update failure: %v", err)
 | 
				
			||||||
 | 
							db.tfu = nil
 | 
				
			||||||
 | 
							return nextUpdateWait, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dbf := databaseFormat{make(threatsForUpdate), last}
 | 
						dbf := databaseFormat{make(threatsForUpdate), last}
 | 
				
			||||||
	for td, phs := range db.tfu {
 | 
						for td, phs := range db.tfu {
 | 
				
			||||||
| 
						 | 
					@ -215,6 +270,8 @@ func (db *database) Update(api api) {
 | 
				
			||||||
			db.log.Printf("save failure: %v", err)
 | 
								db.log.Printf("save failure: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nextUpdateWait, true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Lookup looks up the full hash in the threat list and returns a partial
 | 
					// Lookup looks up the full hash in the threat list and returns a partial
 | 
				
			||||||
| 
						 | 
					@ -242,10 +299,38 @@ func (db *database) setError(err error) {
 | 
				
			||||||
	db.tfu = nil
 | 
						db.tfu = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	db.ml.Lock()
 | 
						db.ml.Lock()
 | 
				
			||||||
 | 
						if db.err == nil {
 | 
				
			||||||
 | 
							db.readyCh = make(chan struct{})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	db.tfl, db.err, db.last = nil, err, time.Time{}
 | 
						db.tfl, db.err, db.last = nil, err, time.Time{}
 | 
				
			||||||
	db.ml.Unlock()
 | 
						db.ml.Unlock()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setStale sets the error state to a stale message, without clearing
 | 
				
			||||||
 | 
					// the database state.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This assumes that the db.ml lock is already held.
 | 
				
			||||||
 | 
					func (db *database) setStale() {
 | 
				
			||||||
 | 
						if db.err == nil {
 | 
				
			||||||
 | 
							db.readyCh = make(chan struct{})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						db.err = errStale
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// clearError clears the db error state, and unblocks any callers of
 | 
				
			||||||
 | 
					// WaitUntilReady.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This assumes that the db.mu lock is already held.
 | 
				
			||||||
 | 
					func (db *database) clearError() {
 | 
				
			||||||
 | 
						db.ml.Lock()
 | 
				
			||||||
 | 
						defer db.ml.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if db.err != nil {
 | 
				
			||||||
 | 
							close(db.readyCh)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						db.err = nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// generateThreatsForUpdate regenerates the threatsForUpdate hashes from
 | 
					// generateThreatsForUpdate regenerates the threatsForUpdate hashes from
 | 
				
			||||||
// the threatsForLookup. We do this to avoid holding onto the hash lists for
 | 
					// the threatsForLookup. We do this to avoid holding onto the hash lists for
 | 
				
			||||||
// a long time, needlessly occupying lots of memory.
 | 
					// a long time, needlessly occupying lots of memory.
 | 
				
			||||||
| 
						 | 
					@ -284,10 +369,11 @@ func (db *database) generateThreatsForLookups(last time.Time) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	db.ml.Lock()
 | 
						db.ml.Lock()
 | 
				
			||||||
	wasBad := db.err != nil
 | 
						wasBad := db.err != nil
 | 
				
			||||||
	db.tfl, db.err, db.last = tfl, nil, last
 | 
						db.tfl, db.last = tfl, last
 | 
				
			||||||
	db.ml.Unlock()
 | 
						db.ml.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if wasBad {
 | 
						if wasBad {
 | 
				
			||||||
 | 
							db.clearError()
 | 
				
			||||||
		db.log.Printf("database is now healthy")
 | 
							db.log.Printf("database is now healthy")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -424,7 +510,9 @@ func (tfu threatsForUpdate) update(resp *pb.FetchThreatListUpdatesResponse) erro
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		phs.SHA256 = m.GetChecksum().Sha256
 | 
							if cs := m.GetChecksum(); cs != nil {
 | 
				
			||||||
 | 
								phs.SHA256 = cs.Sha256
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if !bytes.Equal(phs.SHA256, phs.Hashes.SHA256()) {
 | 
							if !bytes.Equal(phs.SHA256, phs.Hashes.SHA256()) {
 | 
				
			||||||
			return errors.New("safebrowsing: threat list SHA256 mismatch")
 | 
								return errors.New("safebrowsing: threat list SHA256 mismatch")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										532
									
								
								vendor/github.com/google/safebrowsing/internal/safebrowsing_proto/safebrowsing.pb.go
								
								
									generated
								
								
									vendored
								
								
							
							
						
						
									
										532
									
								
								vendor/github.com/google/safebrowsing/internal/safebrowsing_proto/safebrowsing.pb.go
								
								
									generated
								
								
									vendored
								
								
							| 
						 | 
					@ -27,13 +27,13 @@ It has these top-level messages:
 | 
				
			||||||
	ThreatEntryMetadata
 | 
						ThreatEntryMetadata
 | 
				
			||||||
	ThreatListDescriptor
 | 
						ThreatListDescriptor
 | 
				
			||||||
	ListThreatListsResponse
 | 
						ListThreatListsResponse
 | 
				
			||||||
	Duration
 | 
					 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
package safebrowsing_proto
 | 
					package safebrowsing_proto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import proto "github.com/golang/protobuf/proto"
 | 
					import proto "github.com/golang/protobuf/proto"
 | 
				
			||||||
import fmt "fmt"
 | 
					import fmt "fmt"
 | 
				
			||||||
import math "math"
 | 
					import math "math"
 | 
				
			||||||
 | 
					import google_protobuf "github.com/golang/protobuf/ptypes/duration"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Reference imports to suppress errors if they are not otherwise used.
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
var _ = proto.Marshal
 | 
					var _ = proto.Marshal
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,9 @@ var _ = math.Inf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This is a compile-time assertion to ensure that this generated file
 | 
					// This is a compile-time assertion to ensure that this generated file
 | 
				
			||||||
// is compatible with the proto package it is being compiled against.
 | 
					// is compatible with the proto package it is being compiled against.
 | 
				
			||||||
const _ = proto.ProtoPackageIsVersion1
 | 
					// A compilation error at this line likely means your copy of the
 | 
				
			||||||
 | 
					// proto package needs to be updated.
 | 
				
			||||||
 | 
					const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Types of threats.
 | 
					// Types of threats.
 | 
				
			||||||
type ThreatType int32
 | 
					type ThreatType int32
 | 
				
			||||||
| 
						 | 
					@ -229,11 +231,11 @@ func (FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType) EnumDescri
 | 
				
			||||||
// checking for matches in threat lists.
 | 
					// checking for matches in threat lists.
 | 
				
			||||||
type ThreatInfo struct {
 | 
					type ThreatInfo struct {
 | 
				
			||||||
	// The threat types to be checked.
 | 
						// The threat types to be checked.
 | 
				
			||||||
	ThreatTypes []ThreatType `protobuf:"varint,1,rep,name=threat_types,json=threatTypes,enum=safebrowsing_proto.ThreatType" json:"threat_types,omitempty"`
 | 
						ThreatTypes []ThreatType `protobuf:"varint,1,rep,packed,name=threat_types,json=threatTypes,enum=safebrowsing_proto.ThreatType" json:"threat_types,omitempty"`
 | 
				
			||||||
	// The platform types to be checked.
 | 
						// The platform types to be checked.
 | 
				
			||||||
	PlatformTypes []PlatformType `protobuf:"varint,2,rep,name=platform_types,json=platformTypes,enum=safebrowsing_proto.PlatformType" json:"platform_types,omitempty"`
 | 
						PlatformTypes []PlatformType `protobuf:"varint,2,rep,packed,name=platform_types,json=platformTypes,enum=safebrowsing_proto.PlatformType" json:"platform_types,omitempty"`
 | 
				
			||||||
	// The entry types to be checked.
 | 
						// The entry types to be checked.
 | 
				
			||||||
	ThreatEntryTypes []ThreatEntryType `protobuf:"varint,4,rep,name=threat_entry_types,json=threatEntryTypes,enum=safebrowsing_proto.ThreatEntryType" json:"threat_entry_types,omitempty"`
 | 
						ThreatEntryTypes []ThreatEntryType `protobuf:"varint,4,rep,packed,name=threat_entry_types,json=threatEntryTypes,enum=safebrowsing_proto.ThreatEntryType" json:"threat_entry_types,omitempty"`
 | 
				
			||||||
	// The threat entries to be checked.
 | 
						// The threat entries to be checked.
 | 
				
			||||||
	ThreatEntries []*ThreatEntry `protobuf:"bytes,3,rep,name=threat_entries,json=threatEntries" json:"threat_entries,omitempty"`
 | 
						ThreatEntries []*ThreatEntry `protobuf:"bytes,3,rep,name=threat_entries,json=threatEntries" json:"threat_entries,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -243,6 +245,27 @@ func (m *ThreatInfo) String() string            { return proto.CompactTextString
 | 
				
			||||||
func (*ThreatInfo) ProtoMessage()               {}
 | 
					func (*ThreatInfo) ProtoMessage()               {}
 | 
				
			||||||
func (*ThreatInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 | 
					func (*ThreatInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatInfo) GetThreatTypes() []ThreatType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatTypes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatInfo) GetPlatformTypes() []PlatformType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.PlatformTypes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatInfo) GetThreatEntryTypes() []ThreatEntryType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatEntryTypes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *ThreatInfo) GetThreatEntries() []*ThreatEntry {
 | 
					func (m *ThreatInfo) GetThreatEntries() []*ThreatEntry {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.ThreatEntries
 | 
							return m.ThreatEntries
 | 
				
			||||||
| 
						 | 
					@ -264,7 +287,7 @@ type ThreatMatch struct {
 | 
				
			||||||
	ThreatEntryMetadata *ThreatEntryMetadata `protobuf:"bytes,4,opt,name=threat_entry_metadata,json=threatEntryMetadata" json:"threat_entry_metadata,omitempty"`
 | 
						ThreatEntryMetadata *ThreatEntryMetadata `protobuf:"bytes,4,opt,name=threat_entry_metadata,json=threatEntryMetadata" json:"threat_entry_metadata,omitempty"`
 | 
				
			||||||
	// The cache lifetime for the returned match. Clients must not cache this
 | 
						// The cache lifetime for the returned match. Clients must not cache this
 | 
				
			||||||
	// response for more than this duration to avoid false positives.
 | 
						// response for more than this duration to avoid false positives.
 | 
				
			||||||
	CacheDuration *Duration `protobuf:"bytes,5,opt,name=cache_duration,json=cacheDuration" json:"cache_duration,omitempty"`
 | 
						CacheDuration *google_protobuf.Duration `protobuf:"bytes,5,opt,name=cache_duration,json=cacheDuration" json:"cache_duration,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *ThreatMatch) Reset()                    { *m = ThreatMatch{} }
 | 
					func (m *ThreatMatch) Reset()                    { *m = ThreatMatch{} }
 | 
				
			||||||
| 
						 | 
					@ -272,6 +295,27 @@ func (m *ThreatMatch) String() string            { return proto.CompactTextStrin
 | 
				
			||||||
func (*ThreatMatch) ProtoMessage()               {}
 | 
					func (*ThreatMatch) ProtoMessage()               {}
 | 
				
			||||||
func (*ThreatMatch) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 | 
					func (*ThreatMatch) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatMatch) GetThreatType() ThreatType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatType_THREAT_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatMatch) GetPlatformType() PlatformType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.PlatformType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return PlatformType_PLATFORM_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatMatch) GetThreatEntryType() ThreatEntryType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatEntryType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatEntryType_THREAT_ENTRY_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *ThreatMatch) GetThreat() *ThreatEntry {
 | 
					func (m *ThreatMatch) GetThreat() *ThreatEntry {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Threat
 | 
							return m.Threat
 | 
				
			||||||
| 
						 | 
					@ -286,7 +330,7 @@ func (m *ThreatMatch) GetThreatEntryMetadata() *ThreatEntryMetadata {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *ThreatMatch) GetCacheDuration() *Duration {
 | 
					func (m *ThreatMatch) GetCacheDuration() *google_protobuf.Duration {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.CacheDuration
 | 
							return m.CacheDuration
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -394,6 +438,34 @@ func (*FetchThreatListUpdatesRequest_ListUpdateRequest) Descriptor() ([]byte, []
 | 
				
			||||||
	return fileDescriptor0, []int{4, 0}
 | 
						return fileDescriptor0, []int{4, 0}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest) GetThreatType() ThreatType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatType_THREAT_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest) GetPlatformType() PlatformType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.PlatformType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return PlatformType_PLATFORM_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest) GetThreatEntryType() ThreatEntryType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatEntryType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatEntryType_THREAT_ENTRY_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest) GetState() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.State
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FetchThreatListUpdatesRequest_ListUpdateRequest) GetConstraints() *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints {
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest) GetConstraints() *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Constraints
 | 
							return m.Constraints
 | 
				
			||||||
| 
						 | 
					@ -416,7 +488,7 @@ type FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints struct {
 | 
				
			||||||
	// 3166-1 alpha-2 format.
 | 
						// 3166-1 alpha-2 format.
 | 
				
			||||||
	Region string `protobuf:"bytes,3,opt,name=region" json:"region,omitempty"`
 | 
						Region string `protobuf:"bytes,3,opt,name=region" json:"region,omitempty"`
 | 
				
			||||||
	// The compression types supported by the client.
 | 
						// The compression types supported by the client.
 | 
				
			||||||
	SupportedCompressions []CompressionType `protobuf:"varint,4,rep,name=supported_compressions,json=supportedCompressions,enum=safebrowsing_proto.CompressionType" json:"supported_compressions,omitempty"`
 | 
						SupportedCompressions []CompressionType `protobuf:"varint,4,rep,packed,name=supported_compressions,json=supportedCompressions,enum=safebrowsing_proto.CompressionType" json:"supported_compressions,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) Reset() {
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) Reset() {
 | 
				
			||||||
| 
						 | 
					@ -430,13 +502,41 @@ func (*FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) Descriptor()
 | 
				
			||||||
	return fileDescriptor0, []int{4, 0, 0}
 | 
						return fileDescriptor0, []int{4, 0, 0}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) GetMaxUpdateEntries() int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.MaxUpdateEntries
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) GetMaxDatabaseEntries() int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.MaxDatabaseEntries
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) GetRegion() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Region
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints) GetSupportedCompressions() []CompressionType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.SupportedCompressions
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Response type for threat list update requests.
 | 
					// Response type for threat list update requests.
 | 
				
			||||||
type FetchThreatListUpdatesResponse struct {
 | 
					type FetchThreatListUpdatesResponse struct {
 | 
				
			||||||
	// The list updates requested by the clients.
 | 
						// The list updates requested by the clients.
 | 
				
			||||||
	ListUpdateResponses []*FetchThreatListUpdatesResponse_ListUpdateResponse `protobuf:"bytes,1,rep,name=list_update_responses,json=listUpdateResponses" json:"list_update_responses,omitempty"`
 | 
						ListUpdateResponses []*FetchThreatListUpdatesResponse_ListUpdateResponse `protobuf:"bytes,1,rep,name=list_update_responses,json=listUpdateResponses" json:"list_update_responses,omitempty"`
 | 
				
			||||||
	// The minimum duration the client must wait before issuing any update
 | 
						// The minimum duration the client must wait before issuing any update
 | 
				
			||||||
	// request. If this field is not set clients may update as soon as they want.
 | 
						// request. If this field is not set clients may update as soon as they want.
 | 
				
			||||||
	MinimumWaitDuration *Duration `protobuf:"bytes,2,opt,name=minimum_wait_duration,json=minimumWaitDuration" json:"minimum_wait_duration,omitempty"`
 | 
						MinimumWaitDuration *google_protobuf.Duration `protobuf:"bytes,2,opt,name=minimum_wait_duration,json=minimumWaitDuration" json:"minimum_wait_duration,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FetchThreatListUpdatesResponse) Reset()                    { *m = FetchThreatListUpdatesResponse{} }
 | 
					func (m *FetchThreatListUpdatesResponse) Reset()                    { *m = FetchThreatListUpdatesResponse{} }
 | 
				
			||||||
| 
						 | 
					@ -451,7 +551,7 @@ func (m *FetchThreatListUpdatesResponse) GetListUpdateResponses() []*FetchThreat
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FetchThreatListUpdatesResponse) GetMinimumWaitDuration() *Duration {
 | 
					func (m *FetchThreatListUpdatesResponse) GetMinimumWaitDuration() *google_protobuf.Duration {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.MinimumWaitDuration
 | 
							return m.MinimumWaitDuration
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -496,6 +596,34 @@ func (*FetchThreatListUpdatesResponse_ListUpdateResponse) Descriptor() ([]byte,
 | 
				
			||||||
	return fileDescriptor0, []int{5, 0}
 | 
						return fileDescriptor0, []int{5, 0}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetThreatType() ThreatType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatType_THREAT_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetThreatEntryType() ThreatEntryType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatEntryType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatEntryType_THREAT_ENTRY_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetPlatformType() PlatformType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.PlatformType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return PlatformType_PLATFORM_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetResponseType() FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ResponseType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return FetchThreatListUpdatesResponse_ListUpdateResponse_RESPONSE_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetAdditions() []*ThreatEntrySet {
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetAdditions() []*ThreatEntrySet {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Additions
 | 
							return m.Additions
 | 
				
			||||||
| 
						 | 
					@ -510,6 +638,13 @@ func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetRemovals() []*Thr
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetNewClientState() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.NewClientState
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetChecksum() *Checksum {
 | 
					func (m *FetchThreatListUpdatesResponse_ListUpdateResponse) GetChecksum() *Checksum {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.Checksum
 | 
							return m.Checksum
 | 
				
			||||||
| 
						 | 
					@ -539,6 +674,13 @@ func (m *FindFullHashesRequest) GetClient() *ClientInfo {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *FindFullHashesRequest) GetClientStates() [][]byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ClientStates
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FindFullHashesRequest) GetThreatInfo() *ThreatInfo {
 | 
					func (m *FindFullHashesRequest) GetThreatInfo() *ThreatInfo {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.ThreatInfo
 | 
							return m.ThreatInfo
 | 
				
			||||||
| 
						 | 
					@ -553,10 +695,10 @@ type FindFullHashesResponse struct {
 | 
				
			||||||
	// The minimum duration the client must wait before issuing any find hashes
 | 
						// The minimum duration the client must wait before issuing any find hashes
 | 
				
			||||||
	// request. If this field is not set, clients can issue a request as soon as
 | 
						// request. If this field is not set, clients can issue a request as soon as
 | 
				
			||||||
	// they want.
 | 
						// they want.
 | 
				
			||||||
	MinimumWaitDuration *Duration `protobuf:"bytes,2,opt,name=minimum_wait_duration,json=minimumWaitDuration" json:"minimum_wait_duration,omitempty"`
 | 
						MinimumWaitDuration *google_protobuf.Duration `protobuf:"bytes,2,opt,name=minimum_wait_duration,json=minimumWaitDuration" json:"minimum_wait_duration,omitempty"`
 | 
				
			||||||
	// For requested entities that did not match the threat list, how long to
 | 
						// For requested entities that did not match the threat list, how long to
 | 
				
			||||||
	// cache the response.
 | 
						// cache the response.
 | 
				
			||||||
	NegativeCacheDuration *Duration `protobuf:"bytes,3,opt,name=negative_cache_duration,json=negativeCacheDuration" json:"negative_cache_duration,omitempty"`
 | 
						NegativeCacheDuration *google_protobuf.Duration `protobuf:"bytes,3,opt,name=negative_cache_duration,json=negativeCacheDuration" json:"negative_cache_duration,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FindFullHashesResponse) Reset()                    { *m = FindFullHashesResponse{} }
 | 
					func (m *FindFullHashesResponse) Reset()                    { *m = FindFullHashesResponse{} }
 | 
				
			||||||
| 
						 | 
					@ -571,14 +713,14 @@ func (m *FindFullHashesResponse) GetMatches() []*ThreatMatch {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FindFullHashesResponse) GetMinimumWaitDuration() *Duration {
 | 
					func (m *FindFullHashesResponse) GetMinimumWaitDuration() *google_protobuf.Duration {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.MinimumWaitDuration
 | 
							return m.MinimumWaitDuration
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *FindFullHashesResponse) GetNegativeCacheDuration() *Duration {
 | 
					func (m *FindFullHashesResponse) GetNegativeCacheDuration() *google_protobuf.Duration {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.NegativeCacheDuration
 | 
							return m.NegativeCacheDuration
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -599,6 +741,20 @@ func (m *ClientInfo) String() string            { return proto.CompactTextString
 | 
				
			||||||
func (*ClientInfo) ProtoMessage()               {}
 | 
					func (*ClientInfo) ProtoMessage()               {}
 | 
				
			||||||
func (*ClientInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
 | 
					func (*ClientInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ClientInfo) GetClientId() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ClientId
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ClientInfo) GetClientVersion() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ClientVersion
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The expected state of a client's local database.
 | 
					// The expected state of a client's local database.
 | 
				
			||||||
type Checksum struct {
 | 
					type Checksum struct {
 | 
				
			||||||
	// The SHA256 hash of the client state; that is, of the sorted list of all
 | 
						// The SHA256 hash of the client state; that is, of the sorted list of all
 | 
				
			||||||
| 
						 | 
					@ -611,6 +767,13 @@ func (m *Checksum) String() string            { return proto.CompactTextString(m
 | 
				
			||||||
func (*Checksum) ProtoMessage()               {}
 | 
					func (*Checksum) ProtoMessage()               {}
 | 
				
			||||||
func (*Checksum) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
 | 
					func (*Checksum) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Checksum) GetSha256() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Sha256
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// An individual threat; for example, a malicious URL or its hash
 | 
					// An individual threat; for example, a malicious URL or its hash
 | 
				
			||||||
// representation. Only one of these fields should be set.
 | 
					// representation. Only one of these fields should be set.
 | 
				
			||||||
type ThreatEntry struct {
 | 
					type ThreatEntry struct {
 | 
				
			||||||
| 
						 | 
					@ -626,6 +789,20 @@ func (m *ThreatEntry) String() string            { return proto.CompactTextStrin
 | 
				
			||||||
func (*ThreatEntry) ProtoMessage()               {}
 | 
					func (*ThreatEntry) ProtoMessage()               {}
 | 
				
			||||||
func (*ThreatEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
 | 
					func (*ThreatEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatEntry) GetHash() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Hash
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatEntry) GetUrl() string {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Url
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A set of threats that should be added or removed from a client's local
 | 
					// A set of threats that should be added or removed from a client's local
 | 
				
			||||||
// database.
 | 
					// database.
 | 
				
			||||||
type ThreatEntrySet struct {
 | 
					type ThreatEntrySet struct {
 | 
				
			||||||
| 
						 | 
					@ -648,6 +825,13 @@ func (m *ThreatEntrySet) String() string            { return proto.CompactTextSt
 | 
				
			||||||
func (*ThreatEntrySet) ProtoMessage()               {}
 | 
					func (*ThreatEntrySet) ProtoMessage()               {}
 | 
				
			||||||
func (*ThreatEntrySet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
 | 
					func (*ThreatEntrySet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatEntrySet) GetCompressionType() CompressionType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.CompressionType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return CompressionType_COMPRESSION_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *ThreatEntrySet) GetRawHashes() *RawHashes {
 | 
					func (m *ThreatEntrySet) GetRawHashes() *RawHashes {
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil {
 | 
				
			||||||
		return m.RawHashes
 | 
							return m.RawHashes
 | 
				
			||||||
| 
						 | 
					@ -679,7 +863,7 @@ func (m *ThreatEntrySet) GetRiceIndices() *RiceDeltaEncoding {
 | 
				
			||||||
// A set of raw indices to remove from a local list.
 | 
					// A set of raw indices to remove from a local list.
 | 
				
			||||||
type RawIndices struct {
 | 
					type RawIndices struct {
 | 
				
			||||||
	// The indices to remove from a lexicographically-sorted local list.
 | 
						// The indices to remove from a lexicographically-sorted local list.
 | 
				
			||||||
	Indices []int32 `protobuf:"varint,1,rep,name=indices" json:"indices,omitempty"`
 | 
						Indices []int32 `protobuf:"varint,1,rep,packed,name=indices" json:"indices,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *RawIndices) Reset()                    { *m = RawIndices{} }
 | 
					func (m *RawIndices) Reset()                    { *m = RawIndices{} }
 | 
				
			||||||
| 
						 | 
					@ -687,6 +871,13 @@ func (m *RawIndices) String() string            { return proto.CompactTextString
 | 
				
			||||||
func (*RawIndices) ProtoMessage()               {}
 | 
					func (*RawIndices) ProtoMessage()               {}
 | 
				
			||||||
func (*RawIndices) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
 | 
					func (*RawIndices) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RawIndices) GetIndices() []int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Indices
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The uncompressed threat entries in hash format of a particular prefix length.
 | 
					// The uncompressed threat entries in hash format of a particular prefix length.
 | 
				
			||||||
// Hashes can be anywhere from 4 to 32 bytes in size. A large majority are 4
 | 
					// Hashes can be anywhere from 4 to 32 bytes in size. A large majority are 4
 | 
				
			||||||
// bytes, but some hashes are lengthened if they collide with the hash of a
 | 
					// bytes, but some hashes are lengthened if they collide with the hash of a
 | 
				
			||||||
| 
						 | 
					@ -708,6 +899,20 @@ func (m *RawHashes) String() string            { return proto.CompactTextString(
 | 
				
			||||||
func (*RawHashes) ProtoMessage()               {}
 | 
					func (*RawHashes) ProtoMessage()               {}
 | 
				
			||||||
func (*RawHashes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
 | 
					func (*RawHashes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RawHashes) GetPrefixSize() int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.PrefixSize
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RawHashes) GetRawHashes() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.RawHashes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The Rice-Golomb encoded data. Used for sending compressed 4-byte hashes or
 | 
					// The Rice-Golomb encoded data. Used for sending compressed 4-byte hashes or
 | 
				
			||||||
// compressed removal indices.
 | 
					// compressed removal indices.
 | 
				
			||||||
type RiceDeltaEncoding struct {
 | 
					type RiceDeltaEncoding struct {
 | 
				
			||||||
| 
						 | 
					@ -730,6 +935,34 @@ func (m *RiceDeltaEncoding) String() string            { return proto.CompactTex
 | 
				
			||||||
func (*RiceDeltaEncoding) ProtoMessage()               {}
 | 
					func (*RiceDeltaEncoding) ProtoMessage()               {}
 | 
				
			||||||
func (*RiceDeltaEncoding) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
 | 
					func (*RiceDeltaEncoding) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RiceDeltaEncoding) GetFirstValue() int64 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.FirstValue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RiceDeltaEncoding) GetRiceParameter() int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.RiceParameter
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RiceDeltaEncoding) GetNumEntries() int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.NumEntries
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *RiceDeltaEncoding) GetEncodedData() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.EncodedData
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The metadata associated with a specific threat entry. The client is expected
 | 
					// The metadata associated with a specific threat entry. The client is expected
 | 
				
			||||||
// to know the metadata key/value pairs associated with each threat type.
 | 
					// to know the metadata key/value pairs associated with each threat type.
 | 
				
			||||||
type ThreatEntryMetadata struct {
 | 
					type ThreatEntryMetadata struct {
 | 
				
			||||||
| 
						 | 
					@ -764,6 +997,20 @@ func (*ThreatEntryMetadata_MetadataEntry) Descriptor() ([]byte, []int) {
 | 
				
			||||||
	return fileDescriptor0, []int{15, 0}
 | 
						return fileDescriptor0, []int{15, 0}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatEntryMetadata_MetadataEntry) GetKey() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Key
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatEntryMetadata_MetadataEntry) GetValue() []byte {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.Value
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Describes an individual threat list. A list is defined by three parameters:
 | 
					// Describes an individual threat list. A list is defined by three parameters:
 | 
				
			||||||
// the type of threat posed, the type of platform targeted by the threat, and
 | 
					// the type of threat posed, the type of platform targeted by the threat, and
 | 
				
			||||||
// the type of entries in the list.
 | 
					// the type of entries in the list.
 | 
				
			||||||
| 
						 | 
					@ -781,6 +1028,27 @@ func (m *ThreatListDescriptor) String() string            { return proto.Compact
 | 
				
			||||||
func (*ThreatListDescriptor) ProtoMessage()               {}
 | 
					func (*ThreatListDescriptor) ProtoMessage()               {}
 | 
				
			||||||
func (*ThreatListDescriptor) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
 | 
					func (*ThreatListDescriptor) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatListDescriptor) GetThreatType() ThreatType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatType_THREAT_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatListDescriptor) GetPlatformType() PlatformType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.PlatformType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return PlatformType_PLATFORM_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *ThreatListDescriptor) GetThreatEntryType() ThreatEntryType {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.ThreatEntryType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ThreatEntryType_THREAT_ENTRY_TYPE_UNSPECIFIED
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A collection of lists available for download by the client.
 | 
					// A collection of lists available for download by the client.
 | 
				
			||||||
type ListThreatListsResponse struct {
 | 
					type ListThreatListsResponse struct {
 | 
				
			||||||
	// The lists available for download by the client.
 | 
						// The lists available for download by the client.
 | 
				
			||||||
| 
						 | 
					@ -799,30 +1067,6 @@ func (m *ListThreatListsResponse) GetThreatLists() []*ThreatListDescriptor {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A Duration represents a signed, fixed-length span of time represented
 | 
					 | 
				
			||||||
// as a count of seconds and fractions of seconds at nanosecond
 | 
					 | 
				
			||||||
// resolution. It is independent of any calendar and concepts like "day"
 | 
					 | 
				
			||||||
// or "month". It is related to Timestamp in that the difference between
 | 
					 | 
				
			||||||
// two Timestamp values is a Duration and it can be added or subtracted
 | 
					 | 
				
			||||||
// from a Timestamp. Range is approximately +-10,000 years.
 | 
					 | 
				
			||||||
type Duration struct {
 | 
					 | 
				
			||||||
	// Signed seconds of the span of time. Must be from -315,576,000,000
 | 
					 | 
				
			||||||
	// to +315,576,000,000 inclusive.
 | 
					 | 
				
			||||||
	Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
 | 
					 | 
				
			||||||
	// Signed fractions of a second at nanosecond resolution of the span
 | 
					 | 
				
			||||||
	// of time. Durations less than one second are represented with a 0
 | 
					 | 
				
			||||||
	// `seconds` field and a positive or negative `nanos` field. For durations
 | 
					 | 
				
			||||||
	// of one second or more, a non-zero value for the `nanos` field must be
 | 
					 | 
				
			||||||
	// of the same sign as the `seconds` field. Must be from -999,999,999
 | 
					 | 
				
			||||||
	// to +999,999,999 inclusive.
 | 
					 | 
				
			||||||
	Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *Duration) Reset()                    { *m = Duration{} }
 | 
					 | 
				
			||||||
func (m *Duration) String() string            { return proto.CompactTextString(m) }
 | 
					 | 
				
			||||||
func (*Duration) ProtoMessage()               {}
 | 
					 | 
				
			||||||
func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	proto.RegisterType((*ThreatInfo)(nil), "safebrowsing_proto.ThreatInfo")
 | 
						proto.RegisterType((*ThreatInfo)(nil), "safebrowsing_proto.ThreatInfo")
 | 
				
			||||||
	proto.RegisterType((*ThreatMatch)(nil), "safebrowsing_proto.ThreatMatch")
 | 
						proto.RegisterType((*ThreatMatch)(nil), "safebrowsing_proto.ThreatMatch")
 | 
				
			||||||
| 
						 | 
					@ -846,7 +1090,6 @@ func init() {
 | 
				
			||||||
	proto.RegisterType((*ThreatEntryMetadata_MetadataEntry)(nil), "safebrowsing_proto.ThreatEntryMetadata.MetadataEntry")
 | 
						proto.RegisterType((*ThreatEntryMetadata_MetadataEntry)(nil), "safebrowsing_proto.ThreatEntryMetadata.MetadataEntry")
 | 
				
			||||||
	proto.RegisterType((*ThreatListDescriptor)(nil), "safebrowsing_proto.ThreatListDescriptor")
 | 
						proto.RegisterType((*ThreatListDescriptor)(nil), "safebrowsing_proto.ThreatListDescriptor")
 | 
				
			||||||
	proto.RegisterType((*ListThreatListsResponse)(nil), "safebrowsing_proto.ListThreatListsResponse")
 | 
						proto.RegisterType((*ListThreatListsResponse)(nil), "safebrowsing_proto.ListThreatListsResponse")
 | 
				
			||||||
	proto.RegisterType((*Duration)(nil), "safebrowsing_proto.Duration")
 | 
					 | 
				
			||||||
	proto.RegisterEnum("safebrowsing_proto.ThreatType", ThreatType_name, ThreatType_value)
 | 
						proto.RegisterEnum("safebrowsing_proto.ThreatType", ThreatType_name, ThreatType_value)
 | 
				
			||||||
	proto.RegisterEnum("safebrowsing_proto.PlatformType", PlatformType_name, PlatformType_value)
 | 
						proto.RegisterEnum("safebrowsing_proto.PlatformType", PlatformType_name, PlatformType_value)
 | 
				
			||||||
	proto.RegisterEnum("safebrowsing_proto.CompressionType", CompressionType_name, CompressionType_value)
 | 
						proto.RegisterEnum("safebrowsing_proto.CompressionType", CompressionType_name, CompressionType_value)
 | 
				
			||||||
| 
						 | 
					@ -854,108 +1097,111 @@ func init() {
 | 
				
			||||||
	proto.RegisterEnum("safebrowsing_proto.FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType", FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType_name, FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType_value)
 | 
						proto.RegisterEnum("safebrowsing_proto.FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType", FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType_name, FetchThreatListUpdatesResponse_ListUpdateResponse_ResponseType_value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() { proto.RegisterFile("safebrowsing.proto", fileDescriptor0) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor0 = []byte{
 | 
					var fileDescriptor0 = []byte{
 | 
				
			||||||
	// 1628 bytes of a gzipped FileDescriptorProto
 | 
						// 1636 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x58, 0x5b, 0x6f, 0xdb, 0x46,
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x8f, 0xdb, 0xc6,
 | 
				
			||||||
	0x16, 0x5e, 0x49, 0xd6, 0xed, 0x48, 0xb2, 0xe5, 0xf1, 0x25, 0x8e, 0x13, 0x27, 0x59, 0x06, 0xd9,
 | 
						0x15, 0x2f, 0xc5, 0x95, 0xb4, 0xfb, 0xf4, 0x67, 0xb9, 0x63, 0xaf, 0x2d, 0x6f, 0x62, 0x7b, 0x43,
 | 
				
			||||||
	0x0d, 0x8c, 0x85, 0xb1, 0x48, 0x90, 0x64, 0x77, 0xb1, 0xd8, 0x2d, 0x2b, 0x51, 0x36, 0x11, 0x99,
 | 
						0x23, 0xad, 0x61, 0x14, 0x4a, 0xe1, 0x20, 0x49, 0x0b, 0x14, 0x6d, 0x58, 0x89, 0xf2, 0x12, 0xd1,
 | 
				
			||||||
	0x52, 0x47, 0x72, 0x1c, 0xb7, 0x0f, 0x04, 0x23, 0xd1, 0x31, 0x11, 0xdd, 0x42, 0x52, 0x71, 0xdc,
 | 
						0x92, 0xca, 0x48, 0xf2, 0xda, 0xcd, 0x81, 0xa0, 0xa9, 0xd1, 0x8a, 0x88, 0x44, 0x2a, 0x9c, 0x91,
 | 
				
			||||||
	0x9f, 0xd0, 0xa7, 0x02, 0x45, 0x9f, 0xdb, 0xe7, 0xbe, 0x16, 0xfd, 0x01, 0xfd, 0x19, 0x7d, 0xec,
 | 
						0xe5, 0xcd, 0x47, 0x28, 0xd0, 0x53, 0xd1, 0x73, 0x7b, 0xee, 0xb5, 0xe8, 0xb5, 0xdf, 0xa3, 0xc7,
 | 
				
			||||||
	0x2f, 0x28, 0xfa, 0xdc, 0x97, 0x9e, 0x19, 0xce, 0x88, 0xd4, 0xc5, 0x8e, 0x12, 0xfb, 0x21, 0x6f,
 | 
						0x7e, 0x82, 0xa2, 0x87, 0xde, 0x8b, 0x19, 0x0e, 0x25, 0xea, 0xcf, 0x7a, 0xd7, 0x59, 0x1f, 0x72,
 | 
				
			||||||
	0x33, 0x67, 0xce, 0x7c, 0x73, 0xf8, 0xcd, 0xb9, 0x0d, 0x81, 0x78, 0xd6, 0xb1, 0xfd, 0xc2, 0xed,
 | 
						0x9b, 0x79, 0x7c, 0xf3, 0x9b, 0xc7, 0xdf, 0xfb, 0x4b, 0x02, 0xa2, 0xde, 0x90, 0xbc, 0x8a, 0xa3,
 | 
				
			||||||
	0x9f, 0x7a, 0x4e, 0xef, 0xe5, 0xce, 0xc0, 0xed, 0xfb, 0x7d, 0x32, 0x26, 0x33, 0xb9, 0x4c, 0xf9,
 | 
						0x39, 0x0d, 0xc2, 0xf3, 0xfa, 0x34, 0x8e, 0x58, 0x84, 0x56, 0x64, 0xae, 0x90, 0x1d, 0x3d, 0x38,
 | 
				
			||||||
	0x31, 0x0e, 0xd0, 0x3c, 0x71, 0x6d, 0xcb, 0xd7, 0x7b, 0xc7, 0x7d, 0xa2, 0x42, 0xde, 0xe7, 0x33,
 | 
						0x8f, 0xa2, 0xf3, 0x31, 0xf9, 0x44, 0xec, 0x5e, 0xcd, 0x86, 0x9f, 0x0c, 0x66, 0xb1, 0xc7, 0x82,
 | 
				
			||||||
	0xd3, 0x3f, 0x1b, 0xd8, 0xde, 0x46, 0xec, 0x4e, 0xe2, 0xfe, 0xe2, 0x83, 0x5b, 0x3b, 0xd3, 0x3b,
 | 
						0x28, 0x4c, 0xce, 0xe8, 0x7f, 0xcf, 0x01, 0xf4, 0x46, 0x31, 0xf1, 0x98, 0x15, 0x0e, 0x23, 0x64,
 | 
				
			||||||
	0x77, 0x82, 0x5d, 0x4d, 0x54, 0xa3, 0x39, 0x7f, 0x34, 0xf6, 0xc8, 0x2e, 0x2c, 0x0e, 0x3a, 0x96,
 | 
						0x40, 0x99, 0x89, 0x9d, 0xcb, 0x2e, 0xa6, 0x84, 0xd6, 0x94, 0x63, 0xf5, 0x71, 0xf5, 0xe9, 0x83,
 | 
				
			||||||
	0x7f, 0xdc, 0x77, 0xbb, 0x02, 0x24, 0xce, 0x41, 0xee, 0xcc, 0x02, 0xa9, 0x0b, 0x4d, 0x0e, 0x53,
 | 
						0xfa, 0x26, 0x72, 0x3d, 0x39, 0xd5, 0xbb, 0x98, 0x12, 0x5c, 0x62, 0x8b, 0x35, 0x45, 0xcf, 0xa0,
 | 
				
			||||||
	0x18, 0x44, 0x66, 0x1e, 0xf9, 0x0c, 0x88, 0xb0, 0xc5, 0xee, 0xf9, 0xee, 0x99, 0x00, 0x5b, 0xe0,
 | 
						0x3a, 0x1d, 0x7b, 0x6c, 0x18, 0xc5, 0x13, 0x09, 0x92, 0x13, 0x20, 0xc7, 0xdb, 0x40, 0x3a, 0x52,
 | 
				
			||||||
	0x60, 0x77, 0xcf, 0xb7, 0x48, 0x63, 0xca, 0x1c, 0xaf, 0xe8, 0x8f, 0x0b, 0x3c, 0x52, 0x81, 0xc5,
 | 
						0x53, 0xc0, 0x54, 0xa6, 0x99, 0x1d, 0x45, 0x5f, 0x03, 0x92, 0xb6, 0x90, 0x90, 0xc5, 0x17, 0x12,
 | 
				
			||||||
	0x08, 0xa4, 0x83, 0x70, 0x09, 0x84, 0xcb, 0x3d, 0xb8, 0xfd, 0x0e, 0x38, 0x5a, 0x08, 0xa1, 0x70,
 | 
						0x6c, 0x47, 0x80, 0x3d, 0xba, 0xdc, 0x22, 0x93, 0x2b, 0x0b, 0x3c, 0x8d, 0xad, 0x0a, 0x28, 0x6a,
 | 
				
			||||||
	0x97, 0xf2, 0x73, 0x02, 0x72, 0xc1, 0xf2, 0xbe, 0xe5, 0xb7, 0x4e, 0xc8, 0xff, 0x21, 0x17, 0xa1,
 | 
						0x41, 0x35, 0x03, 0x19, 0x10, 0x5a, 0x53, 0x8f, 0xd5, 0xc7, 0xa5, 0xa7, 0x0f, 0xaf, 0x80, 0xc3,
 | 
				
			||||||
	0x0d, 0x59, 0x8b, 0xcd, 0xc1, 0x1a, 0x84, 0xac, 0x11, 0x0d, 0x0a, 0x63, 0xa4, 0x21, 0x67, 0xb1,
 | 
						0x95, 0x25, 0x54, 0x40, 0xa8, 0xfe, 0x4f, 0x15, 0x4a, 0xc9, 0xe3, 0x53, 0x8f, 0xf9, 0x23, 0xf4,
 | 
				
			||||||
	0xb9, 0x38, 0xcb, 0x47, 0x39, 0x23, 0x35, 0x58, 0x9e, 0xa2, 0x6c, 0x23, 0xc5, 0xa1, 0xe6, 0x62,
 | 
						0x5b, 0x28, 0x65, 0x68, 0xab, 0x29, 0xc7, 0xca, 0x35, 0x58, 0x83, 0x25, 0x6b, 0xc8, 0x84, 0xca,
 | 
				
			||||||
	0x6c, 0x69, 0x82, 0x31, 0xf2, 0x04, 0x52, 0x81, 0x08, 0x89, 0x8a, 0xcd, 0x43, 0x94, 0x50, 0x27,
 | 
						0x0a, 0x69, 0xb5, 0x9c, 0x80, 0xb8, 0x9a, 0xb3, 0x72, 0x96, 0x33, 0xe4, 0xc0, 0xc1, 0x06, 0x65,
 | 
				
			||||||
	0x5f, 0xc0, 0xda, 0x98, 0x25, 0x5d, 0xdb, 0xb7, 0xda, 0x96, 0x6f, 0xe1, 0xfd, 0x31, 0x9c, 0xbf,
 | 
						0xb5, 0x82, 0x80, 0xba, 0x16, 0x63, 0xfb, 0x6b, 0x8c, 0xa1, 0x2f, 0xa0, 0x90, 0x88, 0x6a, 0xea,
 | 
				
			||||||
	0xbf, 0x03, 0x67, 0x5f, 0xa8, 0xd3, 0x15, 0x7f, 0x5a, 0x48, 0x4a, 0xb0, 0xd8, 0xb2, 0x5a, 0x27,
 | 
						0xb1, 0x72, 0x1d, 0xa2, 0xa4, 0x3a, 0xfa, 0x06, 0x0e, 0x57, 0x2c, 0x99, 0x10, 0xe6, 0x0d, 0x3c,
 | 
				
			||||||
	0xb6, 0xd9, 0x1e, 0xba, 0x96, 0xef, 0xf4, 0x7b, 0x1b, 0x49, 0x8e, 0x7a, 0x73, 0x16, 0x6a, 0x59,
 | 
						0xe6, 0xd5, 0x76, 0x04, 0xce, 0xcf, 0xae, 0xc0, 0x39, 0x95, 0xea, 0xf8, 0x16, 0xdb, 0x14, 0xa2,
 | 
				
			||||||
	0xe8, 0xd0, 0x02, 0xdf, 0x23, 0xa7, 0xca, 0x37, 0x31, 0xd8, 0xa8, 0x38, 0xbd, 0x76, 0xe4, 0x1e,
 | 
						0x2f, 0xa1, 0xea, 0x7b, 0xfe, 0x88, 0xb8, 0x69, 0x30, 0xd7, 0xf2, 0x02, 0xf5, 0x5e, 0x3d, 0x89,
 | 
				
			||||||
	0x6d, 0x8f, 0xda, 0xaf, 0x87, 0xb6, 0xe7, 0x93, 0xc7, 0x90, 0x6a, 0x75, 0x1c, 0x34, 0x9d, 0xdf,
 | 
						0xf6, 0x7a, 0x1a, 0xed, 0xf5, 0xa6, 0x54, 0xc0, 0x15, 0x71, 0x20, 0xdd, 0xea, 0x7f, 0x52, 0xa0,
 | 
				
			||||||
	0x65, 0x6e, 0xf6, 0x5d, 0x96, 0xb8, 0x06, 0x8b, 0x1b, 0x2a, 0xb4, 0x23, 0x8e, 0xe0, 0xa0, 0x98,
 | 
						0xd6, 0x0a, 0xc2, 0x41, 0xc6, 0x89, 0x84, 0x62, 0xf2, 0xdd, 0x8c, 0x50, 0x86, 0x3e, 0x87, 0x82,
 | 
				
			||||||
	0xdf, 0x62, 0xee, 0x22, 0x47, 0xe0, 0x9b, 0x85, 0x23, 0xb0, 0xb1, 0xf2, 0x0c, 0xae, 0xcf, 0x30,
 | 
						0x3f, 0x0e, 0x48, 0xc8, 0x84, 0x23, 0x4b, 0xdb, 0x1d, 0xd9, 0x10, 0x1a, 0x3c, 0x69, 0xb0, 0xd4,
 | 
				
			||||||
	0xca, 0x1b, 0xf4, 0x7b, 0x9e, 0x4d, 0xfe, 0x0d, 0xe9, 0x6e, 0x20, 0xe2, 0x81, 0x79, 0xe1, 0x75,
 | 
						0xce, 0x44, 0x41, 0x10, 0x0e, 0x23, 0xe1, 0xc2, 0xd2, 0xdb, 0xa2, 0x40, 0x1c, 0x96, 0x51, 0xc0,
 | 
				
			||||||
	0xf0, 0xbd, 0x54, 0xea, 0x2b, 0x3f, 0xa4, 0x60, 0xab, 0x62, 0xe3, 0x38, 0x58, 0xad, 0x3a, 0x9e,
 | 
						0xd7, 0xfa, 0x73, 0xb8, 0xb7, 0xc5, 0x28, 0x3a, 0x8d, 0x42, 0x4a, 0xd0, 0xaf, 0xa0, 0x38, 0x49,
 | 
				
			||||||
	0x7f, 0x30, 0x40, 0x32, 0x2f, 0xff, 0xc9, 0x43, 0x58, 0xed, 0x20, 0x9a, 0x39, 0xe4, 0x70, 0xa6,
 | 
						0x44, 0x22, 0x2b, 0xdf, 0xea, 0x0b, 0x71, 0x16, 0xa7, 0xfa, 0xfa, 0xdf, 0x0a, 0x70, 0xbf, 0x45,
 | 
				
			||||||
	0x1b, 0xc0, 0xc9, 0xc8, 0x2a, 0xcd, 0x42, 0xb9, 0xd0, 0x90, 0x9d, 0x50, 0x24, 0x24, 0x94, 0x74,
 | 
						0x98, 0x3f, 0x4a, 0x9e, 0xb6, 0x03, 0xca, 0xfa, 0xd3, 0x81, 0xc7, 0x6e, 0xfe, 0xca, 0x33, 0xb8,
 | 
				
			||||||
	0x26, 0x45, 0xde, 0xe6, 0x2f, 0x0b, 0xb0, 0x3c, 0xa5, 0xf9, 0x71, 0x07, 0x62, 0xf2, 0x12, 0x81,
 | 
						0x3d, 0x0e, 0x28, 0x73, 0x67, 0x02, 0xce, 0x8d, 0x13, 0xb8, 0x34, 0xad, 0x1a, 0xdb, 0x50, 0xde,
 | 
				
			||||||
	0xb8, 0x0a, 0x49, 0xcf, 0xc7, 0x0f, 0xe5, 0x71, 0x98, 0xa7, 0xc1, 0x84, 0xbc, 0x86, 0x5c, 0x0b,
 | 
						0x6a, 0x48, 0x7d, 0x29, 0x92, 0x12, 0x8c, 0xc6, 0xeb, 0x22, 0x7a, 0xf4, 0xaf, 0x1d, 0x38, 0xd8,
 | 
				
			||||||
	0x3d, 0xc3, 0x77, 0x2d, 0xa7, 0xe7, 0x7b, 0x22, 0xb6, 0x6a, 0x57, 0x40, 0xf9, 0x4e, 0x29, 0x84,
 | 
						0xd0, 0xfc, 0x71, 0x67, 0x61, 0xfe, 0x06, 0x59, 0x78, 0x1b, 0xf2, 0x94, 0x79, 0x8c, 0x88, 0x24,
 | 
				
			||||||
	0xa5, 0xd1, 0x33, 0x36, 0x7f, 0x8d, 0x41, 0x2e, 0xb2, 0x48, 0xfe, 0x01, 0xa4, 0x6b, 0xbd, 0x95,
 | 
						0x2c, 0xe3, 0x64, 0x83, 0xbe, 0x83, 0x92, 0x1f, 0x85, 0x94, 0xc5, 0x5e, 0x10, 0x32, 0x2a, 0x13,
 | 
				
			||||||
	0xb7, 0x2f, 0xd3, 0x2a, 0x23, 0x3e, 0x49, 0x8b, 0xb8, 0x12, 0xc0, 0x8a, 0xc4, 0x49, 0xfe, 0x09,
 | 
						0xcb, 0x79, 0x0f, 0x94, 0xd7, 0x1b, 0x4b, 0x58, 0x9c, 0xbd, 0xe3, 0xe8, 0xdf, 0x0a, 0x94, 0x32,
 | 
				
			||||||
	0xab, 0x4c, 0x9b, 0x45, 0xf1, 0x0b, 0xcb, 0x0b, 0xf5, 0xe3, 0x5c, 0x9f, 0x21, 0x95, 0xc5, 0x92,
 | 
						0x0f, 0xd1, 0xcf, 0x01, 0x4d, 0xbc, 0x37, 0xa9, 0xf7, 0xd3, 0x9a, 0xca, 0x89, 0xcf, 0x63, 0x6d,
 | 
				
			||||||
	0xdc, 0xb1, 0x0e, 0x29, 0xd7, 0x7e, 0xc9, 0x62, 0x9c, 0x7d, 0x79, 0x96, 0x8a, 0x19, 0xf9, 0x1c,
 | 
						0xe2, 0xbd, 0x49, 0x60, 0x65, 0xd5, 0x44, 0xbf, 0x80, 0xdb, 0x5c, 0x9b, 0xa7, 0xf0, 0x2b, 0x8f,
 | 
				
			||||||
	0xd6, 0xbd, 0xe1, 0x60, 0xd0, 0x77, 0x7d, 0xbb, 0x6d, 0xb6, 0xfa, 0xdd, 0x81, 0x6b, 0x7b, 0x1e,
 | 
						0x2e, 0xf5, 0x73, 0x42, 0x9f, 0x23, 0x35, 0xe5, 0xa3, 0xf4, 0xc4, 0x1d, 0x28, 0xc4, 0xe4, 0x9c,
 | 
				
			||||||
	0x2e, 0x5c, 0x58, 0x21, 0x4a, 0xa1, 0x1e, 0xa7, 0x79, 0x6d, 0x04, 0x11, 0x59, 0xf1, 0x94, 0xaf,
 | 
						0x27, 0x38, 0x7f, 0xf3, 0x3d, 0x2c, 0x77, 0xe8, 0xf7, 0x70, 0x87, 0xce, 0xa6, 0xd3, 0x28, 0x66,
 | 
				
			||||||
	0xd3, 0x70, 0xeb, 0x3c, 0xc2, 0x44, 0x28, 0x9e, 0xc1, 0xda, 0xb8, 0xd7, 0x07, 0x72, 0x19, 0x98,
 | 
						0x64, 0xe0, 0xfa, 0xd1, 0x64, 0x1a, 0x13, 0x4a, 0x83, 0x28, 0x7c, 0x6b, 0x7b, 0x68, 0x2c, 0xf5,
 | 
				
			||||||
	0xda, 0xfb, 0xdc, 0x41, 0xb0, 0x75, 0xec, 0x12, 0x02, 0x11, 0x5d, 0xe9, 0x4c, 0xc9, 0x3c, 0x52,
 | 
						0x04, 0xcd, 0x87, 0x0b, 0x88, 0xcc, 0x13, 0xaa, 0xff, 0xb1, 0x08, 0x0f, 0x2e, 0x23, 0x4c, 0xa6,
 | 
				
			||||||
	0x87, 0xb5, 0xae, 0xd3, 0x73, 0xba, 0xc3, 0xae, 0x79, 0x6a, 0x39, 0x7e, 0x98, 0x04, 0xe3, 0x73,
 | 
						0xe2, 0x05, 0x1c, 0xae, 0x46, 0x7d, 0x22, 0x4f, 0x13, 0xd3, 0x7c, 0x17, 0x1f, 0x24, 0x47, 0x57,
 | 
				
			||||||
	0x24, 0xc1, 0x15, 0xb1, 0xf5, 0x10, 0x77, 0x4a, 0xe1, 0xe6, 0xf7, 0x49, 0x20, 0xd3, 0xa7, 0x5f,
 | 
						0x9c, 0x90, 0x88, 0xf0, 0xad, 0xf1, 0x86, 0x8c, 0xa2, 0x53, 0x38, 0x9c, 0x04, 0x61, 0x30, 0x99,
 | 
				
			||||||
	0x3e, 0x98, 0x66, 0x46, 0x41, 0xfc, 0x12, 0x51, 0x30, 0x15, 0x9d, 0x89, 0x0f, 0x8a, 0xce, 0x53,
 | 
						0x4d, 0xdc, 0xb9, 0x17, 0xb0, 0x65, 0x05, 0xcc, 0x5d, 0x55, 0x01, 0x6f, 0xc9, 0x73, 0x67, 0x5e,
 | 
				
			||||||
	0x28, 0xc8, 0x0b, 0x0b, 0x60, 0x16, 0x38, 0x0c, 0xbd, 0x92, 0x4b, 0xdb, 0x91, 0x83, 0xe0, 0x60,
 | 
						0xc0, 0x52, 0xe1, 0xd1, 0x5f, 0xf3, 0x80, 0x36, 0xaf, 0xbe, 0x79, 0x26, 0x6d, 0x4d, 0x81, 0xdc,
 | 
				
			||||||
	0x37, 0x32, 0x23, 0x9f, 0x40, 0xd6, 0x6a, 0xb7, 0x1d, 0x9f, 0xfb, 0x69, 0x92, 0x7b, 0x8a, 0xf2,
 | 
						0x0d, 0x52, 0x60, 0x23, 0x35, 0xd5, 0x1f, 0x94, 0x9a, 0x73, 0xa8, 0xa4, 0xde, 0x4a, 0x60, 0x76,
 | 
				
			||||||
	0x0e, 0x22, 0x1a, 0xb6, 0x4f, 0xc3, 0x4d, 0xe4, 0x7f, 0x90, 0x71, 0xed, 0x6e, 0xff, 0x8d, 0xd5,
 | 
						0x04, 0x0c, 0x7e, 0x2f, 0x1e, 0xab, 0xa7, 0x8b, 0xe4, 0xe2, 0x38, 0xb3, 0x43, 0x5f, 0xc2, 0x9e,
 | 
				
			||||||
	0xf1, 0xb0, 0xb0, 0xcf, 0x0b, 0x30, 0xda, 0x43, 0xee, 0x43, 0xb1, 0x67, 0x9f, 0x9a, 0x41, 0xee,
 | 
						0x37, 0x18, 0x04, 0x4c, 0x04, 0x69, 0x5e, 0x84, 0x89, 0x7e, 0x05, 0x11, 0x5d, 0xc2, 0xf0, 0xf2,
 | 
				
			||||||
	0x36, 0x83, 0x94, 0x92, 0xe6, 0x29, 0x65, 0x11, 0xe5, 0x41, 0x7a, 0x6f, 0xf0, 0xdc, 0xf2, 0x2f,
 | 
						0x10, 0xfa, 0x0d, 0xec, 0xc6, 0x64, 0x12, 0xbd, 0xf6, 0xc6, 0xb4, 0x56, 0xb8, 0x36, 0xc0, 0xe2,
 | 
				
			||||||
	0xc8, 0x60, 0xe5, 0x68, 0xbd, 0xf2, 0x86, 0xdd, 0x8d, 0xcc, 0xf9, 0x9e, 0x55, 0x12, 0x3a, 0x74,
 | 
						0x0c, 0x7a, 0x0c, 0x5a, 0x48, 0xe6, 0x6e, 0x52, 0xb8, 0xdd, 0xa4, 0x9e, 0x14, 0x45, 0x3d, 0xa9,
 | 
				
			||||||
	0xa4, 0xad, 0x50, 0xc8, 0x47, 0x39, 0x20, 0x5b, 0x70, 0x9d, 0x6a, 0x8d, 0x7a, 0xcd, 0x68, 0x68,
 | 
						0x86, 0x64, 0x9e, 0xd4, 0xf6, 0xae, 0x28, 0x2c, 0xbf, 0x84, 0x5d, 0x7f, 0x44, 0xfc, 0x6f, 0xe9,
 | 
				
			||||||
	0x66, 0xf3, 0xa8, 0xae, 0x99, 0x07, 0x46, 0xa3, 0xae, 0x95, 0xf4, 0x8a, 0xae, 0x95, 0x8b, 0x7f,
 | 
						0x6c, 0x52, 0xdb, 0x15, 0x61, 0xf5, 0xe1, 0xd6, 0x7c, 0x92, 0x3a, 0x78, 0xa1, 0xad, 0x63, 0x28,
 | 
				
			||||||
	0x21, 0x04, 0x16, 0xeb, 0x2a, 0x6d, 0xea, 0x6a, 0xd5, 0x3c, 0xa8, 0x97, 0xd5, 0xa6, 0x56, 0x8c,
 | 
						0x67, 0x39, 0x40, 0xf7, 0xe1, 0x1e, 0x36, 0xbb, 0x1d, 0xc7, 0xee, 0x9a, 0x6e, 0xef, 0x65, 0xc7,
 | 
				
			||||||
	0x91, 0x25, 0xc8, 0x55, 0x0e, 0xaa, 0x23, 0x41, 0x5c, 0xf9, 0x29, 0x06, 0x6b, 0xac, 0x30, 0x56,
 | 
						0x74, 0xfb, 0x76, 0xb7, 0x63, 0x36, 0xac, 0x96, 0x65, 0x36, 0xb5, 0x9f, 0x20, 0x04, 0xd5, 0x8e,
 | 
				
			||||||
	0x86, 0x9d, 0xce, 0x9e, 0xe5, 0x5d, 0x41, 0xa9, 0xbe, 0x0b, 0x85, 0x28, 0x0b, 0x41, 0x9b, 0x9a,
 | 
						0x81, 0x7b, 0x96, 0xd1, 0x76, 0xfb, 0x9d, 0xa6, 0xd1, 0x33, 0x35, 0x05, 0xed, 0x43, 0xa9, 0xd5,
 | 
				
			||||||
	0xa7, 0xf9, 0x56, 0xc8, 0x81, 0x37, 0x59, 0xcf, 0x13, 0xef, 0x5d, 0xcf, 0xff, 0x88, 0xc1, 0xfa,
 | 
						0x6f, 0x2f, 0x04, 0x39, 0xfd, 0x1f, 0x0a, 0x1c, 0xf2, 0xae, 0xd8, 0x9a, 0x8d, 0xc7, 0x27, 0x1e,
 | 
				
			||||||
	0xa4, 0xdd, 0x97, 0xae, 0xe6, 0x57, 0x9f, 0x02, 0x48, 0x13, 0xae, 0xf5, 0xec, 0x97, 0x38, 0x7e,
 | 
						0x7d, 0x0f, 0x7d, 0xfa, 0x11, 0x54, 0xb2, 0x2c, 0x24, 0x03, 0x6a, 0x19, 0x97, 0xfd, 0x25, 0x07,
 | 
				
			||||||
	0x63, 0x9b, 0x13, 0xbd, 0x55, 0x62, 0x0e, 0xcc, 0x35, 0xb9, 0xb9, 0x34, 0xd6, 0x63, 0xd5, 0x01,
 | 
						0x74, 0xbd, 0x99, 0xab, 0xef, 0xdc, 0xcc, 0xff, 0xa7, 0xc0, 0x9d, 0x75, 0xbb, 0x6f, 0xdc, 0xca,
 | 
				
			||||||
	0x42, 0xe6, 0xc9, 0x0d, 0xc8, 0x0a, 0xc6, 0x9d, 0x36, 0xbf, 0xac, 0x2c, 0x3a, 0x4d, 0xb0, 0xdc,
 | 
						0xdf, 0x73, 0xfe, 0xa3, 0xaf, 0xe1, 0x6e, 0x48, 0xce, 0x3d, 0x16, 0xbc, 0x26, 0xee, 0xda, 0x48,
 | 
				
			||||||
	0x26, 0xf7, 0xb0, 0xa7, 0x0b, 0x16, 0xdf, 0xd8, 0xae, 0x27, 0xbf, 0x25, 0x4b, 0xc5, 0x25, 0x3d,
 | 
						0xa5, 0x5e, 0x05, 0x78, 0x98, 0x9e, 0x6c, 0xac, 0x8c, 0x56, 0x1d, 0x80, 0x25, 0xe7, 0xe8, 0x03,
 | 
				
			||||||
	0x0b, 0x84, 0x8a, 0x02, 0x19, 0xe9, 0x71, 0xac, 0x34, 0x78, 0x27, 0xd6, 0x83, 0x47, 0x8f, 0x39,
 | 
						0xd8, 0x93, 0x5c, 0x07, 0x03, 0xe1, 0xa6, 0x3d, 0xbc, 0x9b, 0x08, 0xac, 0x01, 0xfa, 0x18, 0xaa,
 | 
				
			||||||
	0x58, 0x9e, 0x8a, 0x99, 0xf2, 0x50, 0x36, 0xe7, 0xdc, 0xff, 0xd1, 0xbf, 0x16, 0x4e, 0x90, 0x79,
 | 
						0xf2, 0xe1, 0x6b, 0x12, 0xd3, 0xf4, 0x2d, 0xf6, 0xb0, 0x74, 0xcf, 0xf3, 0x44, 0xa8, 0xeb, 0xb0,
 | 
				
			||||||
	0xa1, 0xc4, 0xc7, 0xa4, 0x08, 0x89, 0xa1, 0xdb, 0x11, 0x47, 0xb0, 0xa1, 0xf2, 0x7b, 0x1c, 0x16,
 | 
						0x9b, 0xc6, 0x1a, 0xef, 0x08, 0x74, 0xe4, 0x3d, 0xfd, 0xec, 0x73, 0x01, 0x56, 0xc6, 0x72, 0xa7,
 | 
				
			||||||
	0xc7, 0xa3, 0x86, 0x18, 0x50, 0x8c, 0x14, 0x96, 0x68, 0x12, 0x9c, 0xab, 0xb8, 0x2c, 0xb5, 0xc6,
 | 
						0x7f, 0x9a, 0x0e, 0xe4, 0x22, 0xf2, 0x11, 0x82, 0x9d, 0x91, 0x47, 0x47, 0x52, 0x49, 0xac, 0x91,
 | 
				
			||||||
	0x05, 0xe4, 0xbf, 0x00, 0xae, 0x75, 0x6a, 0x9e, 0x70, 0x37, 0x10, 0x57, 0xb5, 0x35, 0x0b, 0x89,
 | 
						0x06, 0xea, 0x2c, 0x1e, 0xcb, 0x2b, 0xf8, 0x52, 0xff, 0x6f, 0x0e, 0xaa, 0xab, 0xf9, 0x82, 0x6c,
 | 
				
			||||||
	0x5a, 0xa7, 0xc2, 0x57, 0xb2, 0xae, 0x1c, 0x32, 0x57, 0x64, 0xbb, 0xd1, 0x97, 0x9c, 0x16, 0x7f,
 | 
						0xd0, 0x32, 0xfd, 0x24, 0x5b, 0xfe, 0xae, 0xd5, 0x53, 0xf6, 0xfd, 0x55, 0x01, 0xfa, 0x35, 0x40,
 | 
				
			||||||
	0xb8, 0x9c, 0xeb, 0x8a, 0xb8, 0x5d, 0x0f, 0xb4, 0x28, 0x3b, 0x50, 0x8c, 0xf1, 0xf1, 0x93, 0x73,
 | 
						0xec, 0xcd, 0xdd, 0x91, 0x08, 0x00, 0xe9, 0xa4, 0xfb, 0xdb, 0x90, 0xb0, 0x37, 0x97, 0x51, 0xb2,
 | 
				
			||||||
	0x71, 0x20, 0xcf, 0x0f, 0x9a, 0x85, 0x7b, 0x33, 0x01, 0x50, 0xad, 0x6c, 0x77, 0x7c, 0x4b, 0xeb,
 | 
						0x17, 0xa7, 0x4b, 0x1e, 0x84, 0xfc, 0x74, 0x10, 0x0e, 0x02, 0x5f, 0x7c, 0xac, 0x5c, 0x1a, 0x84,
 | 
				
			||||||
	0xb5, 0xfa, 0x6d, 0x94, 0x23, 0x0e, 0x8a, 0x84, 0x21, 0x7b, 0x90, 0xe7, 0x38, 0xd2, 0x92, 0xe4,
 | 
						0xd8, 0x9b, 0x5b, 0x89, 0x16, 0xe6, 0x17, 0xca, 0x35, 0x6a, 0x41, 0x29, 0x0e, 0x7c, 0x92, 0xde,
 | 
				
			||||||
	0xfb, 0x00, 0x71, 0x13, 0x84, 0x45, 0xca, 0xdf, 0x00, 0x42, 0x5b, 0xc9, 0x06, 0xa4, 0x25, 0x24,
 | 
						0x9f, 0xcc, 0x08, 0x1f, 0x6f, 0x05, 0x08, 0x7c, 0xd2, 0x24, 0x63, 0xe6, 0x99, 0xa1, 0x1f, 0x0d,
 | 
				
			||||||
	0x8b, 0x87, 0x24, 0x95, 0x53, 0xe5, 0x29, 0x64, 0x47, 0x94, 0x90, 0xdb, 0x90, 0x43, 0x56, 0x8f,
 | 
						0x82, 0xf0, 0x1c, 0x03, 0x3f, 0x29, 0x0d, 0x39, 0x81, 0xb2, 0xc0, 0x49, 0x2d, 0xc9, 0xbf, 0x0b,
 | 
				
			||||||
	0x9d, 0xb7, 0xa6, 0xe7, 0x7c, 0x69, 0x8b, 0x4e, 0x03, 0x02, 0x51, 0x03, 0x25, 0x98, 0x6e, 0x26,
 | 
						0x90, 0x30, 0x41, 0x5a, 0xa4, 0xff, 0x14, 0x60, 0x69, 0x2b, 0xaa, 0x41, 0x31, 0x85, 0xe4, 0x99,
 | 
				
			||||||
	0x69, 0xce, 0x47, 0x78, 0x54, 0xbe, 0x8b, 0xc1, 0xf2, 0x94, 0x5d, 0x0c, 0xf5, 0xd8, 0x71, 0xb1,
 | 
						0x90, 0xc7, 0xe9, 0x56, 0xff, 0x0a, 0xf6, 0x16, 0x94, 0xa0, 0x87, 0x50, 0x9a, 0xc6, 0x64, 0x18,
 | 
				
			||||||
	0xa0, 0x63, 0x96, 0x1c, 0x06, 0xa8, 0x09, 0x0a, 0x5c, 0xf4, 0x8c, 0x49, 0x98, 0x7f, 0xf2, 0xaf,
 | 
						0xbc, 0x71, 0x69, 0xf0, 0x3d, 0x91, 0x03, 0x06, 0x24, 0xa2, 0x6e, 0xf0, 0x3d, 0x2f, 0x34, 0xeb,
 | 
				
			||||||
	0x1e, 0x58, 0xae, 0x85, 0x8f, 0x19, 0xdb, 0x15, 0x3d, 0x4b, 0x81, 0x49, 0xeb, 0x52, 0xc8, 0x70,
 | 
						0x34, 0x97, 0x33, 0x3c, 0xea, 0x7f, 0x51, 0xe0, 0x60, 0xc3, 0x2e, 0x8e, 0x3a, 0x0c, 0x62, 0xca,
 | 
				
			||||||
	0x7a, 0x18, 0x95, 0xe1, 0xf3, 0x92, 0x5b, 0x87, 0x22, 0xd9, 0xcf, 0xfc, 0x15, 0xf2, 0x36, 0x3b,
 | 
						0xdc, 0xd7, 0xde, 0x78, 0x96, 0xa0, 0xaa, 0x18, 0x84, 0xe8, 0x39, 0x97, 0xf0, 0xf8, 0x14, 0x6f,
 | 
				
			||||||
	0x14, 0xbb, 0x96, 0xd1, 0x7b, 0x28, 0x4f, 0x73, 0x42, 0xc6, 0xba, 0x1f, 0x66, 0xe1, 0xca, 0x8c,
 | 
						0x3d, 0xf5, 0x62, 0x6f, 0x42, 0x18, 0x89, 0xe5, 0xa8, 0x52, 0xe1, 0xd2, 0x4e, 0x2a, 0xe4, 0x38,
 | 
				
			||||||
	0xb7, 0x10, 0x96, 0xd3, 0x74, 0xd8, 0x5f, 0xb1, 0x84, 0xf1, 0x68, 0xce, 0x57, 0xd4, 0x8e, 0x1c,
 | 
						0xe1, 0x6c, 0x92, 0xf9, 0xa4, 0x14, 0xd6, 0x85, 0xb3, 0x49, 0x3a, 0xc6, 0x7c, 0x04, 0x65, 0xc2,
 | 
				
			||||||
	0x04, 0x6f, 0x34, 0x89, 0xb2, 0xf9, 0x04, 0x0a, 0x63, 0x2b, 0x2c, 0x2c, 0x5e, 0xd9, 0x67, 0x22,
 | 
						0x2f, 0x25, 0x03, 0x77, 0xf1, 0x0d, 0x54, 0xc6, 0x25, 0x29, 0xe3, 0x43, 0x0f, 0xb7, 0xf0, 0xd6,
 | 
				
			||||||
	0x52, 0xd8, 0x90, 0xf5, 0x9d, 0x01, 0x23, 0x01, 0x8f, 0xc1, 0x44, 0xf9, 0x2d, 0x06, 0xab, 0x61,
 | 
						0x96, 0xef, 0x1f, 0xe4, 0x40, 0x71, 0x39, 0x56, 0xf1, 0x52, 0xf1, 0xd9, 0x35, 0xbf, 0x9c, 0xea,
 | 
				
			||||||
	0x4d, 0x2c, 0xdb, 0x5e, 0xcb, 0x75, 0x06, 0x7e, 0xdf, 0xfd, 0xb8, 0xfb, 0xef, 0xc4, 0x87, 0x77,
 | 
						0xe9, 0x22, 0xf9, 0x2e, 0x4b, 0x51, 0x8e, 0xbe, 0x80, 0xca, 0xca, 0x13, 0x9e, 0x16, 0xdf, 0x92,
 | 
				
			||||||
	0x1e, 0xca, 0x31, 0x5c, 0x63, 0x9f, 0x1a, 0x7e, 0x74, 0x98, 0xc7, 0x9f, 0x8e, 0xfe, 0x99, 0xb0,
 | 
						0x0b, 0x99, 0x29, 0x7c, 0xc9, 0xc7, 0xcd, 0x84, 0x91, 0x84, 0xc7, 0x64, 0xa3, 0xff, 0x47, 0x81,
 | 
				
			||||||
	0x6e, 0x4d, 0xde, 0xcd, 0xfd, 0xf3, 0x8f, 0x19, 0xe7, 0x4c, 0xfe, 0x3d, 0xe1, 0xa0, 0xca, 0x7f,
 | 
						0xdb, 0xcb, 0x6e, 0xd8, 0x24, 0xd4, 0x8f, 0x83, 0x29, 0x8b, 0xe2, 0x1f, 0xf7, 0xd8, 0xad, 0xfe,
 | 
				
			||||||
	0x20, 0x33, 0xca, 0xc9, 0x18, 0x10, 0x9e, 0x8d, 0xbd, 0x77, 0xdb, 0x13, 0xfe, 0x28, 0xa7, 0xec,
 | 
						0xf0, 0x99, 0x43, 0x1f, 0xc2, 0x5d, 0xfe, 0xaa, 0xcb, 0x97, 0x5e, 0x56, 0xf0, 0xaf, 0x16, 0xff,
 | 
				
			||||||
	0x56, 0x7a, 0x56, 0xaf, 0x2f, 0xfb, 0xe6, 0x60, 0xb2, 0xfd, 0x55, 0x4c, 0xfe, 0xcb, 0xe1, 0x1c,
 | 
						0x49, 0xf8, 0x90, 0x96, 0xfa, 0xe6, 0xf1, 0xe5, 0xd7, 0xac, 0x72, 0x96, 0xfe, 0x31, 0x11, 0xa0,
 | 
				
			||||||
	0xdc, 0x80, 0x6b, 0xcd, 0x3d, 0xaa, 0xa9, 0xcd, 0x59, 0x45, 0x37, 0x07, 0xe9, 0x7d, 0xb5, 0x7a,
 | 
						0x4f, 0xfe, 0xa0, 0xa4, 0xff, 0x60, 0xc4, 0x7b, 0x7c, 0x00, 0x77, 0x7b, 0x27, 0xd8, 0x34, 0x7a,
 | 
				
			||||||
	0xa8, 0x52, 0x56, 0x6d, 0xd7, 0x81, 0x34, 0x6a, 0x25, 0x56, 0x80, 0x35, 0x63, 0x57, 0x37, 0x34,
 | 
						0xdb, 0x5a, 0x66, 0x09, 0x8a, 0xa7, 0x46, 0xfb, 0xcc, 0xc0, 0xbc, 0x57, 0xde, 0x01, 0xd4, 0x75,
 | 
				
			||||||
	0x8d, 0xea, 0xc6, 0x6e, 0x31, 0x4e, 0xd6, 0x60, 0xf9, 0xc0, 0x38, 0x54, 0x8d, 0xa6, 0x56, 0x36,
 | 
						0x1a, 0xbc, 0x7d, 0x9a, 0xf6, 0x33, 0xcb, 0x36, 0x4d, 0x6c, 0xd9, 0xcf, 0xb4, 0x1c, 0x3a, 0x84,
 | 
				
			||||||
	0x1b, 0xb5, 0x4a, 0x93, 0xab, 0x27, 0xb0, 0x72, 0xde, 0xae, 0xd7, 0x9a, 0x9a, 0xc1, 0x4a, 0x76,
 | 
						0x83, 0xbe, 0x7d, 0x66, 0xd8, 0x3d, 0xb3, 0xe9, 0x76, 0x9d, 0x56, 0x4f, 0xa8, 0xab, 0xe8, 0x11,
 | 
				
			||||||
	0xf5, 0xc8, 0xdc, 0x53, 0xe9, 0x3e, 0x16, 0x6b, 0x53, 0xad, 0xd7, 0xab, 0x7a, 0x49, 0x6d, 0xea,
 | 
						0x3c, 0xec, 0x38, 0x3d, 0xd3, 0xe6, 0x0d, 0xb7, 0xfd, 0xd2, 0x3d, 0x31, 0xf0, 0x69, 0xab, 0xdf,
 | 
				
			||||||
	0x35, 0xa3, 0xb8, 0xb0, 0xfd, 0x6d, 0x0c, 0xf2, 0xd1, 0x0b, 0x62, 0x5d, 0x40, 0xbd, 0xaa, 0x36,
 | 
						0x76, 0x8d, 0x4e, 0xa7, 0x6d, 0x35, 0x8c, 0x9e, 0xe5, 0xd8, 0xda, 0xce, 0x93, 0x3f, 0x2b, 0x50,
 | 
				
			||||||
	0x2b, 0x35, 0xba, 0x7f, 0x8e, 0x41, 0x87, 0xba, 0x51, 0xae, 0x1d, 0x36, 0xd0, 0xa0, 0x2c, 0x24,
 | 
						0xce, 0x92, 0xcc, 0x7b, 0x78, 0xa7, 0x6d, 0xf4, 0x5a, 0x0e, 0x3e, 0xbd, 0xc4, 0xa0, 0x33, 0xcb,
 | 
				
			||||||
	0xab, 0xba, 0x71, 0xf0, 0x1c, 0x6d, 0x40, 0xb9, 0x6a, 0x94, 0x69, 0x4d, 0x2f, 0xe3, 0xc9, 0x69,
 | 
						0x6e, 0x3a, 0x67, 0x5d, 0x4d, 0x41, 0x7b, 0x90, 0x6f, 0x5b, 0x76, 0xff, 0x85, 0x96, 0xe3, 0x72,
 | 
				
			||||||
	0x48, 0xd4, 0x1a, 0xcf, 0x8b, 0x0b, 0x6c, 0xa0, 0xd7, 0x1a, 0xc5, 0x24, 0x7a, 0x6c, 0x5e, 0x35,
 | 
						0xc3, 0x6e, 0x62, 0xc7, 0x6a, 0x6a, 0x2a, 0x2a, 0x82, 0xea, 0x74, 0x5f, 0x68, 0x3b, 0x7c, 0x61,
 | 
				
			||||||
	0x8e, 0x4c, 0x89, 0x5c, 0x4c, 0x91, 0x65, 0x28, 0xa0, 0x59, 0x23, 0x49, 0xa3, 0x98, 0x26, 0x00,
 | 
						0x39, 0x5d, 0x2d, 0x8f, 0x34, 0x28, 0x1b, 0xf6, 0x4b, 0x37, 0x45, 0xd6, 0x0a, 0xe8, 0x00, 0x2a,
 | 
				
			||||||
	0xa9, 0xd2, 0x1e, 0xad, 0xed, 0x6b, 0xc5, 0xcc, 0x76, 0x05, 0x96, 0x26, 0x12, 0x35, 0xb9, 0x03,
 | 
						0x46, 0xbb, 0xbd, 0x90, 0x74, 0xb5, 0x22, 0x02, 0x28, 0x34, 0x4e, 0xb0, 0x73, 0x6a, 0x6a, 0xbb,
 | 
				
			||||||
	0x37, 0x4b, 0xb5, 0xfd, 0x3a, 0xf6, 0x28, 0x0d, 0xb4, 0x7d, 0x96, 0x71, 0x78, 0x1c, 0x55, 0x0f,
 | 
						0x4f, 0x5a, 0xb0, 0xbf, 0x56, 0x6c, 0xd1, 0x31, 0x7c, 0xd8, 0x70, 0x4e, 0x3b, 0xd8, 0xec, 0x76,
 | 
				
			||||||
	0xd1, 0xb0, 0x0c, 0x2c, 0x50, 0xbd, 0x84, 0x0d, 0xc9, 0xb6, 0x03, 0x4b, 0x13, 0x4e, 0x83, 0xa1,
 | 
						0x2d, 0xc7, 0xde, 0x66, 0x5c, 0x11, 0x54, 0x6c, 0x9c, 0x69, 0x0a, 0xda, 0x85, 0x1d, 0x6c, 0x35,
 | 
				
			||||||
	0xbd, 0x25, 0x08, 0x47, 0x6e, 0xe8, 0xd1, 0x39, 0xbd, 0xce, 0x01, 0x45, 0x9a, 0x9f, 0xcb, 0xd3,
 | 
						0x4c, 0x2d, 0xf7, 0xe4, 0x1b, 0xd8, 0x5f, 0x73, 0x3c, 0xfa, 0x08, 0xee, 0x4b, 0xc2, 0x4d, 0xbb,
 | 
				
			||||||
	0x10, 0x13, 0x0d, 0xfe, 0x54, 0x37, 0x54, 0xdc, 0x50, 0xd6, 0x77, 0xb5, 0x46, 0x13, 0x3f, 0x3a,
 | 
						0x87, 0x5f, 0x5e, 0x02, 0xd4, 0xc7, 0x6d, 0x4d, 0x41, 0x55, 0x00, 0xf3, 0x85, 0xd9, 0xe8, 0xf7,
 | 
				
			||||||
	0x0f, 0x19, 0xbd, 0x6e, 0x52, 0xd5, 0xd8, 0x45, 0xbe, 0x5f, 0xa4, 0xb8, 0xf3, 0x3c, 0xfc, 0x33,
 | 
						0x8c, 0xdf, 0xb5, 0x4d, 0x2d, 0x87, 0xca, 0xb0, 0x6b, 0x75, 0x5c, 0x6c, 0xd8, 0xcf, 0x4c, 0x4d,
 | 
				
			||||||
	0x00, 0x00, 0xff, 0xff, 0x08, 0xe3, 0x60, 0x1f, 0xd4, 0x13, 0x00, 0x00,
 | 
						0x7d, 0x55, 0x10, 0x2e, 0xff, 0xf4, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x68, 0x6b, 0x92, 0x80,
 | 
				
			||||||
 | 
						0x9e, 0x13, 0x00, 0x00,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								vendor/github.com/google/safebrowsing/internal/safebrowsing_proto/safebrowsing.proto
								
								
									generated
								
								
									vendored
								
								
							
							
						
						
									
										31
									
								
								vendor/github.com/google/safebrowsing/internal/safebrowsing_proto/safebrowsing.proto
								
								
									generated
								
								
									vendored
								
								
							| 
						 | 
					@ -14,6 +14,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
syntax = "proto3";
 | 
					syntax = "proto3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "google/protobuf/duration.proto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package safebrowsing_proto;
 | 
					package safebrowsing_proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The Safe Browsing APIs enable clients to check web resources (most commonly
 | 
					// The Safe Browsing APIs enable clients to check web resources (most commonly
 | 
				
			||||||
| 
						 | 
					@ -81,7 +83,7 @@ message ThreatMatch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The cache lifetime for the returned match. Clients must not cache this
 | 
					  // The cache lifetime for the returned match. Clients must not cache this
 | 
				
			||||||
  // response for more than this duration to avoid false positives.
 | 
					  // response for more than this duration to avoid false positives.
 | 
				
			||||||
  Duration cache_duration = 5;
 | 
					  google.protobuf.Duration cache_duration = 5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Request to check entries against lists.
 | 
					// Request to check entries against lists.
 | 
				
			||||||
| 
						 | 
					@ -208,7 +210,7 @@ message FetchThreatListUpdatesResponse {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The minimum duration the client must wait before issuing any update
 | 
					  // The minimum duration the client must wait before issuing any update
 | 
				
			||||||
  // request. If this field is not set clients may update as soon as they want.
 | 
					  // request. If this field is not set clients may update as soon as they want.
 | 
				
			||||||
  Duration minimum_wait_duration = 2;
 | 
					  google.protobuf.Duration minimum_wait_duration = 2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Request to return full hashes matched by the provided hash prefixes.
 | 
					// Request to return full hashes matched by the provided hash prefixes.
 | 
				
			||||||
| 
						 | 
					@ -231,11 +233,11 @@ message FindFullHashesResponse {
 | 
				
			||||||
  // The minimum duration the client must wait before issuing any find hashes
 | 
					  // The minimum duration the client must wait before issuing any find hashes
 | 
				
			||||||
  // request. If this field is not set, clients can issue a request as soon as
 | 
					  // request. If this field is not set, clients can issue a request as soon as
 | 
				
			||||||
  // they want.
 | 
					  // they want.
 | 
				
			||||||
  Duration minimum_wait_duration = 2;
 | 
					  google.protobuf.Duration minimum_wait_duration = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // For requested entities that did not match the threat list, how long to
 | 
					  // For requested entities that did not match the threat list, how long to
 | 
				
			||||||
  // cache the response.
 | 
					  // cache the response.
 | 
				
			||||||
  Duration negative_cache_duration = 3;
 | 
					  google.protobuf.Duration negative_cache_duration = 3;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,24 +446,3 @@ message ListThreatListsResponse {
 | 
				
			||||||
  // The lists available for download by the client.
 | 
					  // The lists available for download by the client.
 | 
				
			||||||
  repeated ThreatListDescriptor threat_lists = 1;
 | 
					  repeated ThreatListDescriptor threat_lists = 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// A Duration represents a signed, fixed-length span of time represented
 | 
					 | 
				
			||||||
// as a count of seconds and fractions of seconds at nanosecond
 | 
					 | 
				
			||||||
// resolution. It is independent of any calendar and concepts like "day"
 | 
					 | 
				
			||||||
// or "month". It is related to Timestamp in that the difference between
 | 
					 | 
				
			||||||
// two Timestamp values is a Duration and it can be added or subtracted
 | 
					 | 
				
			||||||
// from a Timestamp. Range is approximately +-10,000 years.
 | 
					 | 
				
			||||||
message Duration {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Signed seconds of the span of time. Must be from -315,576,000,000
 | 
					 | 
				
			||||||
  // to +315,576,000,000 inclusive.
 | 
					 | 
				
			||||||
  int64 seconds = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Signed fractions of a second at nanosecond resolution of the span
 | 
					 | 
				
			||||||
  // of time. Durations less than one second are represented with a 0
 | 
					 | 
				
			||||||
  // `seconds` field and a positive or negative `nanos` field. For durations
 | 
					 | 
				
			||||||
  // of one second or more, a non-zero value for the `nanos` field must be
 | 
					 | 
				
			||||||
  // of the same sign as the `seconds` field. Must be from -999,999,999
 | 
					 | 
				
			||||||
  // to +999,999,999 inclusive.
 | 
					 | 
				
			||||||
  int32 nanos = 2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,7 @@
 | 
				
			||||||
package safebrowsing
 | 
					package safebrowsing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
| 
						 | 
					@ -94,6 +95,10 @@ const (
 | 
				
			||||||
	// strings to send with every API call.
 | 
						// strings to send with every API call.
 | 
				
			||||||
	DefaultID      = "GoSafeBrowser"
 | 
						DefaultID      = "GoSafeBrowser"
 | 
				
			||||||
	DefaultVersion = "1.0.0"
 | 
						DefaultVersion = "1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// DefaultRequestTimeout is the default amount of time a single
 | 
				
			||||||
 | 
						// api request can take.
 | 
				
			||||||
 | 
						DefaultRequestTimeout = time.Minute
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Errors specific to this package.
 | 
					// Errors specific to this package.
 | 
				
			||||||
| 
						 | 
					@ -207,6 +212,9 @@ type Config struct {
 | 
				
			||||||
	// If empty, it defaults to DefaultThreatLists.
 | 
						// If empty, it defaults to DefaultThreatLists.
 | 
				
			||||||
	ThreatLists []ThreatDescriptor
 | 
						ThreatLists []ThreatDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RequestTimeout determines the timeout value for the http client.
 | 
				
			||||||
 | 
						RequestTimeout time.Duration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Logger is an io.Writer that allows SafeBrowser to write debug information
 | 
						// Logger is an io.Writer that allows SafeBrowser to write debug information
 | 
				
			||||||
	// intended for human consumption.
 | 
						// intended for human consumption.
 | 
				
			||||||
	// If empty, no logs will be written.
 | 
						// If empty, no logs will be written.
 | 
				
			||||||
| 
						 | 
					@ -231,6 +239,9 @@ func (c *Config) setDefaults() bool {
 | 
				
			||||||
	if c.UpdatePeriod <= 0 {
 | 
						if c.UpdatePeriod <= 0 {
 | 
				
			||||||
		c.UpdatePeriod = DefaultUpdatePeriod
 | 
							c.UpdatePeriod = DefaultUpdatePeriod
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if c.RequestTimeout <= 0 {
 | 
				
			||||||
 | 
							c.RequestTimeout = DefaultRequestTimeout
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if c.compressionTypes == nil {
 | 
						if c.compressionTypes == nil {
 | 
				
			||||||
		c.compressionTypes = []pb.CompressionType{pb.CompressionType_RAW, pb.CompressionType_RICE}
 | 
							c.compressionTypes = []pb.CompressionType{pb.CompressionType_RAW, pb.CompressionType_RICE}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -251,8 +262,8 @@ func (c Config) copy() Config {
 | 
				
			||||||
// local database and caching that would normally be needed to interact
 | 
					// local database and caching that would normally be needed to interact
 | 
				
			||||||
// with the API server.
 | 
					// with the API server.
 | 
				
			||||||
type SafeBrowser struct {
 | 
					type SafeBrowser struct {
 | 
				
			||||||
 | 
						stats  Stats // Must be first for 64-bit alignment on non 64-bit systems.
 | 
				
			||||||
	config Config
 | 
						config Config
 | 
				
			||||||
	stats  Stats
 | 
					 | 
				
			||||||
	api    api
 | 
						api    api
 | 
				
			||||||
	db     database
 | 
						db     database
 | 
				
			||||||
	c      cache
 | 
						c      cache
 | 
				
			||||||
| 
						 | 
					@ -271,6 +282,7 @@ type Stats struct {
 | 
				
			||||||
	QueriesByCache    int64         // Number of queries satisfied by the cache alone
 | 
						QueriesByCache    int64         // Number of queries satisfied by the cache alone
 | 
				
			||||||
	QueriesByAPI      int64         // Number of queries satisfied by an API call
 | 
						QueriesByAPI      int64         // Number of queries satisfied by an API call
 | 
				
			||||||
	QueriesFail       int64         // Number of queries that could not be satisfied
 | 
						QueriesFail       int64         // Number of queries that could not be satisfied
 | 
				
			||||||
 | 
						DatabaseUpdateLag time.Duration // Duration since last *missed* update. 0 if next update is in the future.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewSafeBrowser creates a new SafeBrowser.
 | 
					// NewSafeBrowser creates a new SafeBrowser.
 | 
				
			||||||
| 
						 | 
					@ -286,7 +298,7 @@ func NewSafeBrowser(conf Config) (*SafeBrowser, error) {
 | 
				
			||||||
	// Create the SafeBrowsing object.
 | 
						// Create the SafeBrowsing object.
 | 
				
			||||||
	if conf.api == nil {
 | 
						if conf.api == nil {
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		conf.api, err = newNetAPI(conf.ServerURL, conf.APIKey)
 | 
							conf.api, err = newNetAPI(conf.ServerURL, conf.APIKey, conf.RequestTimeout)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -316,14 +328,19 @@ func NewSafeBrowser(conf Config) (*SafeBrowser, error) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sb.log = log.New(w, "safebrowsing: ", log.Ldate|log.Ltime|log.Lshortfile)
 | 
						sb.log = log.New(w, "safebrowsing: ", log.Ldate|log.Ltime|log.Lshortfile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delay := time.Duration(0)
 | 
				
			||||||
	// If database file is provided, use that to initialize.
 | 
						// If database file is provided, use that to initialize.
 | 
				
			||||||
	if !sb.db.Init(&sb.config, sb.log) {
 | 
						if !sb.db.Init(&sb.config, sb.log) {
 | 
				
			||||||
		sb.db.Update(sb.api)
 | 
							delay, _ = sb.db.Update(sb.api)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if age := sb.db.SinceLastUpdate(); age < sb.config.UpdatePeriod {
 | 
				
			||||||
 | 
								delay = sb.config.UpdatePeriod - age
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Start the background list updater.
 | 
						// Start the background list updater.
 | 
				
			||||||
	sb.done = make(chan bool)
 | 
						sb.done = make(chan bool)
 | 
				
			||||||
	go sb.updater(conf.UpdatePeriod)
 | 
						go sb.updater(delay)
 | 
				
			||||||
	return sb, nil
 | 
						return sb, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -337,10 +354,28 @@ func (sb *SafeBrowser) Status() (Stats, error) {
 | 
				
			||||||
		QueriesByCache:    atomic.LoadInt64(&sb.stats.QueriesByCache),
 | 
							QueriesByCache:    atomic.LoadInt64(&sb.stats.QueriesByCache),
 | 
				
			||||||
		QueriesByAPI:      atomic.LoadInt64(&sb.stats.QueriesByAPI),
 | 
							QueriesByAPI:      atomic.LoadInt64(&sb.stats.QueriesByAPI),
 | 
				
			||||||
		QueriesFail:       atomic.LoadInt64(&sb.stats.QueriesFail),
 | 
							QueriesFail:       atomic.LoadInt64(&sb.stats.QueriesFail),
 | 
				
			||||||
 | 
							DatabaseUpdateLag: sb.db.UpdateLag(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return stats, sb.db.Status()
 | 
						return stats, sb.db.Status()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WaitUntilReady blocks until the database is not in an error state.
 | 
				
			||||||
 | 
					// Returns nil when the database is ready. Returns an error if the provided
 | 
				
			||||||
 | 
					// context is canceled or if the SafeBrowser instance is Closed.
 | 
				
			||||||
 | 
					func (sb *SafeBrowser) WaitUntilReady(ctx context.Context) error {
 | 
				
			||||||
 | 
						if atomic.LoadUint32(&sb.closed) == 1 {
 | 
				
			||||||
 | 
							return errClosed
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
						case <-sb.db.Ready():
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						case <-ctx.Done():
 | 
				
			||||||
 | 
							return ctx.Err()
 | 
				
			||||||
 | 
						case <-sb.done:
 | 
				
			||||||
 | 
							return errClosed
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LookupURLs looks up the provided URLs. It returns a list of threats, one for
 | 
					// LookupURLs looks up the provided URLs. It returns a list of threats, one for
 | 
				
			||||||
// every URL requested, and an error if any occurred. It is safe to call this
 | 
					// every URL requested, and an error if any occurred. It is safe to call this
 | 
				
			||||||
// method concurrently.
 | 
					// method concurrently.
 | 
				
			||||||
| 
						 | 
					@ -492,16 +527,17 @@ func (sb *SafeBrowser) LookupURLs(urls []string) (threats [][]URLThreat, err err
 | 
				
			||||||
// updater is a blocking method that periodically updates the local database.
 | 
					// updater is a blocking method that periodically updates the local database.
 | 
				
			||||||
// This should be run as a separate goroutine and will be automatically stopped
 | 
					// This should be run as a separate goroutine and will be automatically stopped
 | 
				
			||||||
// when sb.Close is called.
 | 
					// when sb.Close is called.
 | 
				
			||||||
func (sb *SafeBrowser) updater(period time.Duration) {
 | 
					func (sb *SafeBrowser) updater(delay time.Duration) {
 | 
				
			||||||
	ticker := time.NewTicker(period)
 | 
					 | 
				
			||||||
	defer ticker.Stop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
 | 
							sb.log.Printf("Next update in %v", delay)
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-ticker.C:
 | 
							case <-time.After(delay):
 | 
				
			||||||
			sb.log.Printf("background threat list update")
 | 
								var ok bool
 | 
				
			||||||
 | 
								if delay, ok = sb.db.Update(sb.api); ok {
 | 
				
			||||||
 | 
									sb.log.Printf("background threat list updated")
 | 
				
			||||||
				sb.c.Purge()
 | 
									sb.c.Purge()
 | 
				
			||||||
			sb.db.Update(sb.api)
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case <-sb.done:
 | 
							case <-sb.done:
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -426,13 +426,9 @@ func generateLookupHosts(urlStr string) ([]string, error) {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// handle IPv4 and IPv6 addresses.
 | 
						// handle IPv4 and IPv6 addresses.
 | 
				
			||||||
	u, err := url.Parse(urlStr)
 | 
						ip := net.ParseIP(strings.Trim(host, "[]"))
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ip := net.ParseIP(strings.Trim(u.Host, "[]"))
 | 
					 | 
				
			||||||
	if ip != nil {
 | 
						if ip != nil {
 | 
				
			||||||
		return []string{u.Host}, nil
 | 
							return []string{host}, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	hostComponents := strings.Split(host, ".")
 | 
						hostComponents := strings.Split(host, ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue