...

Source file src/github.com/miekg/dns/privaterr.go

Documentation: github.com/miekg/dns

     1  package dns
     2  
     3  import "strings"
     4  
     5  // PrivateRdata is an interface used for implementing "Private Use" RR types, see
     6  // RFC 6895. This allows one to experiment with new RR types, without requesting an
     7  // official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
     8  type PrivateRdata interface {
     9  	// String returns the text presentation of the Rdata of the Private RR.
    10  	String() string
    11  	// Parse parses the Rdata of the private RR.
    12  	Parse([]string) error
    13  	// Pack is used when packing a private RR into a buffer.
    14  	Pack([]byte) (int, error)
    15  	// Unpack is used when unpacking a private RR from a buffer.
    16  	Unpack([]byte) (int, error)
    17  	// Copy copies the Rdata into the PrivateRdata argument.
    18  	Copy(PrivateRdata) error
    19  	// Len returns the length in octets of the Rdata.
    20  	Len() int
    21  }
    22  
    23  // PrivateRR represents an RR that uses a PrivateRdata user-defined type.
    24  // It mocks normal RRs and implements dns.RR interface.
    25  type PrivateRR struct {
    26  	Hdr  RR_Header
    27  	Data PrivateRdata
    28  
    29  	generator func() PrivateRdata // for copy
    30  }
    31  
    32  // Header return the RR header of r.
    33  func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
    34  
    35  func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
    36  
    37  // Private len and copy parts to satisfy RR interface.
    38  func (r *PrivateRR) len(off int, compression map[string]struct{}) int {
    39  	l := r.Hdr.len(off, compression)
    40  	l += r.Data.Len()
    41  	return l
    42  }
    43  
    44  func (r *PrivateRR) copy() RR {
    45  	// make new RR like this:
    46  	rr := &PrivateRR{r.Hdr, r.generator(), r.generator}
    47  
    48  	if err := r.Data.Copy(rr.Data); err != nil {
    49  		panic("dns: got value that could not be used to copy Private rdata: " + err.Error())
    50  	}
    51  
    52  	return rr
    53  }
    54  
    55  func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {
    56  	n, err := r.Data.Pack(msg[off:])
    57  	if err != nil {
    58  		return len(msg), err
    59  	}
    60  	off += n
    61  	return off, nil
    62  }
    63  
    64  func (r *PrivateRR) unpack(msg []byte, off int) (int, error) {
    65  	off1, err := r.Data.Unpack(msg[off:])
    66  	off += off1
    67  	return off, err
    68  }
    69  
    70  func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError {
    71  	var l lex
    72  	text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
    73  Fetch:
    74  	for {
    75  		// TODO(miek): we could also be returning _QUOTE, this might or might not
    76  		// be an issue (basically parsing TXT becomes hard)
    77  		switch l, _ = c.Next(); l.value {
    78  		case zNewline, zEOF:
    79  			break Fetch
    80  		case zString:
    81  			text = append(text, l.token)
    82  		}
    83  	}
    84  
    85  	err := r.Data.Parse(text)
    86  	if err != nil {
    87  		return &ParseError{"", err.Error(), l}
    88  	}
    89  
    90  	return nil
    91  }
    92  
    93  func (r *PrivateRR) isDuplicate(r2 RR) bool { return false }
    94  
    95  // PrivateHandle registers a private resource record type. It requires
    96  // string and numeric representation of private RR type and generator function as argument.
    97  func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
    98  	rtypestr = strings.ToUpper(rtypestr)
    99  
   100  	TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} }
   101  	TypeToString[rtype] = rtypestr
   102  	StringToType[rtypestr] = rtype
   103  }
   104  
   105  // PrivateHandleRemove removes definitions required to support private RR type.
   106  func PrivateHandleRemove(rtype uint16) {
   107  	rtypestr, ok := TypeToString[rtype]
   108  	if ok {
   109  		delete(TypeToRR, rtype)
   110  		delete(TypeToString, rtype)
   111  		delete(StringToType, rtypestr)
   112  	}
   113  }
   114  

View as plain text