2 NNCP -- Node-to-Node CoPy
3 Copyright (C) 2016-2017 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
33 "golang.org/x/crypto/blake2b"
36 func (ctx *Ctx) Tx(node *Node, pkt *Pkt, nice uint8, size int64, src io.Reader) (*Node, error) {
37 tmp, err := ctx.NewTmpFileWHash()
41 hops := make([]*Node, 0, 1+len(node.Via))
42 hops = append(hops, node)
44 for i := len(node.Via); i > 0; i-- {
45 lastNode = ctx.Neigh[*node.Via[i-1]]
46 hops = append(hops, lastNode)
48 errs := make(chan error)
50 pipeR, pipeW := io.Pipe()
51 go func(size int64, src io.Reader, dst io.WriteCloser) {
54 "nice": strconv.Itoa(int(nice)),
55 "size": strconv.FormatInt(size, 10),
57 errs <- PktEncWrite(ctx.Self, hops[0], pkt, nice, size, src, dst)
59 }(curSize, src, pipeW)
61 var pipeRPrev io.Reader
62 for i := 1; i < len(hops); i++ {
66 PathLen: blake2b.Size256,
67 Path: new([MaxPathSize]byte),
69 copy(pktTrans.Path[:], hops[i-1].Id[:])
70 curSize += PktOverhead + PktEncOverhead
72 pipeR, pipeW = io.Pipe()
73 go func(node *Node, pkt *Pkt, size int64, src io.Reader, dst io.WriteCloser) {
76 "nice": strconv.Itoa(int(nice)),
77 "size": strconv.FormatInt(size, 10),
79 errs <- PktEncWrite(ctx.Self, node, pkt, nice, size, src, dst)
81 }(hops[i], &pktTrans, curSize, pipeRPrev, pipeW)
84 _, err := io.Copy(tmp.W, pipeR)
87 for i := 0; i <= len(hops); i++ {
94 nodePath := filepath.Join(ctx.Spool, lastNode.Id.String())
95 err = tmp.Commit(filepath.Join(nodePath, string(TTx)))
96 os.Symlink(nodePath, filepath.Join(ctx.Spool, lastNode.Name))
100 func (ctx *Ctx) TxFile(node *Node, nice uint8, srcPath, dstPath string) error {
101 dstPath = path.Clean(dstPath)
102 if path.IsAbs(dstPath) {
103 return errors.New("Relative destination path required")
105 pkt, err := NewPkt(PktTypeFile, dstPath)
109 src, err := os.Open(srcPath)
114 srcStat, err := src.Stat()
118 _, err = ctx.Tx(node, pkt, nice, srcStat.Size(), bufio.NewReader(src))
123 "nice": strconv.Itoa(int(nice)),
126 "size": strconv.FormatInt(srcStat.Size(), 10),
132 "nice": strconv.Itoa(int(nice)),
135 "size": strconv.FormatInt(srcStat.Size(), 10),
142 func (ctx *Ctx) TxFreq(node *Node, nice uint8, srcPath, dstPath string) error {
143 dstPath = path.Clean(dstPath)
144 if path.IsAbs(dstPath) {
145 return errors.New("Relative destination path required")
147 srcPath = path.Clean(srcPath)
148 if path.IsAbs(srcPath) {
149 return errors.New("Relative source path required")
151 pkt, err := NewPkt(PktTypeFreq, srcPath)
155 src := strings.NewReader(dstPath)
156 size := int64(src.Len())
157 _, err = ctx.Tx(node, pkt, nice, size, src)
162 "nice": strconv.Itoa(int(nice)),
170 "nice": strconv.Itoa(int(nice)),
179 func (ctx *Ctx) TxMail(node *Node, nice uint8, recipient string, body []byte) error {
180 pkt, err := NewPkt(PktTypeMail, recipient)
184 var compressed bytes.Buffer
185 compressor := zlib.NewWriter(&compressed)
186 if _, err = io.Copy(compressor, bytes.NewReader(body)); err != nil {
190 size := int64(compressed.Len())
191 _, err = ctx.Tx(node, pkt, nice, size, &compressed)
196 "nice": strconv.Itoa(int(nice)),
198 "size": strconv.FormatInt(size, 10),
204 "nice": strconv.Itoa(int(nice)),
206 "size": strconv.FormatInt(size, 10),
213 func (ctx *Ctx) TxTrns(node *Node, nice uint8, size int64, src io.Reader) error {
217 "nice": strconv.Itoa(int(nice)),
218 "size": strconv.FormatInt(size, 10),
220 tmp, err := ctx.NewTmpFileWHash()
224 if _, err = io.Copy(tmp.W, src); err != nil {
227 nodePath := filepath.Join(ctx.Spool, node.Id.String())
228 err = tmp.Commit(filepath.Join(nodePath, string(TTx)))
233 "nice": strconv.Itoa(int(nice)),
234 "size": strconv.FormatInt(size, 10),
240 "nice": strconv.Itoa(int(nice)),
241 "size": strconv.FormatInt(size, 10),
245 os.Symlink(nodePath, filepath.Join(ctx.Spool, node.Name))