Compare commits

...

6 Commits

Author SHA1 Message Date
Jakob Borg
24b8f9211a Open GUI on startup 2014-03-02 12:52:32 +01:00
Jakob Borg
ea0bed2238 drone.io badge 2014-02-24 14:06:22 +01:00
Jakob Borg
e2fe57c440 deadcode 2014-02-24 13:34:24 +01:00
Jakob Borg
434a0ccf2a golint 2014-02-24 13:29:30 +01:00
Jakob Borg
e7bf3ac108 go vet 2014-02-24 13:24:03 +01:00
Jakob Borg
c5bdaebf2b Remove spurious debug print 2014-02-23 15:08:15 +01:00
14 changed files with 105 additions and 65 deletions

View File

@@ -1,4 +1,4 @@
syncthing
syncthing [![Build Status](https://drone.io/github.com/calmh/syncthing/status.png)](https://drone.io/github.com/calmh/syncthing/latest)
=========
This is the `syncthing` project. The following are the project goals:

View File

@@ -17,7 +17,7 @@ func Blocks(r io.Reader, blocksize int) ([]Block, error) {
var blocks []Block
var offset int64
for {
lr := &io.LimitedReader{r, int64(blocksize)}
lr := &io.LimitedReader{R: r, N: int64(blocksize)}
hf := sha256.New()
n, err := io.Copy(hf, lr)
if err != nil {

View File

@@ -34,7 +34,7 @@ type Discoverer struct {
}
var (
ErrIncorrectMagic = errors.New("Incorrect magic number")
ErrIncorrectMagic = errors.New("incorrect magic number")
)
// We tolerate a certain amount of errors because we might be running on
@@ -91,7 +91,7 @@ func (d *Discoverer) sendAnnouncements() {
}
if Debug {
fmt.Println("send announcement -> ", remote)
log.Println("send announcement -> ", remote)
}
_, _, err = d.conn.WriteMsgUDP(buf, nil, remote)
if err != nil {
@@ -123,7 +123,7 @@ func (d *Discoverer) sendExtAnnouncements() {
for errCounter < maxErrors {
if Debug {
fmt.Println("send announcement -> ", remote)
log.Println("send announcement -> ", remote)
}
_, _, err = d.conn.WriteMsgUDP(buf, nil, remote)
if err != nil {
@@ -134,7 +134,7 @@ func (d *Discoverer) sendExtAnnouncements() {
}
time.Sleep(d.ExtBroadcastIntv)
}
log.Println("discover/write: %v: stopping due to too many errors:", remote, err)
log.Printf("discover/write: %v: stopping due to too many errors: %v", remote, err)
}
func (d *Discoverer) recvAnnouncements() {
@@ -184,7 +184,6 @@ func (d *Discoverer) recvAnnouncements() {
d.registryLock.Lock()
_, seen := d.registry[pkt.NodeID]
if !seen {
fmt.Println("new node seen, forced announce")
select {
case d.forcedBroadcastTick <- time.Now():
}

View File

@@ -272,7 +272,7 @@ func TestFileQueueThreadHandling(t *testing.T) {
close(start)
wg.Wait()
if int(gotTot) != total {
t.Error("Total mismatch; %d != %d", gotTot, total)
t.Errorf("Total mismatch; %d != %d", gotTot, total)
}
}
@@ -283,13 +283,13 @@ func TestDeleteAt(t *testing.T) {
q.files = queuedFileList{{name: "a"}, {name: "b"}, {name: "c"}, {name: "d"}}
q.deleteAt(i)
if l := len(q.files); l != 3 {
t.Fatal("deleteAt(%d) failed; %d != 3", i, l)
t.Fatalf("deleteAt(%d) failed; %d != 3", i, l)
}
}
q.files = queuedFileList{{name: "a"}}
q.deleteAt(0)
if l := len(q.files); l != 0 {
t.Fatal("deleteAt(only) failed; %d != 0", l)
t.Fatalf("deleteAt(only) failed; %d != 0", l)
}
}

36
main.go
View File

@@ -24,11 +24,10 @@ import (
)
var cfg Configuration
var Version string = "unknown-dev"
var Version = "unknown-dev"
var (
myID string
config ini.Config
myID string
)
var (
@@ -83,7 +82,7 @@ func main() {
fatalErr(err)
}
myID = string(certId(cert.Certificate[0]))
myID = string(certID(cert.Certificate[0]))
log.SetPrefix("[" + myID[0:5] + "] ")
logger.SetPrefix("[" + myID[0:5] + "] ")
@@ -188,16 +187,26 @@ func main() {
// GUI
if cfg.Options.GUIEnabled && cfg.Options.GUIAddress != "" {
host, port, err := net.SplitHostPort(cfg.Options.GUIAddress)
addr, err := net.ResolveTCPAddr("tcp", cfg.Options.GUIAddress)
if err != nil {
warnf("Cannot start GUI on %q: %v", cfg.Options.GUIAddress, err)
} else {
if len(host) > 0 {
infof("Starting web GUI on http://%s", cfg.Options.GUIAddress)
} else {
infof("Starting web GUI on port %s", port)
var hostOpen, hostShow string
switch {
case addr.IP == nil:
hostOpen = "localhost"
hostShow = "0.0.0.0"
case addr.IP.IsUnspecified():
hostOpen = "localhost"
hostShow = addr.IP.String()
default:
hostOpen = addr.IP.String()
hostShow = hostOpen
}
infof("Starting web GUI on http://%s:%d/", hostShow, addr.Port)
startGUI(cfg.Options.GUIAddress, m)
openURL(fmt.Sprintf("http://%s:%d", hostOpen, addr.Port))
}
}
@@ -388,7 +397,7 @@ listen:
continue
}
remoteID := certId(tc.ConnectionState().PeerCertificates[0].Raw)
remoteID := certID(tc.ConnectionState().PeerCertificates[0].Raw)
if remoteID == myID {
warnf("Connect from myself (%s) - should not happen", remoteID)
@@ -469,7 +478,7 @@ func connect(myID string, disc *discover.Discoverer, m *Model, tlsCfg *tls.Confi
continue
}
remoteID := certId(conn.ConnectionState().PeerCertificates[0].Raw)
remoteID := certID(conn.ConnectionState().PeerCertificates[0].Raw)
if remoteID != nodeCfg.NodeID {
warnln("Unexpected nodeID", remoteID, "!=", nodeCfg.NodeID)
conn.Close()
@@ -502,7 +511,10 @@ func saveIndex(m *Model) {
gzw := gzip.NewWriter(idxf)
protocol.IndexMessage{"local", m.ProtocolIndex()}.EncodeXDR(gzw)
protocol.IndexMessage{
Repository: "local",
Files: m.ProtocolIndex(),
}.EncodeXDR(gzw)
gzw.Close()
idxf.Close()
os.Rename(fullName+".tmp", fullName)

View File

@@ -64,9 +64,6 @@ type Connection interface {
const (
idxBcastHoldtime = 15 * time.Second // Wait at least this long after the last index modification
idxBcastMaxDelay = 120 * time.Second // Unless we've already waited this long
minFileHoldTimeS = 60 // Never allow file changes more often than this
maxFileHoldTimeS = 600 // Always allow file changes at least this often
)
var (

34
openurl.go Normal file
View File

@@ -0,0 +1,34 @@
/*
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"os/exec"
"runtime"
)
func openURL(url string) error {
if runtime.GOOS == "windows" {
return exec.Command("cmd.exe", "/C", "start "+url).Run()
}
if runtime.GOOS == "darwin" {
return exec.Command("open", url).Run()
}
return exec.Command("xdg-open", url).Run()
}

View File

@@ -46,7 +46,6 @@ func (e *ErrPipe) Write(data []byte) (int, error) {
e.PipeWriter.CloseWithError(e.err)
e.closed = true
return n, e.err
} else {
return e.PipeWriter.Write(data)
}
return e.PipeWriter.Write(data)
}

View File

@@ -31,7 +31,8 @@ const (
)
var (
ErrClusterHash = fmt.Errorf("Configuration error: mismatched cluster hash")
ErrClusterHash = fmt.Errorf("configuration error: mismatched cluster hash")
ErrClosed = errors.New("connection closed")
)
type Model interface {
@@ -56,7 +57,7 @@ type Connection struct {
xw *xdr.Writer
closed bool
awaiting map[int]chan asyncResult
nextId int
nextID int
indexSent map[string]map[string][2]int64
peerOptions map[string]string
myOptions map[string]string
@@ -68,8 +69,6 @@ type Connection struct {
statisticsLock sync.Mutex
}
var ErrClosed = errors.New("Connection closed")
type asyncResult struct {
val []byte
err error
@@ -105,7 +104,7 @@ func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver M
c.myOptions = options
go func() {
c.Lock()
header{0, c.nextId, messageTypeOptions}.encodeXDR(c.xw)
header{0, c.nextID, messageTypeOptions}.encodeXDR(c.xw)
var om OptionsMessage
for k, v := range options {
om.Options = append(om.Options, Option{k, v})
@@ -118,7 +117,7 @@ func NewConnection(nodeID string, reader io.Reader, writer io.Writer, receiver M
if err != nil {
log.Println("Warning: Write error during initial handshake:", err)
}
c.nextId++
c.nextID++
c.Unlock()
}()
}
@@ -155,12 +154,12 @@ func (c *Connection) Index(repo string, idx []FileInfo) {
idx = diff
}
header{0, c.nextId, msgType}.encodeXDR(c.xw)
header{0, c.nextID, msgType}.encodeXDR(c.xw)
_, err := IndexMessage{repo, idx}.encodeXDR(c.xw)
if err == nil {
err = c.flush()
}
c.nextId = (c.nextId + 1) & 0xfff
c.nextID = (c.nextID + 1) & 0xfff
c.hasSentIndex = true
c.Unlock()
@@ -178,8 +177,8 @@ func (c *Connection) Request(repo string, name string, offset int64, size int) (
return nil, ErrClosed
}
rc := make(chan asyncResult)
c.awaiting[c.nextId] = rc
header{0, c.nextId, messageTypeRequest}.encodeXDR(c.xw)
c.awaiting[c.nextID] = rc
header{0, c.nextID, messageTypeRequest}.encodeXDR(c.xw)
_, err := RequestMessage{repo, name, uint64(offset), uint32(size)}.encodeXDR(c.xw)
if err == nil {
err = c.flush()
@@ -189,7 +188,7 @@ func (c *Connection) Request(repo string, name string, offset int64, size int) (
c.close(err)
return nil, err
}
c.nextId = (c.nextId + 1) & 0xfff
c.nextID = (c.nextID + 1) & 0xfff
c.Unlock()
res, ok := <-rc
@@ -206,8 +205,8 @@ func (c *Connection) ping() bool {
return false
}
rc := make(chan asyncResult, 1)
c.awaiting[c.nextId] = rc
header{0, c.nextId, messageTypePing}.encodeXDR(c.xw)
c.awaiting[c.nextID] = rc
header{0, c.nextID, messageTypePing}.encodeXDR(c.xw)
err := c.flush()
if err != nil {
c.Unlock()
@@ -218,7 +217,7 @@ func (c *Connection) ping() bool {
c.close(c.xw.Error())
return false
}
c.nextId = (c.nextId + 1) & 0xfff
c.nextID = (c.nextID + 1) & 0xfff
c.Unlock()
res, ok := <-rc
@@ -268,7 +267,7 @@ loop:
break loop
}
if hdr.version != 0 {
c.close(fmt.Errorf("Protocol error: %s: unknown message version %#x", c.ID, hdr.version))
c.close(fmt.Errorf("protocol error: %s: unknown message version %#x", c.id, hdr.version))
break loop
}
@@ -371,7 +370,7 @@ loop:
}
default:
c.close(fmt.Errorf("Protocol error: %s: unknown message type %#x", c.ID, hdr.msgType))
c.close(fmt.Errorf("protocol error: %s: unknown message type %#x", c.id, hdr.msgType))
break loop
}
}
@@ -410,10 +409,10 @@ func (c *Connection) pingerLoop() {
select {
case ok := <-rc:
if !ok {
c.close(fmt.Errorf("Ping failure"))
c.close(fmt.Errorf("ping failure"))
}
case <-time.After(pingTimeout):
c.close(fmt.Errorf("Ping timeout"))
c.close(fmt.Errorf("ping timeout"))
}
}
}

View File

@@ -38,7 +38,7 @@ func TestPing(t *testing.T) {
}
func TestPingErr(t *testing.T) {
e := errors.New("Something broke")
e := errors.New("something broke")
for i := 0; i < 12; i++ {
for j := 0; j < 12; j++ {
@@ -64,7 +64,7 @@ func TestPingErr(t *testing.T) {
}
func TestRequestResponseErr(t *testing.T) {
e := errors.New("Something broke")
e := errors.New("something broke")
var pass bool
for i := 0; i < 48; i++ {
@@ -99,16 +99,16 @@ func TestRequestResponseErr(t *testing.T) {
t.Errorf("Incorrect response data %q", string(d))
}
if m0.repo != "default" {
t.Error("Incorrect repo %q", m0.repo)
t.Errorf("Incorrect repo %q", m0.repo)
}
if m0.name != "tn" {
t.Error("Incorrect name %q", m0.name)
t.Errorf("Incorrect name %q", m0.name)
}
if m0.offset != 1234 {
t.Error("Incorrect offset %d", m0.offset)
t.Errorf("Incorrect offset %d", m0.offset)
}
if m0.size != 5678 {
t.Error("Incorrect size %d", m0.size)
t.Errorf("Incorrect size %d", m0.size)
}
t.Logf("Pass at %d+%d bytes", i, j)
pass = true

View File

@@ -6,7 +6,7 @@ import (
)
const (
MAX_CHANGE_HISTORY = 4
MaxChangeHistory = 4
)
type change struct {
@@ -45,8 +45,8 @@ func (h changeHistory) bandwidth(t time.Time) int64 {
func (h *changeHistory) append(size int64, t time.Time) {
c := change{size, t}
if len(h.changes) == MAX_CHANGE_HISTORY {
h.changes = h.changes[1:MAX_CHANGE_HISTORY]
if len(h.changes) == MaxChangeHistory {
h.changes = h.changes[1:MaxChangeHistory]
}
h.changes = append(h.changes, c)
}

View File

@@ -21,7 +21,7 @@ func TestSuppressor(t *testing.T) {
// bw is 10000 / 10 = 1000
t1 = t0.Add(10 * time.Second)
if bw := s.changes["foo"].bandwidth(t1); bw != 1000 {
t.Error("Incorrect bw %d", bw)
t.Errorf("Incorrect bw %d", bw)
}
sup, prev = s.suppress("foo", 10000, t1)
if sup {
@@ -34,7 +34,7 @@ func TestSuppressor(t *testing.T) {
// bw is (10000 + 10000) / 11 = 1818
t1 = t0.Add(11 * time.Second)
if bw := s.changes["foo"].bandwidth(t1); bw != 1818 {
t.Error("Incorrect bw %d", bw)
t.Errorf("Incorrect bw %d", bw)
}
sup, prev = s.suppress("foo", 100500, t1)
if sup {
@@ -47,7 +47,7 @@ func TestSuppressor(t *testing.T) {
// bw is (10000 + 10000 + 100500) / 12 = 10041
t1 = t0.Add(12 * time.Second)
if bw := s.changes["foo"].bandwidth(t1); bw != 10041 {
t.Error("Incorrect bw %d", bw)
t.Errorf("Incorrect bw %d", bw)
}
sup, prev = s.suppress("foo", 10000000, t1) // value will be ignored
if !sup {
@@ -60,7 +60,7 @@ func TestSuppressor(t *testing.T) {
// bw is (10000 + 10000 + 100500) / 15 = 8033
t1 = t0.Add(15 * time.Second)
if bw := s.changes["foo"].bandwidth(t1); bw != 8033 {
t.Error("Incorrect bw %d", bw)
t.Errorf("Incorrect bw %d", bw)
}
sup, prev = s.suppress("foo", 10000000, t1)
if sup {
@@ -84,29 +84,29 @@ func TestHistory(t *testing.T) {
t.Errorf("Incorrect first record size %d", s)
}
for i := 1; i < MAX_CHANGE_HISTORY; i++ {
for i := 1; i < MaxChangeHistory; i++ {
h.append(int64(40+i), t0.Add(time.Duration(i)*time.Second))
}
if l := len(h.changes); l != MAX_CHANGE_HISTORY {
if l := len(h.changes); l != MaxChangeHistory {
t.Errorf("Incorrect history length %d", l)
}
if s := h.changes[0].size; s != 40 {
t.Errorf("Incorrect first record size %d", s)
}
if s := h.changes[MAX_CHANGE_HISTORY-1].size; s != 40+MAX_CHANGE_HISTORY-1 {
if s := h.changes[MaxChangeHistory-1].size; s != 40+MaxChangeHistory-1 {
t.Errorf("Incorrect last record size %d", s)
}
h.append(999, t0.Add(time.Duration(999)*time.Second))
if l := len(h.changes); l != MAX_CHANGE_HISTORY {
if l := len(h.changes); l != MaxChangeHistory {
t.Errorf("Incorrect history length %d", l)
}
if s := h.changes[0].size; s != 41 {
t.Errorf("Incorrect first record size %d", s)
}
if s := h.changes[MAX_CHANGE_HISTORY-1].size; s != 999 {
if s := h.changes[MaxChangeHistory-1].size; s != 999 {
t.Errorf("Incorrect last record size %d", s)
}

2
tls.go
View File

@@ -25,7 +25,7 @@ func loadCert(dir string) (tls.Certificate, error) {
return tls.LoadX509KeyPair(path.Join(dir, "cert.pem"), path.Join(dir, "key.pem"))
}
func certId(bs []byte) string {
func certID(bs []byte) string {
hf := sha256.New()
hf.Write(bs)
id := hf.Sum(nil)

View File

@@ -5,7 +5,7 @@ import (
"io"
)
var ErrElementSizeExceeded = errors.New("Element size exceeded")
var ErrElementSizeExceeded = errors.New("element size exceeded")
type Reader struct {
r io.Reader