initial support for meta-headers

modules
Jean-Louis Huynen 2019-02-27 16:30:18 +01:00
parent c9bd1bb37b
commit 73664bd3bb
3 changed files with 67 additions and 5 deletions

View File

@ -52,7 +52,8 @@ Part of the client configuration can be stored in folder containing the followin
- type: D4 packat type, see [types](https://github.com/D4-project/architecture/tree/master/format)
- uuid: generated automiatically if empty
- version: protocol version
- rootCA.crt: optional CA certificate to check the server certificate
- rootCA.crt: optional : CA certificate to check the server certificate
- metaheader.json: optional : a json file describing feed's meta-type [types](https://github.com/D4-project/architecture/tree/master/format)
## Flags

View File

@ -1 +1 @@
127.0.0.1:4443
0.0.0.0:4443

View File

@ -66,6 +66,7 @@ type (
errnoCopy uint8
debug bool
conf d4params
mh metaHeader
}
d4params struct {
@ -77,6 +78,11 @@ type (
destination string
ttype uint8
}
metaHeader struct {
r io.Reader
src io.Reader
}
)
var (
@ -147,21 +153,38 @@ func main() {
signal.Notify(s, os.Interrupt, os.Kill)
c := make(chan string)
k := make(chan string)
for {
// init or reinit after retry
if set(d4p) {
// type 254 requires to send a meta-header first
if d4.conf.ttype == 254 {
if d4.hijackSource() {
nread, err := io.CopyBuffer(&d4.dst, d4.src, d4.dst.pb)
if err != nil {
panic(fmt.Sprintf("Cannot initiate session %s", err))
}
infof(fmt.Sprintf("Meta-Header sent: %d bytes", nread))
}
d4p.restoreSource()
}
// copy routine
go d4Copy(d4p, c, k)
} else if d4.retry > 0 {
go func() {
infof(fmt.Sprintf("Sleeping for %.f seconds before retry...\n", d4.retry.Seconds()))
fmt.Printf("Sleeping for %.f seconds before retry...\n", d4.retry.Seconds())
time.Sleep(d4.retry)
infof(fmt.Sprintf("Sleeping for %f seconds before retry.\n", d4.retry.Seconds()))
c <- "done waiting"
}()
} else {
panic("Unrecoverable error without retry.")
}
// Block until we catch an event
select {
case str := <-c:
fmt.Println(str)
infof(str)
continue
case str := <-k:
fmt.Println(str)
@ -258,6 +281,15 @@ func d4loadConfig(d4 *d4S) bool {
// parse type to uint8
tmp, _ = strconv.ParseUint(string(readConfFile(d4, "type")), 10, 8)
(*d4).conf.ttype = uint8(tmp)
// parse meta header file
if tmp == 254 {
file, err := os.Open((*d4).confdir + "/metaheader.json")
if err != nil && err != io.EOF {
panic("Failed to open Meta-Header File.")
} else {
(*d4).mh = newMetaHeader(file)
}
}
// Add the custom CA cert in D4 certpool
if (*d4).cc {
certb, _ := ioutil.ReadFile((*d4).confdir + "rootCA.crt")
@ -270,6 +302,10 @@ func d4loadConfig(d4 *d4S) bool {
return true
}
func newMetaHeader(mhr io.Reader) metaHeader {
return metaHeader{r: mhr}
}
func newD4Writer(writer io.Writer, key []byte) d4Writer {
return d4Writer{w: writer, key: key}
}
@ -434,7 +470,7 @@ func (d4w *d4Writer) updateHMAC(ps int) bool {
func (d4w *d4Writer) initHeader(d4 *d4S) bool {
// zero out the header
copy(d4w.fb[:HDR_SIZE], make([]byte, HDR_SIZE))
// put version a type into the header
// put version and type into the header
d4w.fb[0] = (*d4).conf.version
d4w.fb[1] = (*d4).conf.ttype
// put uuid into the header
@ -449,3 +485,28 @@ func (d4w *d4Writer) initHeader(d4 *d4S) bool {
infof(fmt.Sprintf("%b\n", d4w.fb[:HDR_SIZE]))
return true
}
// Cram the meta header in place of the source
func (d4 *d4S) hijackSource() bool {
d4.mh.src = d4.src
d4.src = d4.mh.r
return d4.dst.hijackHeader()
}
// We use type 2 to send the meta header
func (d4w *d4Writer) hijackHeader() bool {
d4w.fb[1] = 2
return true
}
// Meta Header Sent, we stuff our source back into d4
func (d4 *d4S) restoreSource() bool {
d4.src = d4.mh.src
return d4.dst.restoreHeader()
}
// Switch back the header to 254
func (d4w *d4Writer) restoreHeader() bool {
d4w.fb[1] = 254
return true
}