internal/iana: follow the move of TOS/TC registry

The registry for IPv4 TOS Byte and IPv6 Traffic Class Octet has been
moved to DSCP registry.

Also uses HTTPS for fetching any IANA resource.

Change-Id: I6a54defc2be4415fac084fcf9dfe0a481d72df33
Reviewed-on: https://go-review.googlesource.com/115220
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/internal/iana/const.go b/internal/iana/const.go
index 826633e..cea712f 100644
--- a/internal/iana/const.go
+++ b/internal/iana/const.go
@@ -4,38 +4,34 @@
 // Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
 package iana // import "golang.org/x/net/internal/iana"
 
-// Differentiated Services Field Codepoints (DSCP), Updated: 2017-05-12
+// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04
 const (
-	DiffServCS0        = 0x0  // CS0
-	DiffServCS1        = 0x20 // CS1
-	DiffServCS2        = 0x40 // CS2
-	DiffServCS3        = 0x60 // CS3
-	DiffServCS4        = 0x80 // CS4
-	DiffServCS5        = 0xa0 // CS5
-	DiffServCS6        = 0xc0 // CS6
-	DiffServCS7        = 0xe0 // CS7
-	DiffServAF11       = 0x28 // AF11
-	DiffServAF12       = 0x30 // AF12
-	DiffServAF13       = 0x38 // AF13
-	DiffServAF21       = 0x48 // AF21
-	DiffServAF22       = 0x50 // AF22
-	DiffServAF23       = 0x58 // AF23
-	DiffServAF31       = 0x68 // AF31
-	DiffServAF32       = 0x70 // AF32
-	DiffServAF33       = 0x78 // AF33
-	DiffServAF41       = 0x88 // AF41
-	DiffServAF42       = 0x90 // AF42
-	DiffServAF43       = 0x98 // AF43
-	DiffServEF         = 0xb8 // EF
-	DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
-)
-
-// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
-const (
-	NotECNTransport       = 0x0 // Not-ECT (Not ECN-Capable Transport)
-	ECNTransport1         = 0x1 // ECT(1) (ECN-Capable Transport(1))
-	ECNTransport0         = 0x2 // ECT(0) (ECN-Capable Transport(0))
-	CongestionExperienced = 0x3 // CE (Congestion Experienced)
+	DiffServCS0           = 0x00 // CS0
+	DiffServCS1           = 0x20 // CS1
+	DiffServCS2           = 0x40 // CS2
+	DiffServCS3           = 0x60 // CS3
+	DiffServCS4           = 0x80 // CS4
+	DiffServCS5           = 0xa0 // CS5
+	DiffServCS6           = 0xc0 // CS6
+	DiffServCS7           = 0xe0 // CS7
+	DiffServAF11          = 0x28 // AF11
+	DiffServAF12          = 0x30 // AF12
+	DiffServAF13          = 0x38 // AF13
+	DiffServAF21          = 0x48 // AF21
+	DiffServAF22          = 0x50 // AF22
+	DiffServAF23          = 0x58 // AF23
+	DiffServAF31          = 0x68 // AF31
+	DiffServAF32          = 0x70 // AF32
+	DiffServAF33          = 0x78 // AF33
+	DiffServAF41          = 0x88 // AF41
+	DiffServAF42          = 0x90 // AF42
+	DiffServAF43          = 0x98 // AF43
+	DiffServEF            = 0xb8 // EF
+	DiffServVOICEADMIT    = 0xb0 // VOICE-ADMIT
+	NotECNTransport       = 0x00 // Not-ECT (Not ECN-Capable Transport)
+	ECNTransport1         = 0x01 // ECT(1) (ECN-Capable Transport(1))
+	ECNTransport0         = 0x02 // ECT(0) (ECN-Capable Transport(0))
+	CongestionExperienced = 0x03 // CE (Congestion Experienced)
 )
 
 // Protocol Numbers, Updated: 2017-10-13
@@ -179,7 +175,7 @@
 	ProtocolReserved       = 255 // Reserved
 )
 
-// Address Family Numbers, Updated: 2016-10-25
+// Address Family Numbers, Updated: 2018-04-02
 const (
 	AddrFamilyIPv4                          = 1     // IP (IP version 4)
 	AddrFamilyIPv6                          = 2     // IP6 (IP version 6)
diff --git a/internal/iana/gen.go b/internal/iana/gen.go
index 2227e09..2a7661c 100644
--- a/internal/iana/gen.go
+++ b/internal/iana/gen.go
@@ -32,15 +32,11 @@
 		parseDSCPRegistry,
 	},
 	{
-		"https://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
-		parseTOSTCByte,
-	},
-	{
 		"https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
 		parseProtocolNumbers,
 	},
 	{
-		"http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml",
+		"https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml",
 		parseAddrFamilyNumbers,
 	},
 }
@@ -85,31 +81,39 @@
 	if err := dec.Decode(&dr); err != nil {
 		return err
 	}
-	drs := dr.escape()
 	fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
 	fmt.Fprintf(w, "const (\n")
-	for _, dr := range drs {
-		fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
+	for _, dr := range dr.escapeDSCP() {
+		fmt.Fprintf(w, "DiffServ%s = %#02x", dr.Name, dr.Value)
 		fmt.Fprintf(w, "// %s\n", dr.OrigName)
 	}
+	for _, er := range dr.escapeECN() {
+		fmt.Fprintf(w, "%s = %#02x", er.Descr, er.Value)
+		fmt.Fprintf(w, "// %s\n", er.OrigDescr)
+	}
 	fmt.Fprintf(w, ")\n")
 	return nil
 }
 
 type dscpRegistry struct {
-	XMLName     xml.Name `xml:"registry"`
-	Title       string   `xml:"title"`
-	Updated     string   `xml:"updated"`
-	Note        string   `xml:"note"`
-	RegTitle    string   `xml:"registry>title"`
-	PoolRecords []struct {
-		Name  string `xml:"name"`
-		Space string `xml:"space"`
-	} `xml:"registry>record"`
-	Records []struct {
-		Name  string `xml:"name"`
-		Space string `xml:"space"`
-	} `xml:"registry>registry>record"`
+	XMLName    xml.Name `xml:"registry"`
+	Title      string   `xml:"title"`
+	Updated    string   `xml:"updated"`
+	Note       string   `xml:"note"`
+	Registries []struct {
+		Title      string `xml:"title"`
+		Registries []struct {
+			Title   string `xml:"title"`
+			Records []struct {
+				Name  string `xml:"name"`
+				Space string `xml:"space"`
+			} `xml:"record"`
+		} `xml:"registry"`
+		Records []struct {
+			Value string `xml:"value"`
+			Descr string `xml:"description"`
+		} `xml:"record"`
+	} `xml:"registry"`
 }
 
 type canonDSCPRecord struct {
@@ -118,92 +122,84 @@
 	Value    int
 }
 
-func (drr *dscpRegistry) escape() []canonDSCPRecord {
-	drs := make([]canonDSCPRecord, len(drr.Records))
-	sr := strings.NewReplacer(
-		"+", "",
-		"-", "",
-		"/", "",
-		".", "",
-		" ", "",
-	)
-	for i, dr := range drr.Records {
-		s := strings.TrimSpace(dr.Name)
-		drs[i].OrigName = s
-		drs[i].Name = sr.Replace(s)
-		n, err := strconv.ParseUint(dr.Space, 2, 8)
-		if err != nil {
+func (drr *dscpRegistry) escapeDSCP() []canonDSCPRecord {
+	var drs []canonDSCPRecord
+	for _, preg := range drr.Registries {
+		if !strings.Contains(preg.Title, "Differentiated Services Field Codepoints") {
 			continue
 		}
-		drs[i].Value = int(n) << 2
+		for _, reg := range preg.Registries {
+			if !strings.Contains(reg.Title, "Pool 1 Codepoints") {
+				continue
+			}
+			drs = make([]canonDSCPRecord, len(reg.Records))
+			sr := strings.NewReplacer(
+				"+", "",
+				"-", "",
+				"/", "",
+				".", "",
+				" ", "",
+			)
+			for i, dr := range reg.Records {
+				s := strings.TrimSpace(dr.Name)
+				drs[i].OrigName = s
+				drs[i].Name = sr.Replace(s)
+				n, err := strconv.ParseUint(dr.Space, 2, 8)
+				if err != nil {
+					continue
+				}
+				drs[i].Value = int(n) << 2
+			}
+		}
 	}
 	return drs
 }
 
-func parseTOSTCByte(w io.Writer, r io.Reader) error {
-	dec := xml.NewDecoder(r)
-	var ttb tosTCByte
-	if err := dec.Decode(&ttb); err != nil {
-		return err
-	}
-	trs := ttb.escape()
-	fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
-	fmt.Fprintf(w, "const (\n")
-	for _, tr := range trs {
-		fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
-		fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
-	}
-	fmt.Fprintf(w, ")\n")
-	return nil
+type canonECNRecord struct {
+	OrigDescr string
+	Descr     string
+	Value     int
 }
 
-type tosTCByte struct {
-	XMLName  xml.Name `xml:"registry"`
-	Title    string   `xml:"title"`
-	Updated  string   `xml:"updated"`
-	Note     string   `xml:"note"`
-	RegTitle string   `xml:"registry>title"`
-	Records  []struct {
-		Binary  string `xml:"binary"`
-		Keyword string `xml:"keyword"`
-	} `xml:"registry>record"`
-}
-
-type canonTOSTCByteRecord struct {
-	OrigKeyword string
-	Keyword     string
-	Value       int
-}
-
-func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
-	trs := make([]canonTOSTCByteRecord, len(ttb.Records))
-	sr := strings.NewReplacer(
-		"Capable", "",
-		"(", "",
-		")", "",
-		"+", "",
-		"-", "",
-		"/", "",
-		".", "",
-		" ", "",
-	)
-	for i, tr := range ttb.Records {
-		s := strings.TrimSpace(tr.Keyword)
-		trs[i].OrigKeyword = s
-		ss := strings.Split(s, " ")
-		if len(ss) > 1 {
-			trs[i].Keyword = strings.Join(ss[1:], " ")
-		} else {
-			trs[i].Keyword = ss[0]
-		}
-		trs[i].Keyword = sr.Replace(trs[i].Keyword)
-		n, err := strconv.ParseUint(tr.Binary, 2, 8)
-		if err != nil {
+func (drr *dscpRegistry) escapeECN() []canonECNRecord {
+	var ers []canonECNRecord
+	for _, reg := range drr.Registries {
+		if !strings.Contains(reg.Title, "ECN Field") {
 			continue
 		}
-		trs[i].Value = int(n)
+		ers = make([]canonECNRecord, len(reg.Records))
+		sr := strings.NewReplacer(
+			"Capable", "",
+			"Not-ECT", "",
+			"ECT(1)", "",
+			"ECT(0)", "",
+			"CE", "",
+			"(", "",
+			")", "",
+			"+", "",
+			"-", "",
+			"/", "",
+			".", "",
+			" ", "",
+		)
+		for i, er := range reg.Records {
+			s := strings.TrimSpace(er.Descr)
+			ers[i].OrigDescr = s
+			ss := strings.Split(s, " ")
+			if len(ss) > 1 {
+				ers[i].Descr = strings.Join(ss[1:], " ")
+			} else {
+				ers[i].Descr = ss[0]
+			}
+			ers[i].Descr = sr.Replace(er.Descr)
+			n, err := strconv.ParseUint(er.Value, 2, 8)
+			if err != nil {
+				continue
+			}
+			ers[i].Value = int(n)
+		}
 	}
-	return trs
+	return ers
 }
 
 func parseProtocolNumbers(w io.Writer, r io.Reader) error {