From 34d0e1b2c32d1bfe3aaa8519cf760ce499315ad5 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Feb 2015 12:04:02 +0100 Subject: p2p: fix ecies dependency in tests We forgot to update this reference when moving ecies into the go-ethereum repo. --- Godeps/Godeps.json | 6 +- .../src/github.com/obscuren/ecies/.gitignore | 24 - .../src/github.com/obscuren/ecies/LICENSE | 28 -- .../src/github.com/obscuren/ecies/README | 94 ---- .../src/github.com/obscuren/ecies/asn1.go | 556 --------------------- .../src/github.com/obscuren/ecies/ecies.go | 326 ------------ .../src/github.com/obscuren/ecies/ecies_test.go | 489 ------------------ .../src/github.com/obscuren/ecies/params.go | 187 ------- p2p/crypto_test.go | 2 +- 9 files changed, 2 insertions(+), 1710 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/README delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/asn1.go delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/ecies.go delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/ecies_test.go delete mode 100644 Godeps/_workspace/src/github.com/obscuren/ecies/params.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 831140690..9fa7373c8 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,6 +1,6 @@ { "ImportPath": "github.com/ethereum/go-ethereum", - "GoVersion": "go1.4", + "GoVersion": "go1.4.1", "Packages": [ "./..." ], @@ -57,10 +57,6 @@ "ImportPath": "github.com/jackpal/go-nat-pmp", "Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" }, - { - "ImportPath": "github.com/obscuren/ecies", - "Rev": "d899334bba7bf4a157cab19d8ad836dcb1de0c34" - }, { "ImportPath": "github.com/obscuren/otto", "Rev": "cf13cc4228c5e5ce0fe27a7aea90bc10091c4f19" diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/.gitignore b/Godeps/_workspace/src/github.com/obscuren/ecies/.gitignore deleted file mode 100644 index 802b6744a..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -*~ diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/LICENSE b/Godeps/_workspace/src/github.com/obscuren/ecies/LICENSE deleted file mode 100644 index e1ed19a27..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2013 Kyle Isom -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/README b/Godeps/_workspace/src/github.com/obscuren/ecies/README deleted file mode 100644 index 2650c7b9f..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/README +++ /dev/null @@ -1,94 +0,0 @@ -# NOTE - -This implementation is direct fork of Kylom's implementation. I claim no authorship over this code apart from some minor modifications. -Please be aware this code **has not yet been reviewed**. - -ecies implements the Elliptic Curve Integrated Encryption Scheme. - -The package is designed to be compliant with the appropriate NIST -standards, and therefore doesn't support the full SEC 1 algorithm set. - - -STATUS: - -ecies should be ready for use. The ASN.1 support is only complete so -far as to supported the listed algorithms before. - - -CAVEATS - -1. CMAC support is currently not present. - - -SUPPORTED ALGORITHMS - - SYMMETRIC CIPHERS HASH FUNCTIONS - AES128 SHA-1 - AES192 SHA-224 - AES256 SHA-256 - SHA-384 - ELLIPTIC CURVE SHA-512 - P256 - P384 KEY DERIVATION FUNCTION - P521 NIST SP 800-65a Concatenation KDF - -Curve P224 isn't supported because it does not provide a minimum security -level of AES128 with HMAC-SHA1. According to NIST SP 800-57, the security -level of P224 is 112 bits of security. Symmetric ciphers use CTR-mode; -message tags are computed using HMAC- function. - - -CURVE SELECTION - -According to NIST SP 800-57, the following curves should be selected: - - +----------------+-------+ - | SYMMETRIC SIZE | CURVE | - +----------------+-------+ - | 128-bit | P256 | - +----------------+-------+ - | 192-bit | P384 | - +----------------+-------+ - | 256-bit | P521 | - +----------------+-------+ - - -TODO - -1. Look at serialising the parameters with the SEC 1 ASN.1 module. -2. Validate ASN.1 formats with SEC 1. - - -TEST VECTORS - -The only test vectors I've found so far date from 1993, predating AES -and including only 163-bit curves. Therefore, there are no published -test vectors to compare to. - - -LICENSE - -ecies is released under the same license as the Go source code. See the -LICENSE file for details. - - -REFERENCES - -* SEC (Standard for Efficient Cryptography) 1, version 2.0: Elliptic - Curve Cryptography; Certicom, May 2009. - http://www.secg.org/sec1-v2.pdf -* GEC (Guidelines for Efficient Cryptography) 2, version 0.3: Test - Vectors for SEC 1; Certicom, September 1999. - http://read.pudn.com/downloads168/doc/772358/TestVectorsforSEC%201-gec2.pdf -* NIST SP 800-56a: Recommendation for Pair-Wise Key Establishment Schemes - Using Discrete Logarithm Cryptography. National Institute of Standards - and Technology, May 2007. - http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf -* Suite B Implementer’s Guide to NIST SP 800-56A. National Security - Agency, July 28, 2009. - http://www.nsa.gov/ia/_files/SuiteB_Implementer_G-113808.pdf -* NIST SP 800-57: Recommendation for Key Management – Part 1: General - (Revision 3). National Institute of Standards and Technology, July - 2012. - http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf - diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/asn1.go b/Godeps/_workspace/src/github.com/obscuren/ecies/asn1.go deleted file mode 100644 index 3ef194ea0..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/asn1.go +++ /dev/null @@ -1,556 +0,0 @@ -package ecies - -import ( - "bytes" - "crypto" - "crypto/elliptic" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "encoding/asn1" - "encoding/pem" - "fmt" - "hash" - "math/big" -) - -var ( - secgScheme = []int{1, 3, 132, 1} - shaScheme = []int{2, 16, 840, 1, 101, 3, 4, 2} - ansiX962Scheme = []int{1, 2, 840, 10045} - x963Scheme = []int{1, 2, 840, 63, 0} -) - -var ErrInvalidPrivateKey = fmt.Errorf("ecies: invalid private key") - -func doScheme(base, v []int) asn1.ObjectIdentifier { - var oidInts asn1.ObjectIdentifier - oidInts = append(oidInts, base...) - return append(oidInts, v...) -} - -// curve OID code taken from crypto/x509, including -// - oidNameCurve* -// - namedCurveFromOID -// - oidFromNamedCurve -// RFC 5480, 2.1.1.1. Named Curve -// -// secp224r1 OBJECT IDENTIFIER ::= { -// iso(1) identified-organization(3) certicom(132) curve(0) 33 } -// -// secp256r1 OBJECT IDENTIFIER ::= { -// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) -// prime(1) 7 } -// -// secp384r1 OBJECT IDENTIFIER ::= { -// iso(1) identified-organization(3) certicom(132) curve(0) 34 } -// -// secp521r1 OBJECT IDENTIFIER ::= { -// iso(1) identified-organization(3) certicom(132) curve(0) 35 } -// -// NB: secp256r1 is equivalent to prime256v1 -type secgNamedCurve asn1.ObjectIdentifier - -var ( - secgNamedCurveP224 = secgNamedCurve{1, 3, 132, 0, 33} - secgNamedCurveP256 = secgNamedCurve{1, 2, 840, 10045, 3, 1, 7} - secgNamedCurveP384 = secgNamedCurve{1, 3, 132, 0, 34} - secgNamedCurveP521 = secgNamedCurve{1, 3, 132, 0, 35} - rawCurveP224 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 3} - rawCurveP256 = []byte{6, 8, 4, 2, 1, 3, 4, 7, 2, 2, 0, 6, 6, 1, 3, 1, 7} - rawCurveP384 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 4} - rawCurveP521 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 5} -) - -func rawCurve(curve elliptic.Curve) []byte { - switch curve { - case elliptic.P224(): - return rawCurveP224 - case elliptic.P256(): - return rawCurveP256 - case elliptic.P384(): - return rawCurveP384 - case elliptic.P521(): - return rawCurveP521 - default: - return nil - } -} - -func (curve secgNamedCurve) Equal(curve2 secgNamedCurve) bool { - if len(curve) != len(curve2) { - return false - } - for i, _ := range curve { - if curve[i] != curve2[i] { - return false - } - } - return true -} - -func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve { - switch { - case curve.Equal(secgNamedCurveP224): - return elliptic.P224() - case curve.Equal(secgNamedCurveP256): - return elliptic.P256() - case curve.Equal(secgNamedCurveP384): - return elliptic.P384() - case curve.Equal(secgNamedCurveP521): - return elliptic.P521() - } - return nil -} - -func oidFromNamedCurve(curve elliptic.Curve) (secgNamedCurve, bool) { - switch curve { - case elliptic.P224(): - return secgNamedCurveP224, true - case elliptic.P256(): - return secgNamedCurveP256, true - case elliptic.P384(): - return secgNamedCurveP384, true - case elliptic.P521(): - return secgNamedCurveP521, true - } - - return nil, false -} - -// asnAlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC -// 5280, section 4.1.1.2. -type asnAlgorithmIdentifier struct { - Algorithm asn1.ObjectIdentifier - Parameters asn1.RawValue `asn1:"optional"` -} - -func (a asnAlgorithmIdentifier) Cmp(b asnAlgorithmIdentifier) bool { - if len(a.Algorithm) != len(b.Algorithm) { - return false - } - for i, _ := range a.Algorithm { - if a.Algorithm[i] != b.Algorithm[i] { - return false - } - } - return true -} - -type asnHashFunction asnAlgorithmIdentifier - -var ( - oidSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26} - oidSHA224 = doScheme(shaScheme, []int{4}) - oidSHA256 = doScheme(shaScheme, []int{1}) - oidSHA384 = doScheme(shaScheme, []int{2}) - oidSHA512 = doScheme(shaScheme, []int{3}) -) - -func hashFromOID(oid asn1.ObjectIdentifier) func() hash.Hash { - switch { - case oid.Equal(oidSHA1): - return sha1.New - case oid.Equal(oidSHA224): - return sha256.New224 - case oid.Equal(oidSHA256): - return sha256.New - case oid.Equal(oidSHA384): - return sha512.New384 - case oid.Equal(oidSHA512): - return sha512.New - } - return nil -} - -func oidFromHash(hash crypto.Hash) (asn1.ObjectIdentifier, bool) { - switch hash { - case crypto.SHA1: - return oidSHA1, true - case crypto.SHA224: - return oidSHA224, true - case crypto.SHA256: - return oidSHA256, true - case crypto.SHA384: - return oidSHA384, true - case crypto.SHA512: - return oidSHA512, true - default: - return nil, false - } -} - -var ( - asnAlgoSHA1 = asnHashFunction{ - Algorithm: oidSHA1, - } - asnAlgoSHA224 = asnHashFunction{ - Algorithm: oidSHA224, - } - asnAlgoSHA256 = asnHashFunction{ - Algorithm: oidSHA256, - } - asnAlgoSHA384 = asnHashFunction{ - Algorithm: oidSHA384, - } - asnAlgoSHA512 = asnHashFunction{ - Algorithm: oidSHA512, - } -) - -// type ASNasnSubjectPublicKeyInfo struct { -// -// } -// - -type asnSubjectPublicKeyInfo struct { - Algorithm asn1.ObjectIdentifier - PublicKey asn1.BitString - Supplements ecpksSupplements `asn1:"optional"` -} - -type asnECPKAlgorithms struct { - Type asn1.ObjectIdentifier -} - -var idPublicKeyType = doScheme(ansiX962Scheme, []int{2}) -var idEcPublicKey = doScheme(idPublicKeyType, []int{1}) -var idEcPublicKeySupplemented = doScheme(idPublicKeyType, []int{0}) - -func curveToRaw(curve elliptic.Curve) (rv asn1.RawValue, ok bool) { - switch curve { - case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521(): - raw := rawCurve(curve) - return asn1.RawValue{ - Tag: 30, - Bytes: raw[2:], - FullBytes: raw, - }, true - default: - return rv, false - } -} - -func asnECPublicKeyType(curve elliptic.Curve) (algo asnAlgorithmIdentifier, ok bool) { - raw, ok := curveToRaw(curve) - if !ok { - return - } else { - return asnAlgorithmIdentifier{Algorithm: idEcPublicKey, - Parameters: raw}, true - } -} - -type asnECPrivKeyVer int - -var asnECPrivKeyVer1 asnECPrivKeyVer = 1 - -type asnPrivateKey struct { - Version asnECPrivKeyVer - Private []byte - Curve secgNamedCurve `asn1:"optional"` - Public asn1.BitString -} - -var asnECDH = doScheme(secgScheme, []int{12}) - -type asnECDHAlgorithm asnAlgorithmIdentifier - -var ( - dhSinglePass_stdDH_sha1kdf = asnECDHAlgorithm{ - Algorithm: doScheme(x963Scheme, []int{2}), - } - dhSinglePass_stdDH_sha256kdf = asnECDHAlgorithm{ - Algorithm: doScheme(secgScheme, []int{11, 1}), - } - dhSinglePass_stdDH_sha384kdf = asnECDHAlgorithm{ - Algorithm: doScheme(secgScheme, []int{11, 2}), - } - dhSinglePass_stdDH_sha224kdf = asnECDHAlgorithm{ - Algorithm: doScheme(secgScheme, []int{11, 0}), - } - dhSinglePass_stdDH_sha512kdf = asnECDHAlgorithm{ - Algorithm: doScheme(secgScheme, []int{11, 3}), - } -) - -func (a asnECDHAlgorithm) Cmp(b asnECDHAlgorithm) bool { - if len(a.Algorithm) != len(b.Algorithm) { - return false - } - for i, _ := range a.Algorithm { - if a.Algorithm[i] != b.Algorithm[i] { - return false - } - } - return true -} - -// asnNISTConcatenation is the only supported KDF at this time. -type asnKeyDerivationFunction asnAlgorithmIdentifier - -var asnNISTConcatenationKDF = asnKeyDerivationFunction{ - Algorithm: doScheme(secgScheme, []int{17, 1}), -} - -func (a asnKeyDerivationFunction) Cmp(b asnKeyDerivationFunction) bool { - if len(a.Algorithm) != len(b.Algorithm) { - return false - } - for i, _ := range a.Algorithm { - if a.Algorithm[i] != b.Algorithm[i] { - return false - } - } - return true -} - -var eciesRecommendedParameters = doScheme(secgScheme, []int{7}) -var eciesSpecifiedParameters = doScheme(secgScheme, []int{8}) - -type asnECIESParameters struct { - KDF asnKeyDerivationFunction `asn1:"optional"` - Sym asnSymmetricEncryption `asn1:"optional"` - MAC asnMessageAuthenticationCode `asn1:"optional"` -} - -type asnSymmetricEncryption asnAlgorithmIdentifier - -var ( - aes128CTRinECIES = asnSymmetricEncryption{ - Algorithm: doScheme(secgScheme, []int{21, 0}), - } - aes192CTRinECIES = asnSymmetricEncryption{ - Algorithm: doScheme(secgScheme, []int{21, 1}), - } - aes256CTRinECIES = asnSymmetricEncryption{ - Algorithm: doScheme(secgScheme, []int{21, 2}), - } -) - -func (a asnSymmetricEncryption) Cmp(b asnSymmetricEncryption) bool { - if len(a.Algorithm) != len(b.Algorithm) { - return false - } - for i, _ := range a.Algorithm { - if a.Algorithm[i] != b.Algorithm[i] { - return false - } - } - return true -} - -type asnMessageAuthenticationCode asnAlgorithmIdentifier - -var ( - hmacFull = asnMessageAuthenticationCode{ - Algorithm: doScheme(secgScheme, []int{22}), - } -) - -func (a asnMessageAuthenticationCode) Cmp(b asnMessageAuthenticationCode) bool { - if len(a.Algorithm) != len(b.Algorithm) { - return false - } - for i, _ := range a.Algorithm { - if a.Algorithm[i] != b.Algorithm[i] { - return false - } - } - return true -} - -type ecpksSupplements struct { - ECDomain secgNamedCurve - ECCAlgorithms eccAlgorithmSet -} - -type eccAlgorithmSet struct { - ECDH asnECDHAlgorithm `asn1:"optional"` - ECIES asnECIESParameters `asn1:"optional"` -} - -func marshalSubjectPublicKeyInfo(pub *PublicKey) (subj asnSubjectPublicKeyInfo, err error) { - subj.Algorithm = idEcPublicKeySupplemented - curve, ok := oidFromNamedCurve(pub.Curve) - if !ok { - err = ErrInvalidPublicKey - return - } - subj.Supplements.ECDomain = curve - if pub.Params != nil { - subj.Supplements.ECCAlgorithms.ECDH = paramsToASNECDH(pub.Params) - subj.Supplements.ECCAlgorithms.ECIES = paramsToASNECIES(pub.Params) - } - pubkey := elliptic.Marshal(pub.Curve, pub.X, pub.Y) - subj.PublicKey = asn1.BitString{ - BitLength: len(pubkey) * 8, - Bytes: pubkey, - } - return -} - -// Encode a public key to DER format. -func MarshalPublic(pub *PublicKey) ([]byte, error) { - subj, err := marshalSubjectPublicKeyInfo(pub) - if err != nil { - return nil, err - } - return asn1.Marshal(subj) -} - -// Decode a DER-encoded public key. -func UnmarshalPublic(in []byte) (pub *PublicKey, err error) { - var subj asnSubjectPublicKeyInfo - - if _, err = asn1.Unmarshal(in, &subj); err != nil { - return - } - if !subj.Algorithm.Equal(idEcPublicKeySupplemented) { - err = ErrInvalidPublicKey - return - } - pub = new(PublicKey) - pub.Curve = namedCurveFromOID(subj.Supplements.ECDomain) - x, y := elliptic.Unmarshal(pub.Curve, subj.PublicKey.Bytes) - if x == nil { - err = ErrInvalidPublicKey - return - } - pub.X = x - pub.Y = y - pub.Params = new(ECIESParams) - asnECIEStoParams(subj.Supplements.ECCAlgorithms.ECIES, pub.Params) - asnECDHtoParams(subj.Supplements.ECCAlgorithms.ECDH, pub.Params) - if pub.Params == nil { - if pub.Params = ParamsFromCurve(pub.Curve); pub.Params == nil { - err = ErrInvalidPublicKey - } - } - return -} - -func marshalPrivateKey(prv *PrivateKey) (ecprv asnPrivateKey, err error) { - ecprv.Version = asnECPrivKeyVer1 - ecprv.Private = prv.D.Bytes() - - var ok bool - ecprv.Curve, ok = oidFromNamedCurve(prv.PublicKey.Curve) - if !ok { - err = ErrInvalidPrivateKey - return - } - - var pub []byte - if pub, err = MarshalPublic(&prv.PublicKey); err != nil { - return - } else { - ecprv.Public = asn1.BitString{ - BitLength: len(pub) * 8, - Bytes: pub, - } - } - return -} - -// Encode a private key to DER format. -func MarshalPrivate(prv *PrivateKey) ([]byte, error) { - ecprv, err := marshalPrivateKey(prv) - if err != nil { - return nil, err - } - return asn1.Marshal(ecprv) -} - -// Decode a private key from a DER-encoded format. -func UnmarshalPrivate(in []byte) (prv *PrivateKey, err error) { - var ecprv asnPrivateKey - - if _, err = asn1.Unmarshal(in, &ecprv); err != nil { - return - } else if ecprv.Version != asnECPrivKeyVer1 { - err = ErrInvalidPrivateKey - return - } - - privateCurve := namedCurveFromOID(ecprv.Curve) - if privateCurve == nil { - err = ErrInvalidPrivateKey - return - } - - prv = new(PrivateKey) - prv.D = new(big.Int).SetBytes(ecprv.Private) - - if pub, err := UnmarshalPublic(ecprv.Public.Bytes); err != nil { - return nil, err - } else { - prv.PublicKey = *pub - } - - return -} - -// Export a public key to PEM format. -func ExportPublicPEM(pub *PublicKey) (out []byte, err error) { - der, err := MarshalPublic(pub) - if err != nil { - return - } - - var block pem.Block - block.Type = "ELLIPTIC CURVE PUBLIC KEY" - block.Bytes = der - - buf := new(bytes.Buffer) - err = pem.Encode(buf, &block) - if err != nil { - return - } else { - out = buf.Bytes() - } - return -} - -// Export a private key to PEM format. -func ExportPrivatePEM(prv *PrivateKey) (out []byte, err error) { - der, err := MarshalPrivate(prv) - if err != nil { - return - } - - var block pem.Block - block.Type = "ELLIPTIC CURVE PRIVATE KEY" - block.Bytes = der - - buf := new(bytes.Buffer) - err = pem.Encode(buf, &block) - if err != nil { - return - } else { - out = buf.Bytes() - } - return -} - -// Import a PEM-encoded public key. -func ImportPublicPEM(in []byte) (pub *PublicKey, err error) { - p, _ := pem.Decode(in) - if p == nil || p.Type != "ELLIPTIC CURVE PUBLIC KEY" { - return nil, ErrInvalidPublicKey - } - - pub, err = UnmarshalPublic(p.Bytes) - return -} - -// Import a PEM-encoded private key. -func ImportPrivatePEM(in []byte) (prv *PrivateKey, err error) { - p, _ := pem.Decode(in) - if p == nil || p.Type != "ELLIPTIC CURVE PRIVATE KEY" { - return nil, ErrInvalidPrivateKey - } - - prv, err = UnmarshalPrivate(p.Bytes) - return -} diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/ecies.go b/Godeps/_workspace/src/github.com/obscuren/ecies/ecies.go deleted file mode 100644 index 0e2403d47..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/ecies.go +++ /dev/null @@ -1,326 +0,0 @@ -package ecies - -import ( - "crypto/cipher" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/hmac" - "crypto/subtle" - "fmt" - "hash" - "io" - "math/big" -) - -var ( - ErrImport = fmt.Errorf("ecies: failed to import key") - ErrInvalidCurve = fmt.Errorf("ecies: invalid elliptic curve") - ErrInvalidParams = fmt.Errorf("ecies: invalid ECIES parameters") - ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key") - ErrSharedKeyTooBig = fmt.Errorf("ecies: shared key is too big") -) - -// PublicKey is a representation of an elliptic curve public key. -type PublicKey struct { - X *big.Int - Y *big.Int - elliptic.Curve - Params *ECIESParams -} - -// Export an ECIES public key as an ECDSA public key. -func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey { - return &ecdsa.PublicKey{pub.Curve, pub.X, pub.Y} -} - -// Import an ECDSA public key as an ECIES public key. -func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey { - return &PublicKey{ - X: pub.X, - Y: pub.Y, - Curve: pub.Curve, - Params: ParamsFromCurve(pub.Curve), - } -} - -// PrivateKey is a representation of an elliptic curve private key. -type PrivateKey struct { - PublicKey - D *big.Int -} - -// Export an ECIES private key as an ECDSA private key. -func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey { - pub := &prv.PublicKey - pubECDSA := pub.ExportECDSA() - return &ecdsa.PrivateKey{*pubECDSA, prv.D} -} - -// Import an ECDSA private key as an ECIES private key. -func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey { - pub := ImportECDSAPublic(&prv.PublicKey) - return &PrivateKey{*pub, prv.D} -} - -// Generate an elliptic curve public / private keypair. If params is nil, -// the recommended default paramters for the key will be chosen. -func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) { - pb, x, y, err := elliptic.GenerateKey(curve, rand) - if err != nil { - return - } - prv = new(PrivateKey) - prv.PublicKey.X = x - prv.PublicKey.Y = y - prv.PublicKey.Curve = curve - prv.D = new(big.Int).SetBytes(pb) - if params == nil { - params = ParamsFromCurve(curve) - } - prv.PublicKey.Params = params - return -} - -// MaxSharedKeyLength returns the maximum length of the shared key the -// public key can produce. -func MaxSharedKeyLength(pub *PublicKey) int { - return (pub.Curve.Params().BitSize + 7) / 8 -} - -// ECDH key agreement method used to establish secret keys for encryption. -func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) { - if prv.PublicKey.Curve != pub.Curve { - err = ErrInvalidCurve - return - } - x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, prv.D.Bytes()) - if x == nil || (x.BitLen()+7)/8 < (skLen+macLen) { - err = ErrSharedKeyTooBig - return - } - sk = x.Bytes()[:skLen+macLen] - return -} - -var ( - ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data") - ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long") - ErrInvalidMessage = fmt.Errorf("ecies: invalid message") -) - -var ( - big2To32 = new(big.Int).Exp(big.NewInt(2), big.NewInt(32), nil) - big2To32M1 = new(big.Int).Sub(big2To32, big.NewInt(1)) -) - -func incCounter(ctr []byte) { - if ctr[3]++; ctr[3] != 0 { - return - } else if ctr[2]++; ctr[2] != 0 { - return - } else if ctr[1]++; ctr[1] != 0 { - return - } else if ctr[0]++; ctr[0] != 0 { - return - } - return -} - -// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1). -func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) { - if s1 == nil { - s1 = make([]byte, 0) - } - - reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8) - if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 { - fmt.Println(big2To32M1) - return nil, ErrKeyDataTooLong - } - - counter := []byte{0, 0, 0, 1} - k = make([]byte, 0) - - for i := 0; i <= reps; i++ { - hash.Write(counter) - hash.Write(z) - hash.Write(s1) - k = append(k, hash.Sum(nil)...) - hash.Reset() - incCounter(counter) - } - - k = k[:kdLen] - return -} - -// messageTag computes the MAC of a message (called the tag) as per -// SEC 1, 3.5. -func messageTag(hash func() hash.Hash, km, msg, shared []byte) []byte { - if shared == nil { - shared = make([]byte, 0) - } - mac := hmac.New(hash, km) - mac.Write(msg) - tag := mac.Sum(nil) - return tag -} - -// Generate an initialisation vector for CTR mode. -func generateIV(params *ECIESParams, rand io.Reader) (iv []byte, err error) { - iv = make([]byte, params.BlockSize) - _, err = io.ReadFull(rand, iv) - return -} - -// symEncrypt carries out CTR encryption using the block cipher specified in the -// parameters. -func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, err error) { - c, err := params.Cipher(key) - if err != nil { - return - } - - iv, err := generateIV(params, rand) - if err != nil { - return - } - ctr := cipher.NewCTR(c, iv) - - ct = make([]byte, len(m)+params.BlockSize) - copy(ct, iv) - ctr.XORKeyStream(ct[params.BlockSize:], m) - return -} - -// symDecrypt carries out CTR decryption using the block cipher specified in -// the parameters -func symDecrypt(rand io.Reader, params *ECIESParams, key, ct []byte) (m []byte, err error) { - c, err := params.Cipher(key) - if err != nil { - return - } - - ctr := cipher.NewCTR(c, ct[:params.BlockSize]) - - m = make([]byte, len(ct)-params.BlockSize) - ctr.XORKeyStream(m, ct[params.BlockSize:]) - return -} - -// Encrypt encrypts a message using ECIES as specified in SEC 1, 5.1. If -// the shared information parameters aren't being used, they should be -// nil. -func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err error) { - params := pub.Params - if params == nil { - if params = ParamsFromCurve(pub.Curve); params == nil { - err = ErrUnsupportedECIESParameters - return - } - } - R, err := GenerateKey(rand, pub.Curve, params) - if err != nil { - return - } - - hash := params.Hash() - z, err := R.GenerateShared(pub, params.KeyLen, params.KeyLen) - if err != nil { - return - } - K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen) - if err != nil { - return - } - Ke := K[:params.KeyLen] - Km := K[params.KeyLen:] - hash.Write(Km) - Km = hash.Sum(nil) - hash.Reset() - - em, err := symEncrypt(rand, params, Ke, m) - if err != nil || len(em) <= params.BlockSize { - return - } - - d := messageTag(params.Hash, Km, em, s2) - - Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y) - ct = make([]byte, len(Rb)+len(em)+len(d)) - copy(ct, Rb) - copy(ct[len(Rb):], em) - copy(ct[len(Rb)+len(em):], d) - return -} - -// Decrypt decrypts an ECIES ciphertext. -func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err error) { - if c == nil || len(c) == 0 { - err = ErrInvalidMessage - return - } - params := prv.PublicKey.Params - if params == nil { - if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil { - err = ErrUnsupportedECIESParameters - return - } - } - hash := params.Hash() - - var ( - rLen int - hLen int = hash.Size() - mStart int - mEnd int - ) - - switch c[0] { - case 2, 3, 4: - rLen = ((prv.PublicKey.Curve.Params().BitSize + 7) / 4) - if len(c) < (rLen + hLen + 1) { - err = ErrInvalidMessage - return - } - default: - err = ErrInvalidPublicKey - return - } - - mStart = rLen - mEnd = len(c) - hLen - - R := new(PublicKey) - R.Curve = prv.PublicKey.Curve - R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen]) - if R.X == nil { - err = ErrInvalidPublicKey - return - } - - z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) - if err != nil { - return - } - - K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen) - if err != nil { - return - } - - Ke := K[:params.KeyLen] - Km := K[params.KeyLen:] - hash.Write(Km) - Km = hash.Sum(nil) - hash.Reset() - - d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) - if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { - err = ErrInvalidMessage - return - } - - m, err = symDecrypt(rand, params, Ke, c[mStart:mEnd]) - return -} diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/ecies_test.go b/Godeps/_workspace/src/github.com/obscuren/ecies/ecies_test.go deleted file mode 100644 index 943e4488e..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/ecies_test.go +++ /dev/null @@ -1,489 +0,0 @@ -package ecies - -import ( - "bytes" - "crypto/elliptic" - "crypto/rand" - "crypto/sha256" - "flag" - "fmt" - "io/ioutil" - "testing" -) - -var dumpEnc bool - -func init() { - flDump := flag.Bool("dump", false, "write encrypted test message to file") - flag.Parse() - dumpEnc = *flDump -} - -// Ensure the KDF generates appropriately sized keys. -func TestKDF(t *testing.T) { - msg := []byte("Hello, world") - h := sha256.New() - - k, err := concatKDF(h, msg, nil, 64) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - if len(k) != 64 { - fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n", - len(k)) - t.FailNow() - } -} - -var skLen int -var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match") - -// cmpParams compares a set of ECIES parameters. We assume, as per the -// docs, that AES is the only supported symmetric encryption algorithm. -func cmpParams(p1, p2 *ECIESParams) bool { - if p1.hashAlgo != p2.hashAlgo { - return false - } else if p1.KeyLen != p2.KeyLen { - return false - } else if p1.BlockSize != p2.BlockSize { - return false - } - return true -} - -// cmpPublic returns true if the two public keys represent the same pojnt. -func cmpPublic(pub1, pub2 PublicKey) bool { - if pub1.X == nil || pub1.Y == nil { - fmt.Println(ErrInvalidPublicKey.Error()) - return false - } - if pub2.X == nil || pub2.Y == nil { - fmt.Println(ErrInvalidPublicKey.Error()) - return false - } - pub1Out := elliptic.Marshal(pub1.Curve, pub1.X, pub1.Y) - pub2Out := elliptic.Marshal(pub2.Curve, pub2.X, pub2.Y) - - return bytes.Equal(pub1Out, pub2Out) -} - -// cmpPrivate returns true if the two private keys are the same. -func cmpPrivate(prv1, prv2 *PrivateKey) bool { - if prv1 == nil || prv1.D == nil { - return false - } else if prv2 == nil || prv2.D == nil { - return false - } else if prv1.D.Cmp(prv2.D) != 0 { - return false - } else { - return cmpPublic(prv1.PublicKey, prv2.PublicKey) - } -} - -// Validate the ECDH component. -func TestSharedKey(t *testing.T) { - prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - skLen = MaxSharedKeyLength(&prv1.PublicKey) / 2 - - prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if !bytes.Equal(sk1, sk2) { - fmt.Println(ErrBadSharedKeys.Error()) - t.FailNow() - } -} - -// Verify that the key generation code fails when too much key data is -// requested. -func TestTooBigSharedKey(t *testing.T) { - prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - _, err = prv1.GenerateShared(&prv2.PublicKey, skLen*2, skLen*2) - if err != ErrSharedKeyTooBig { - fmt.Println("ecdh: shared key should be too large for curve") - t.FailNow() - } - - _, err = prv2.GenerateShared(&prv1.PublicKey, skLen*2, skLen*2) - if err != ErrSharedKeyTooBig { - fmt.Println("ecdh: shared key should be too large for curve") - t.FailNow() - } -} - -// Ensure a public key can be successfully marshalled and unmarshalled, and -// that the decoded key is the same as the original. -func TestMarshalPublic(t *testing.T) { - prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - out, err := MarshalPublic(&prv.PublicKey) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - pub, err := UnmarshalPublic(out) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if !cmpPublic(prv.PublicKey, *pub) { - fmt.Println("ecies: failed to unmarshal public key") - t.FailNow() - } -} - -// Ensure that a private key can be encoded into DER format, and that -// the resulting key is properly parsed back into a public key. -func TestMarshalPrivate(t *testing.T) { - prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - out, err := MarshalPrivate(prv) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if dumpEnc { - ioutil.WriteFile("test.out", out, 0644) - } - - prv2, err := UnmarshalPrivate(out) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if !cmpPrivate(prv, prv2) { - fmt.Println("ecdh: private key import failed") - t.FailNow() - } -} - -// Ensure that a private key can be successfully encoded to PEM format, and -// the resulting key is properly parsed back in. -func TestPrivatePEM(t *testing.T) { - prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - out, err := ExportPrivatePEM(prv) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if dumpEnc { - ioutil.WriteFile("test.key", out, 0644) - } - - prv2, err := ImportPrivatePEM(out) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } else if !cmpPrivate(prv, prv2) { - fmt.Println("ecdh: import from PEM failed") - t.FailNow() - } -} - -// Ensure that a public key can be successfully encoded to PEM format, and -// the resulting key is properly parsed back in. -func TestPublicPEM(t *testing.T) { - prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - out, err := ExportPublicPEM(&prv.PublicKey) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if dumpEnc { - ioutil.WriteFile("test.pem", out, 0644) - } - - pub2, err := ImportPublicPEM(out) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } else if !cmpPublic(prv.PublicKey, *pub2) { - fmt.Println("ecdh: import from PEM failed") - t.FailNow() - } -} - -// Benchmark the generation of P256 keys. -func BenchmarkGenerateKeyP256(b *testing.B) { - for i := 0; i < b.N; i++ { - if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil { - fmt.Println(err.Error()) - b.FailNow() - } - } -} - -// Benchmark the generation of P256 shared keys. -func BenchmarkGenSharedKeyP256(b *testing.B) { - prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil) - if err != nil { - fmt.Println(err.Error()) - b.FailNow() - } - - for i := 0; i < b.N; i++ { - _, err := prv.GenerateShared(&prv.PublicKey, skLen, skLen) - if err != nil { - fmt.Println(err.Error()) - b.FailNow() - } - } -} - -// Verify that an encrypted message can be successfully decrypted. -func TestEncryptDecrypt(t *testing.T) { - prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - message := []byte("Hello, world.") - ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if !bytes.Equal(pt, message) { - fmt.Println("ecies: plaintext doesn't match message") - t.FailNow() - } - - _, err = prv1.Decrypt(rand.Reader, ct, nil, nil) - if err == nil { - fmt.Println("ecies: encryption should not have succeeded") - t.FailNow() - } -} - -// TestMarshalEncryption validates the encode/decode produces a valid -// ECIES encryption key. -func TestMarshalEncryption(t *testing.T) { - prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - out, err := MarshalPrivate(prv1) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - prv2, err := UnmarshalPrivate(out) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - message := []byte("Hello, world.") - ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - if !bytes.Equal(pt, message) { - fmt.Println("ecies: plaintext doesn't match message") - t.FailNow() - } - - _, err = prv1.Decrypt(rand.Reader, ct, nil, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - -} - -type testCase struct { - Curve elliptic.Curve - Name string - Expected bool -} - -var testCases = []testCase{ - testCase{ - Curve: elliptic.P224(), - Name: "P224", - Expected: false, - }, - testCase{ - Curve: elliptic.P256(), - Name: "P256", - Expected: true, - }, - testCase{ - Curve: elliptic.P384(), - Name: "P384", - Expected: true, - }, - testCase{ - Curve: elliptic.P521(), - Name: "P521", - Expected: true, - }, -} - -// Test parameter selection for each curve, and that P224 fails automatic -// parameter selection (see README for a discussion of P224). Ensures that -// selecting a set of parameters automatically for the given curve works. -func TestParamSelection(t *testing.T) { - for _, c := range testCases { - testParamSelection(t, c) - } -} - -func testParamSelection(t *testing.T, c testCase) { - params := ParamsFromCurve(c.Curve) - if params == nil && c.Expected { - fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name) - t.FailNow() - } else if params != nil && !c.Expected { - fmt.Printf("ecies: parameters should be invalid (%s)\n", - c.Name) - t.FailNow() - } - - prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Printf("%s (%s)\n", err.Error(), c.Name) - t.FailNow() - } - - prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Printf("%s (%s)\n", err.Error(), c.Name) - t.FailNow() - } - - message := []byte("Hello, world.") - ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) - if err != nil { - fmt.Printf("%s (%s)\n", err.Error(), c.Name) - t.FailNow() - } - - pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) - if err != nil { - fmt.Printf("%s (%s)\n", err.Error(), c.Name) - t.FailNow() - } - - if !bytes.Equal(pt, message) { - fmt.Printf("ecies: plaintext doesn't match message (%s)\n", - c.Name) - t.FailNow() - } - - _, err = prv1.Decrypt(rand.Reader, ct, nil, nil) - if err == nil { - fmt.Printf("ecies: encryption should not have succeeded (%s)\n", - c.Name) - t.FailNow() - } - -} - -// Ensure that the basic public key validation in the decryption operation -// works. -func TestBasicKeyValidation(t *testing.T) { - badBytes := []byte{0, 1, 5, 6, 7, 8, 9} - - prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - message := []byte("Hello, world.") - ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil) - if err != nil { - fmt.Println(err.Error()) - t.FailNow() - } - - for _, b := range badBytes { - ct[0] = b - _, err := prv.Decrypt(rand.Reader, ct, nil, nil) - if err != ErrInvalidPublicKey { - fmt.Println("ecies: validated an invalid key") - t.FailNow() - } - } -} diff --git a/Godeps/_workspace/src/github.com/obscuren/ecies/params.go b/Godeps/_workspace/src/github.com/obscuren/ecies/params.go deleted file mode 100644 index b968c7c17..000000000 --- a/Godeps/_workspace/src/github.com/obscuren/ecies/params.go +++ /dev/null @@ -1,187 +0,0 @@ -package ecies - -// This file contains parameters for ECIES encryption, specifying the -// symmetric encryption and HMAC parameters. - -import ( - "crypto" - "crypto/aes" - "crypto/cipher" - "crypto/elliptic" - "crypto/sha256" - "crypto/sha512" - "fmt" - "hash" -) - -// The default curve for this package is the NIST P256 curve, which -// provides security equivalent to AES-128. -var DefaultCurve = elliptic.P256() - -var ( - ErrUnsupportedECDHAlgorithm = fmt.Errorf("ecies: unsupported ECDH algorithm") - ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters") -) - -type ECIESParams struct { - Hash func() hash.Hash // hash function - hashAlgo crypto.Hash - Cipher func([]byte) (cipher.Block, error) // symmetric cipher - BlockSize int // block size of symmetric cipher - KeyLen int // length of symmetric key -} - -// Standard ECIES parameters: -// * ECIES using AES128 and HMAC-SHA-256-16 -// * ECIES using AES256 and HMAC-SHA-256-32 -// * ECIES using AES256 and HMAC-SHA-384-48 -// * ECIES using AES256 and HMAC-SHA-512-64 -var ( - ECIES_AES128_SHA256 *ECIESParams - ECIES_AES256_SHA256 *ECIESParams - ECIES_AES256_SHA384 *ECIESParams - ECIES_AES256_SHA512 *ECIESParams -) - -func init() { - ECIES_AES128_SHA256 = &ECIESParams{ - Hash: sha256.New, - hashAlgo: crypto.SHA256, - Cipher: aes.NewCipher, - BlockSize: aes.BlockSize, - KeyLen: 16, - } - - ECIES_AES256_SHA256 = &ECIESParams{ - Hash: sha256.New, - hashAlgo: crypto.SHA256, - Cipher: aes.NewCipher, - BlockSize: aes.BlockSize, - KeyLen: 32, - } - - ECIES_AES256_SHA384 = &ECIESParams{ - Hash: sha512.New384, - hashAlgo: crypto.SHA384, - Cipher: aes.NewCipher, - BlockSize: aes.BlockSize, - KeyLen: 32, - } - - ECIES_AES256_SHA512 = &ECIESParams{ - Hash: sha512.New, - hashAlgo: crypto.SHA512, - Cipher: aes.NewCipher, - BlockSize: aes.BlockSize, - KeyLen: 32, - } -} - -var paramsFromCurve = map[elliptic.Curve]*ECIESParams{ - elliptic.P256(): ECIES_AES128_SHA256, - elliptic.P384(): ECIES_AES256_SHA384, - elliptic.P521(): ECIES_AES256_SHA512, -} - -func AddParamsForCurve(curve elliptic.Curve, params *ECIESParams) { - paramsFromCurve[curve] = params -} - -// ParamsFromCurve selects parameters optimal for the selected elliptic curve. -// Only the curves P256, P384, and P512 are supported. -func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) { - return paramsFromCurve[curve] - - /* - switch curve { - case elliptic.P256(): - return ECIES_AES128_SHA256 - case elliptic.P384(): - return ECIES_AES256_SHA384 - case elliptic.P521(): - return ECIES_AES256_SHA512 - default: - return nil - } - */ -} - -// ASN.1 encode the ECIES parameters relevant to the encryption operations. -func paramsToASNECIES(params *ECIESParams) (asnParams asnECIESParameters) { - if nil == params { - return - } - asnParams.KDF = asnNISTConcatenationKDF - asnParams.MAC = hmacFull - switch params.KeyLen { - case 16: - asnParams.Sym = aes128CTRinECIES - case 24: - asnParams.Sym = aes192CTRinECIES - case 32: - asnParams.Sym = aes256CTRinECIES - } - return -} - -// ASN.1 encode the ECIES parameters relevant to ECDH. -func paramsToASNECDH(params *ECIESParams) (algo asnECDHAlgorithm) { - switch params.hashAlgo { - case crypto.SHA224: - algo = dhSinglePass_stdDH_sha224kdf - case crypto.SHA256: - algo = dhSinglePass_stdDH_sha256kdf - case crypto.SHA384: - algo = dhSinglePass_stdDH_sha384kdf - case crypto.SHA512: - algo = dhSinglePass_stdDH_sha512kdf - } - return -} - -// ASN.1 decode the ECIES parameters relevant to the encryption stage. -func asnECIEStoParams(asnParams asnECIESParameters, params *ECIESParams) { - if !asnParams.KDF.Cmp(asnNISTConcatenationKDF) { - params = nil - return - } else if !asnParams.MAC.Cmp(hmacFull) { - params = nil - return - } - - switch { - case asnParams.Sym.Cmp(aes128CTRinECIES): - params.KeyLen = 16 - params.BlockSize = 16 - params.Cipher = aes.NewCipher - case asnParams.Sym.Cmp(aes192CTRinECIES): - params.KeyLen = 24 - params.BlockSize = 16 - params.Cipher = aes.NewCipher - case asnParams.Sym.Cmp(aes256CTRinECIES): - params.KeyLen = 32 - params.BlockSize = 16 - params.Cipher = aes.NewCipher - default: - params = nil - } -} - -// ASN.1 decode the ECIES parameters relevant to ECDH. -func asnECDHtoParams(asnParams asnECDHAlgorithm, params *ECIESParams) { - if asnParams.Cmp(dhSinglePass_stdDH_sha224kdf) { - params.hashAlgo = crypto.SHA224 - params.Hash = sha256.New224 - } else if asnParams.Cmp(dhSinglePass_stdDH_sha256kdf) { - params.hashAlgo = crypto.SHA256 - params.Hash = sha256.New - } else if asnParams.Cmp(dhSinglePass_stdDH_sha384kdf) { - params.hashAlgo = crypto.SHA384 - params.Hash = sha512.New384 - } else if asnParams.Cmp(dhSinglePass_stdDH_sha512kdf) { - params.hashAlgo = crypto.SHA512 - params.Hash = sha512.New - } else { - params = nil - } -} diff --git a/p2p/crypto_test.go b/p2p/crypto_test.go index 0a9d49f96..6cf0f4818 100644 --- a/p2p/crypto_test.go +++ b/p2p/crypto_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/crypto" - "github.com/obscuren/ecies" + "github.com/ethereum/go-ethereum/crypto/ecies" ) func TestPublicKeyEncoding(t *testing.T) { -- cgit v1.2.3 From bb346a3ae1b6c250fdcb28b97280d3512a7fe219 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Feb 2015 12:37:09 +0100 Subject: rpc/ws: switch to golang.org/x/net code.google.com/p/go.net is deprecated and will cause problems in future versions of Go. --- Godeps/Godeps.json | 9 +- .../code.google.com/p/go.net/websocket/client.go | 98 ---- .../p/go.net/websocket/exampledial_test.go | 31 -- .../p/go.net/websocket/examplehandler_test.go | 26 - .../src/code.google.com/p/go.net/websocket/hybi.go | 564 -------------------- .../p/go.net/websocket/hybi_test.go | 590 --------------------- .../code.google.com/p/go.net/websocket/server.go | 114 ---- .../p/go.net/websocket/websocket.go | 411 -------------- .../p/go.net/websocket/websocket_test.go | 341 ------------ .../src/golang.org/x/net/websocket/client.go | 112 ++++ .../golang.org/x/net/websocket/exampledial_test.go | 31 ++ .../x/net/websocket/examplehandler_test.go | 26 + .../src/golang.org/x/net/websocket/hybi.go | 564 ++++++++++++++++++++ .../src/golang.org/x/net/websocket/hybi_test.go | 590 +++++++++++++++++++++ .../src/golang.org/x/net/websocket/server.go | 114 ++++ .../src/golang.org/x/net/websocket/websocket.go | 411 ++++++++++++++ .../golang.org/x/net/websocket/websocket_test.go | 414 +++++++++++++++ rpc/ws/server.go | 2 +- 18 files changed, 2267 insertions(+), 2181 deletions(-) delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/client.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/server.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 9fa7373c8..37176ddba 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -30,11 +30,6 @@ "Comment": "null-236", "Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" }, - { - "ImportPath": "code.google.com/p/go.net/websocket", - "Comment": "null-173", - "Rev": "4231557d7c726df4cf9a4e8cdd8a417c8c200bdb" - }, { "ImportPath": "code.google.com/p/snappy-go/snappy", "Comment": "null-15", @@ -105,6 +100,10 @@ "ImportPath": "golang.org/x/crypto/pbkdf2", "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, + { + "ImportPath": "golang.org/x/net/websocket", + "Rev": "59b0df9b1f7abda5aab0495ee54f408daf182ce7" + }, { "ImportPath": "gopkg.in/check.v1", "Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673" diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go deleted file mode 100644 index a861bb92c..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/client.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "crypto/tls" - "io" - "net" - "net/http" - "net/url" -) - -// DialError is an error that occurs while dialling a websocket server. -type DialError struct { - *Config - Err error -} - -func (e *DialError) Error() string { - return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error() -} - -// NewConfig creates a new WebSocket config for client connection. -func NewConfig(server, origin string) (config *Config, err error) { - config = new(Config) - config.Version = ProtocolVersionHybi13 - config.Location, err = url.ParseRequestURI(server) - if err != nil { - return - } - config.Origin, err = url.ParseRequestURI(origin) - if err != nil { - return - } - config.Header = http.Header(make(map[string][]string)) - return -} - -// NewClient creates a new WebSocket client connection over rwc. -func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) { - br := bufio.NewReader(rwc) - bw := bufio.NewWriter(rwc) - err = hybiClientHandshake(config, br, bw) - if err != nil { - return - } - buf := bufio.NewReadWriter(br, bw) - ws = newHybiClientConn(config, buf, rwc) - return -} - -// Dial opens a new client connection to a WebSocket. -func Dial(url_, protocol, origin string) (ws *Conn, err error) { - config, err := NewConfig(url_, origin) - if err != nil { - return nil, err - } - if protocol != "" { - config.Protocol = []string{protocol} - } - return DialConfig(config) -} - -// DialConfig opens a new client connection to a WebSocket with a config. -func DialConfig(config *Config) (ws *Conn, err error) { - var client net.Conn - if config.Location == nil { - return nil, &DialError{config, ErrBadWebSocketLocation} - } - if config.Origin == nil { - return nil, &DialError{config, ErrBadWebSocketOrigin} - } - switch config.Location.Scheme { - case "ws": - client, err = net.Dial("tcp", config.Location.Host) - - case "wss": - client, err = tls.Dial("tcp", config.Location.Host, config.TlsConfig) - - default: - err = ErrBadScheme - } - if err != nil { - goto Error - } - - ws, err = NewClient(config, client) - if err != nil { - goto Error - } - return - -Error: - return nil, &DialError{config, err} -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go deleted file mode 100644 index 777a66895..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/exampledial_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket_test - -import ( - "fmt" - "log" - - "code.google.com/p/go.net/websocket" -) - -// This example demonstrates a trivial client. -func ExampleDial() { - origin := "http://localhost/" - url := "ws://localhost:12345/ws" - ws, err := websocket.Dial(url, "", origin) - if err != nil { - log.Fatal(err) - } - if _, err := ws.Write([]byte("hello, world!\n")); err != nil { - log.Fatal(err) - } - var msg = make([]byte, 512) - var n int - if n, err = ws.Read(msg); err != nil { - log.Fatal(err) - } - fmt.Printf("Received: %s.\n", msg[:n]) -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go deleted file mode 100644 index 47b0bb9b5..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/examplehandler_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket_test - -import ( - "io" - "net/http" - - "code.google.com/p/go.net/websocket" -) - -// Echo the data received on the WebSocket. -func EchoServer(ws *websocket.Conn) { - io.Copy(ws, ws) -} - -// This example demonstrates a trivial echo server. -func ExampleHandler() { - http.Handle("/echo", websocket.Handler(EchoServer)) - err := http.ListenAndServe(":12345", nil) - if err != nil { - panic("ListenAndServe: " + err.Error()) - } -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go deleted file mode 100644 index f8c0b2e29..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi.go +++ /dev/null @@ -1,564 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -// This file implements a protocol of hybi draft. -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 - -import ( - "bufio" - "bytes" - "crypto/rand" - "crypto/sha1" - "encoding/base64" - "encoding/binary" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strings" -) - -const ( - websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - - closeStatusNormal = 1000 - closeStatusGoingAway = 1001 - closeStatusProtocolError = 1002 - closeStatusUnsupportedData = 1003 - closeStatusFrameTooLarge = 1004 - closeStatusNoStatusRcvd = 1005 - closeStatusAbnormalClosure = 1006 - closeStatusBadMessageData = 1007 - closeStatusPolicyViolation = 1008 - closeStatusTooBigData = 1009 - closeStatusExtensionMismatch = 1010 - - maxControlFramePayloadLength = 125 -) - -var ( - ErrBadMaskingKey = &ProtocolError{"bad masking key"} - ErrBadPongMessage = &ProtocolError{"bad pong message"} - ErrBadClosingStatus = &ProtocolError{"bad closing status"} - ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"} - ErrNotImplemented = &ProtocolError{"not implemented"} - - handshakeHeader = map[string]bool{ - "Host": true, - "Upgrade": true, - "Connection": true, - "Sec-Websocket-Key": true, - "Sec-Websocket-Origin": true, - "Sec-Websocket-Version": true, - "Sec-Websocket-Protocol": true, - "Sec-Websocket-Accept": true, - } -) - -// A hybiFrameHeader is a frame header as defined in hybi draft. -type hybiFrameHeader struct { - Fin bool - Rsv [3]bool - OpCode byte - Length int64 - MaskingKey []byte - - data *bytes.Buffer -} - -// A hybiFrameReader is a reader for hybi frame. -type hybiFrameReader struct { - reader io.Reader - - header hybiFrameHeader - pos int64 - length int -} - -func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) { - n, err = frame.reader.Read(msg) - if err != nil { - return 0, err - } - if frame.header.MaskingKey != nil { - for i := 0; i < n; i++ { - msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4] - frame.pos++ - } - } - return n, err -} - -func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode } - -func (frame *hybiFrameReader) HeaderReader() io.Reader { - if frame.header.data == nil { - return nil - } - if frame.header.data.Len() == 0 { - return nil - } - return frame.header.data -} - -func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil } - -func (frame *hybiFrameReader) Len() (n int) { return frame.length } - -// A hybiFrameReaderFactory creates new frame reader based on its frame type. -type hybiFrameReaderFactory struct { - *bufio.Reader -} - -// NewFrameReader reads a frame header from the connection, and creates new reader for the frame. -// See Section 5.2 Base Framing protocol for detail. -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2 -func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) { - hybiFrame := new(hybiFrameReader) - frame = hybiFrame - var header []byte - var b byte - // First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits) - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0 - for i := 0; i < 3; i++ { - j := uint(6 - i) - hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0 - } - hybiFrame.header.OpCode = header[0] & 0x0f - - // Second byte. Mask/Payload len(7bits) - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - mask := (b & 0x80) != 0 - b &= 0x7f - lengthFields := 0 - switch { - case b <= 125: // Payload length 7bits. - hybiFrame.header.Length = int64(b) - case b == 126: // Payload length 7+16bits - lengthFields = 2 - case b == 127: // Payload length 7+64bits - lengthFields = 8 - } - for i := 0; i < lengthFields; i++ { - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b) - } - if mask { - // Masking key. 4 bytes. - for i := 0; i < 4; i++ { - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b) - } - } - hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length) - hybiFrame.header.data = bytes.NewBuffer(header) - hybiFrame.length = len(header) + int(hybiFrame.header.Length) - return -} - -// A HybiFrameWriter is a writer for hybi frame. -type hybiFrameWriter struct { - writer *bufio.Writer - - header *hybiFrameHeader -} - -func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) { - var header []byte - var b byte - if frame.header.Fin { - b |= 0x80 - } - for i := 0; i < 3; i++ { - if frame.header.Rsv[i] { - j := uint(6 - i) - b |= 1 << j - } - } - b |= frame.header.OpCode - header = append(header, b) - if frame.header.MaskingKey != nil { - b = 0x80 - } else { - b = 0 - } - lengthFields := 0 - length := len(msg) - switch { - case length <= 125: - b |= byte(length) - case length < 65536: - b |= 126 - lengthFields = 2 - default: - b |= 127 - lengthFields = 8 - } - header = append(header, b) - for i := 0; i < lengthFields; i++ { - j := uint((lengthFields - i - 1) * 8) - b = byte((length >> j) & 0xff) - header = append(header, b) - } - if frame.header.MaskingKey != nil { - if len(frame.header.MaskingKey) != 4 { - return 0, ErrBadMaskingKey - } - header = append(header, frame.header.MaskingKey...) - frame.writer.Write(header) - data := make([]byte, length) - for i := range data { - data[i] = msg[i] ^ frame.header.MaskingKey[i%4] - } - frame.writer.Write(data) - err = frame.writer.Flush() - return length, err - } - frame.writer.Write(header) - frame.writer.Write(msg) - err = frame.writer.Flush() - return length, err -} - -func (frame *hybiFrameWriter) Close() error { return nil } - -type hybiFrameWriterFactory struct { - *bufio.Writer - needMaskingKey bool -} - -func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType} - if buf.needMaskingKey { - frameHeader.MaskingKey, err = generateMaskingKey() - if err != nil { - return nil, err - } - } - return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil -} - -type hybiFrameHandler struct { - conn *Conn - payloadType byte -} - -func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader, err error) { - if handler.conn.IsServerConn() { - // The client MUST mask all frames sent to the server. - if frame.(*hybiFrameReader).header.MaskingKey == nil { - handler.WriteClose(closeStatusProtocolError) - return nil, io.EOF - } - } else { - // The server MUST NOT mask all frames. - if frame.(*hybiFrameReader).header.MaskingKey != nil { - handler.WriteClose(closeStatusProtocolError) - return nil, io.EOF - } - } - if header := frame.HeaderReader(); header != nil { - io.Copy(ioutil.Discard, header) - } - switch frame.PayloadType() { - case ContinuationFrame: - frame.(*hybiFrameReader).header.OpCode = handler.payloadType - case TextFrame, BinaryFrame: - handler.payloadType = frame.PayloadType() - case CloseFrame: - return nil, io.EOF - case PingFrame: - pingMsg := make([]byte, maxControlFramePayloadLength) - n, err := io.ReadFull(frame, pingMsg) - if err != nil && err != io.ErrUnexpectedEOF { - return nil, err - } - io.Copy(ioutil.Discard, frame) - n, err = handler.WritePong(pingMsg[:n]) - if err != nil { - return nil, err - } - return nil, nil - case PongFrame: - return nil, ErrNotImplemented - } - return frame, nil -} - -func (handler *hybiFrameHandler) WriteClose(status int) (err error) { - handler.conn.wio.Lock() - defer handler.conn.wio.Unlock() - w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame) - if err != nil { - return err - } - msg := make([]byte, 2) - binary.BigEndian.PutUint16(msg, uint16(status)) - _, err = w.Write(msg) - w.Close() - return err -} - -func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) { - handler.conn.wio.Lock() - defer handler.conn.wio.Unlock() - w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame) - if err != nil { - return 0, err - } - n, err = w.Write(msg) - w.Close() - return n, err -} - -// newHybiConn creates a new WebSocket connection speaking hybi draft protocol. -func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - if buf == nil { - br := bufio.NewReader(rwc) - bw := bufio.NewWriter(rwc) - buf = bufio.NewReadWriter(br, bw) - } - ws := &Conn{config: config, request: request, buf: buf, rwc: rwc, - frameReaderFactory: hybiFrameReaderFactory{buf.Reader}, - frameWriterFactory: hybiFrameWriterFactory{ - buf.Writer, request == nil}, - PayloadType: TextFrame, - defaultCloseStatus: closeStatusNormal} - ws.frameHandler = &hybiFrameHandler{conn: ws} - return ws -} - -// generateMaskingKey generates a masking key for a frame. -func generateMaskingKey() (maskingKey []byte, err error) { - maskingKey = make([]byte, 4) - if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil { - return - } - return -} - -// generateNonce generates a nonce consisting of a randomly selected 16-byte -// value that has been base64-encoded. -func generateNonce() (nonce []byte) { - key := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - panic(err) - } - nonce = make([]byte, 24) - base64.StdEncoding.Encode(nonce, key) - return -} - -// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of -// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string. -func getNonceAccept(nonce []byte) (expected []byte, err error) { - h := sha1.New() - if _, err = h.Write(nonce); err != nil { - return - } - if _, err = h.Write([]byte(websocketGUID)); err != nil { - return - } - expected = make([]byte, 28) - base64.StdEncoding.Encode(expected, h.Sum(nil)) - return -} - -// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17 -func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) { - bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n") - - bw.WriteString("Host: " + config.Location.Host + "\r\n") - bw.WriteString("Upgrade: websocket\r\n") - bw.WriteString("Connection: Upgrade\r\n") - nonce := generateNonce() - if config.handshakeData != nil { - nonce = []byte(config.handshakeData["key"]) - } - bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n") - bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n") - - if config.Version != ProtocolVersionHybi13 { - return ErrBadProtocolVersion - } - - bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n") - if len(config.Protocol) > 0 { - bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n") - } - // TODO(ukai): send Sec-WebSocket-Extensions. - err = config.Header.WriteSubset(bw, handshakeHeader) - if err != nil { - return err - } - - bw.WriteString("\r\n") - if err = bw.Flush(); err != nil { - return err - } - - resp, err := http.ReadResponse(br, &http.Request{Method: "GET"}) - if err != nil { - return err - } - if resp.StatusCode != 101 { - return ErrBadStatus - } - if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" || - strings.ToLower(resp.Header.Get("Connection")) != "upgrade" { - return ErrBadUpgrade - } - expectedAccept, err := getNonceAccept(nonce) - if err != nil { - return err - } - if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) { - return ErrChallengeResponse - } - if resp.Header.Get("Sec-WebSocket-Extensions") != "" { - return ErrUnsupportedExtensions - } - offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol") - if offeredProtocol != "" { - protocolMatched := false - for i := 0; i < len(config.Protocol); i++ { - if config.Protocol[i] == offeredProtocol { - protocolMatched = true - break - } - } - if !protocolMatched { - return ErrBadWebSocketProtocol - } - config.Protocol = []string{offeredProtocol} - } - - return nil -} - -// newHybiClientConn creates a client WebSocket connection after handshake. -func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn { - return newHybiConn(config, buf, rwc, nil) -} - -// A HybiServerHandshaker performs a server handshake using hybi draft protocol. -type hybiServerHandshaker struct { - *Config - accept []byte -} - -func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) { - c.Version = ProtocolVersionHybi13 - if req.Method != "GET" { - return http.StatusMethodNotAllowed, ErrBadRequestMethod - } - // HTTP version can be safely ignored. - - if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" || - !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { - return http.StatusBadRequest, ErrNotWebSocket - } - - key := req.Header.Get("Sec-Websocket-Key") - if key == "" { - return http.StatusBadRequest, ErrChallengeResponse - } - version := req.Header.Get("Sec-Websocket-Version") - switch version { - case "13": - c.Version = ProtocolVersionHybi13 - default: - return http.StatusBadRequest, ErrBadWebSocketVersion - } - var scheme string - if req.TLS != nil { - scheme = "wss" - } else { - scheme = "ws" - } - c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI()) - if err != nil { - return http.StatusBadRequest, err - } - protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol")) - if protocol != "" { - protocols := strings.Split(protocol, ",") - for i := 0; i < len(protocols); i++ { - c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) - } - } - c.accept, err = getNonceAccept([]byte(key)) - if err != nil { - return http.StatusInternalServerError, err - } - return http.StatusSwitchingProtocols, nil -} - -// Origin parses Origin header in "req". -// If origin is "null", returns (nil, nil). -func Origin(config *Config, req *http.Request) (*url.URL, error) { - var origin string - switch config.Version { - case ProtocolVersionHybi13: - origin = req.Header.Get("Origin") - } - if origin == "null" { - return nil, nil - } - return url.ParseRequestURI(origin) -} - -func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) { - if len(c.Protocol) > 0 { - if len(c.Protocol) != 1 { - // You need choose a Protocol in Handshake func in Server. - return ErrBadWebSocketProtocol - } - } - buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n") - buf.WriteString("Upgrade: websocket\r\n") - buf.WriteString("Connection: Upgrade\r\n") - buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n") - if len(c.Protocol) > 0 { - buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n") - } - // TODO(ukai): send Sec-WebSocket-Extensions. - if c.Header != nil { - err := c.Header.WriteSubset(buf, handshakeHeader) - if err != nil { - return err - } - } - buf.WriteString("\r\n") - return buf.Flush() -} - -func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - return newHybiServerConn(c.Config, buf, rwc, request) -} - -// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol. -func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - return newHybiConn(config, buf, rwc, request) -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go deleted file mode 100644 index d6a19108a..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/hybi_test.go +++ /dev/null @@ -1,590 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "bytes" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "testing" -) - -// Test the getNonceAccept function with values in -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 -func TestSecWebSocketAccept(t *testing.T) { - nonce := []byte("dGhlIHNhbXBsZSBub25jZQ==") - expected := []byte("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=") - accept, err := getNonceAccept(nonce) - if err != nil { - t.Errorf("getNonceAccept: returned error %v", err) - return - } - if !bytes.Equal(expected, accept) { - t.Errorf("getNonceAccept: expected %q got %q", expected, accept) - } -} - -func TestHybiClientHandshake(t *testing.T) { - b := bytes.NewBuffer([]byte{}) - bw := bufio.NewWriter(b) - br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols -Upgrade: websocket -Connection: Upgrade -Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= -Sec-WebSocket-Protocol: chat - -`)) - var err error - config := new(Config) - config.Location, err = url.ParseRequestURI("ws://server.example.com/chat") - if err != nil { - t.Fatal("location url", err) - } - config.Origin, err = url.ParseRequestURI("http://example.com") - if err != nil { - t.Fatal("origin url", err) - } - config.Protocol = append(config.Protocol, "chat") - config.Protocol = append(config.Protocol, "superchat") - config.Version = ProtocolVersionHybi13 - - config.handshakeData = map[string]string{ - "key": "dGhlIHNhbXBsZSBub25jZQ==", - } - err = hybiClientHandshake(config, br, bw) - if err != nil { - t.Errorf("handshake failed: %v", err) - } - req, err := http.ReadRequest(bufio.NewReader(b)) - if err != nil { - t.Fatalf("read request: %v", err) - } - if req.Method != "GET" { - t.Errorf("request method expected GET, but got %q", req.Method) - } - if req.URL.Path != "/chat" { - t.Errorf("request path expected /chat, but got %q", req.URL.Path) - } - if req.Proto != "HTTP/1.1" { - t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) - } - if req.Host != "server.example.com" { - t.Errorf("request Host expected server.example.com, but got %v", req.Host) - } - var expectedHeader = map[string]string{ - "Connection": "Upgrade", - "Upgrade": "websocket", - "Sec-Websocket-Key": config.handshakeData["key"], - "Origin": config.Origin.String(), - "Sec-Websocket-Protocol": "chat, superchat", - "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), - } - for k, v := range expectedHeader { - if req.Header.Get(k) != v { - t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k))) - } - } -} - -func TestHybiClientHandshakeWithHeader(t *testing.T) { - b := bytes.NewBuffer([]byte{}) - bw := bufio.NewWriter(b) - br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols -Upgrade: websocket -Connection: Upgrade -Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= -Sec-WebSocket-Protocol: chat - -`)) - var err error - config := new(Config) - config.Location, err = url.ParseRequestURI("ws://server.example.com/chat") - if err != nil { - t.Fatal("location url", err) - } - config.Origin, err = url.ParseRequestURI("http://example.com") - if err != nil { - t.Fatal("origin url", err) - } - config.Protocol = append(config.Protocol, "chat") - config.Protocol = append(config.Protocol, "superchat") - config.Version = ProtocolVersionHybi13 - config.Header = http.Header(make(map[string][]string)) - config.Header.Add("User-Agent", "test") - - config.handshakeData = map[string]string{ - "key": "dGhlIHNhbXBsZSBub25jZQ==", - } - err = hybiClientHandshake(config, br, bw) - if err != nil { - t.Errorf("handshake failed: %v", err) - } - req, err := http.ReadRequest(bufio.NewReader(b)) - if err != nil { - t.Fatalf("read request: %v", err) - } - if req.Method != "GET" { - t.Errorf("request method expected GET, but got %q", req.Method) - } - if req.URL.Path != "/chat" { - t.Errorf("request path expected /chat, but got %q", req.URL.Path) - } - if req.Proto != "HTTP/1.1" { - t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) - } - if req.Host != "server.example.com" { - t.Errorf("request Host expected server.example.com, but got %v", req.Host) - } - var expectedHeader = map[string]string{ - "Connection": "Upgrade", - "Upgrade": "websocket", - "Sec-Websocket-Key": config.handshakeData["key"], - "Origin": config.Origin.String(), - "Sec-Websocket-Protocol": "chat, superchat", - "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), - "User-Agent": "test", - } - for k, v := range expectedHeader { - if req.Header.Get(k) != v { - t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k))) - } - } -} - -func TestHybiServerHandshake(t *testing.T) { - config := new(Config) - handshaker := &hybiServerHandshaker{Config: config} - br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 -Host: server.example.com -Upgrade: websocket -Connection: Upgrade -Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== -Origin: http://example.com -Sec-WebSocket-Protocol: chat, superchat -Sec-WebSocket-Version: 13 - -`)) - req, err := http.ReadRequest(br) - if err != nil { - t.Fatal("request", err) - } - code, err := handshaker.ReadHandshake(br, req) - if err != nil { - t.Errorf("handshake failed: %v", err) - } - if code != http.StatusSwitchingProtocols { - t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) - } - expectedProtocols := []string{"chat", "superchat"} - if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) { - t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol) - } - b := bytes.NewBuffer([]byte{}) - bw := bufio.NewWriter(b) - - config.Protocol = config.Protocol[:1] - - err = handshaker.AcceptHandshake(bw) - if err != nil { - t.Errorf("handshake response failed: %v", err) - } - expectedResponse := strings.Join([]string{ - "HTTP/1.1 101 Switching Protocols", - "Upgrade: websocket", - "Connection: Upgrade", - "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", - "Sec-WebSocket-Protocol: chat", - "", ""}, "\r\n") - - if b.String() != expectedResponse { - t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) - } -} - -func TestHybiServerHandshakeNoSubProtocol(t *testing.T) { - config := new(Config) - handshaker := &hybiServerHandshaker{Config: config} - br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 -Host: server.example.com -Upgrade: websocket -Connection: Upgrade -Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== -Origin: http://example.com -Sec-WebSocket-Version: 13 - -`)) - req, err := http.ReadRequest(br) - if err != nil { - t.Fatal("request", err) - } - code, err := handshaker.ReadHandshake(br, req) - if err != nil { - t.Errorf("handshake failed: %v", err) - } - if code != http.StatusSwitchingProtocols { - t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) - } - if len(config.Protocol) != 0 { - t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol)) - } - b := bytes.NewBuffer([]byte{}) - bw := bufio.NewWriter(b) - - err = handshaker.AcceptHandshake(bw) - if err != nil { - t.Errorf("handshake response failed: %v", err) - } - expectedResponse := strings.Join([]string{ - "HTTP/1.1 101 Switching Protocols", - "Upgrade: websocket", - "Connection: Upgrade", - "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", - "", ""}, "\r\n") - - if b.String() != expectedResponse { - t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) - } -} - -func TestHybiServerHandshakeHybiBadVersion(t *testing.T) { - config := new(Config) - handshaker := &hybiServerHandshaker{Config: config} - br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 -Host: server.example.com -Upgrade: websocket -Connection: Upgrade -Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== -Sec-WebSocket-Origin: http://example.com -Sec-WebSocket-Protocol: chat, superchat -Sec-WebSocket-Version: 9 - -`)) - req, err := http.ReadRequest(br) - if err != nil { - t.Fatal("request", err) - } - code, err := handshaker.ReadHandshake(br, req) - if err != ErrBadWebSocketVersion { - t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err) - } - if code != http.StatusBadRequest { - t.Errorf("status expected %q but got %q", http.StatusBadRequest, code) - } -} - -func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) { - b := bytes.NewBuffer([]byte{}) - frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false} - w, _ := frameWriterFactory.NewFrameWriter(TextFrame) - w.(*hybiFrameWriter).header = frameHeader - _, err := w.Write(testPayload) - w.Close() - if err != nil { - t.Errorf("Write error %q", err) - } - var expectedFrame []byte - expectedFrame = append(expectedFrame, testHeader...) - expectedFrame = append(expectedFrame, testMaskedPayload...) - if !bytes.Equal(expectedFrame, b.Bytes()) { - t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes()) - } - frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)} - r, err := frameReaderFactory.NewFrameReader() - if err != nil { - t.Errorf("Read error %q", err) - } - if header := r.HeaderReader(); header == nil { - t.Errorf("no header") - } else { - actualHeader := make([]byte, r.Len()) - n, err := header.Read(actualHeader) - if err != nil { - t.Errorf("Read header error %q", err) - } else { - if n < len(testHeader) { - t.Errorf("header too short %q got %q", testHeader, actualHeader[:n]) - } - if !bytes.Equal(testHeader, actualHeader[:n]) { - t.Errorf("header expected %q got %q", testHeader, actualHeader[:n]) - } - } - } - if trailer := r.TrailerReader(); trailer != nil { - t.Errorf("unexpected trailer %q", trailer) - } - frame := r.(*hybiFrameReader) - if frameHeader.Fin != frame.header.Fin || - frameHeader.OpCode != frame.header.OpCode || - len(testPayload) != int(frame.header.Length) { - t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame) - } - payload := make([]byte, len(testPayload)) - _, err = r.Read(payload) - if err != nil { - t.Errorf("read %v", err) - } - if !bytes.Equal(testPayload, payload) { - t.Errorf("payload %q vs %q", testPayload, payload) - } -} - -func TestHybiShortTextFrame(t *testing.T) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} - payload := []byte("hello") - testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader) - - payload = make([]byte, 125) - testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader) -} - -func TestHybiShortMaskedTextFrame(t *testing.T) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame, - MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}} - payload := []byte("hello") - maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3} - header := []byte{0x81, 0x85} - header = append(header, frameHeader.MaskingKey...) - testHybiFrame(t, header, payload, maskedPayload, frameHeader) -} - -func TestHybiShortBinaryFrame(t *testing.T) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame} - payload := []byte("hello") - testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader) - - payload = make([]byte, 125) - testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader) -} - -func TestHybiControlFrame(t *testing.T) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame} - payload := []byte("hello") - testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader) - - frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame} - testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader) - - frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame} - payload = []byte{0x03, 0xe8} // 1000 - testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader) -} - -func TestHybiLongFrame(t *testing.T) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} - payload := make([]byte, 126) - testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader) - - payload = make([]byte, 65535) - testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader) - - payload = make([]byte, 65536) - testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader) -} - -func TestHybiClientRead(t *testing.T) { - wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', - 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping - 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} - br := bufio.NewReader(bytes.NewBuffer(wireData)) - bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) - conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) - - msg := make([]byte, 512) - n, err := conn.Read(msg) - if err != nil { - t.Errorf("read 1st frame, error %q", err) - } - if n != 5 { - t.Errorf("read 1st frame, expect 5, got %d", n) - } - if !bytes.Equal(wireData[2:7], msg[:n]) { - t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n]) - } - n, err = conn.Read(msg) - if err != nil { - t.Errorf("read 2nd frame, error %q", err) - } - if n != 5 { - t.Errorf("read 2nd frame, expect 5, got %d", n) - } - if !bytes.Equal(wireData[16:21], msg[:n]) { - t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n]) - } - n, err = conn.Read(msg) - if err == nil { - t.Errorf("read not EOF") - } - if n != 0 { - t.Errorf("expect read 0, got %d", n) - } -} - -func TestHybiShortRead(t *testing.T) { - wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', - 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping - 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} - br := bufio.NewReader(bytes.NewBuffer(wireData)) - bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) - conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) - - step := 0 - pos := 0 - expectedPos := []int{2, 5, 16, 19} - expectedLen := []int{3, 2, 3, 2} - for { - msg := make([]byte, 3) - n, err := conn.Read(msg) - if step >= len(expectedPos) { - if err == nil { - t.Errorf("read not EOF") - } - if n != 0 { - t.Errorf("expect read 0, got %d", n) - } - return - } - pos = expectedPos[step] - endPos := pos + expectedLen[step] - if err != nil { - t.Errorf("read from %d, got error %q", pos, err) - return - } - if n != endPos-pos { - t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n) - } - if !bytes.Equal(wireData[pos:endPos], msg[:n]) { - t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n]) - } - step++ - } -} - -func TestHybiServerRead(t *testing.T) { - wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, - 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello - 0x89, 0x85, 0xcc, 0x55, 0x80, 0x20, - 0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello - 0x81, 0x85, 0xed, 0x83, 0xb4, 0x24, - 0x9a, 0xec, 0xc6, 0x48, 0x89, // world - } - br := bufio.NewReader(bytes.NewBuffer(wireData)) - bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) - conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) - - expected := [][]byte{[]byte("hello"), []byte("world")} - - msg := make([]byte, 512) - n, err := conn.Read(msg) - if err != nil { - t.Errorf("read 1st frame, error %q", err) - } - if n != 5 { - t.Errorf("read 1st frame, expect 5, got %d", n) - } - if !bytes.Equal(expected[0], msg[:n]) { - t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n]) - } - - n, err = conn.Read(msg) - if err != nil { - t.Errorf("read 2nd frame, error %q", err) - } - if n != 5 { - t.Errorf("read 2nd frame, expect 5, got %d", n) - } - if !bytes.Equal(expected[1], msg[:n]) { - t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n]) - } - - n, err = conn.Read(msg) - if err == nil { - t.Errorf("read not EOF") - } - if n != 0 { - t.Errorf("expect read 0, got %d", n) - } -} - -func TestHybiServerReadWithoutMasking(t *testing.T) { - wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'} - br := bufio.NewReader(bytes.NewBuffer(wireData)) - bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) - conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) - // server MUST close the connection upon receiving a non-masked frame. - msg := make([]byte, 512) - _, err := conn.Read(msg) - if err != io.EOF { - t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) - } -} - -func TestHybiClientReadWithMasking(t *testing.T) { - wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, - 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello - } - br := bufio.NewReader(bytes.NewBuffer(wireData)) - bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) - conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) - - // client MUST close the connection upon receiving a masked frame. - msg := make([]byte, 512) - _, err := conn.Read(msg) - if err != io.EOF { - t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) - } -} - -// Test the hybiServerHandshaker supports firefox implementation and -// checks Connection request header include (but it's not necessary -// equal to) "upgrade" -func TestHybiServerFirefoxHandshake(t *testing.T) { - config := new(Config) - handshaker := &hybiServerHandshaker{Config: config} - br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 -Host: server.example.com -Upgrade: websocket -Connection: keep-alive, upgrade -Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== -Origin: http://example.com -Sec-WebSocket-Protocol: chat, superchat -Sec-WebSocket-Version: 13 - -`)) - req, err := http.ReadRequest(br) - if err != nil { - t.Fatal("request", err) - } - code, err := handshaker.ReadHandshake(br, req) - if err != nil { - t.Errorf("handshake failed: %v", err) - } - if code != http.StatusSwitchingProtocols { - t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) - } - b := bytes.NewBuffer([]byte{}) - bw := bufio.NewWriter(b) - - config.Protocol = []string{"chat"} - - err = handshaker.AcceptHandshake(bw) - if err != nil { - t.Errorf("handshake response failed: %v", err) - } - expectedResponse := strings.Join([]string{ - "HTTP/1.1 101 Switching Protocols", - "Upgrade: websocket", - "Connection: Upgrade", - "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", - "Sec-WebSocket-Protocol: chat", - "", ""}, "\r\n") - - if b.String() != expectedResponse { - t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) - } -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go deleted file mode 100644 index 70322133c..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/server.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "fmt" - "io" - "net/http" -) - -func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) { - var hs serverHandshaker = &hybiServerHandshaker{Config: config} - code, err := hs.ReadHandshake(buf.Reader, req) - if err == ErrBadWebSocketVersion { - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion) - buf.WriteString("\r\n") - buf.WriteString(err.Error()) - buf.Flush() - return - } - if err != nil { - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.WriteString(err.Error()) - buf.Flush() - return - } - if handshake != nil { - err = handshake(config, req) - if err != nil { - code = http.StatusForbidden - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.Flush() - return - } - } - err = hs.AcceptHandshake(buf.Writer) - if err != nil { - code = http.StatusBadRequest - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.Flush() - return - } - conn = hs.NewServerConn(buf, rwc, req) - return -} - -// Server represents a server of a WebSocket. -type Server struct { - // Config is a WebSocket configuration for new WebSocket connection. - Config - - // Handshake is an optional function in WebSocket handshake. - // For example, you can check, or don't check Origin header. - // Another example, you can select config.Protocol. - Handshake func(*Config, *http.Request) error - - // Handler handles a WebSocket connection. - Handler -} - -// ServeHTTP implements the http.Handler interface for a WebSocket -func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s.serveWebSocket(w, req) -} - -func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) { - rwc, buf, err := w.(http.Hijacker).Hijack() - if err != nil { - panic("Hijack failed: " + err.Error()) - return - } - // The server should abort the WebSocket connection if it finds - // the client did not send a handshake that matches with protocol - // specification. - defer rwc.Close() - conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake) - if err != nil { - return - } - if conn == nil { - panic("unexpected nil conn") - } - s.Handler(conn) -} - -// Handler is a simple interface to a WebSocket browser client. -// It checks if Origin header is valid URL by default. -// You might want to verify websocket.Conn.Config().Origin in the func. -// If you use Server instead of Handler, you could call websocket.Origin and -// check the origin in your Handshake func. So, if you want to accept -// non-browser client, which doesn't send Origin header, you could use Server -//. that doesn't check origin in its Handshake. -type Handler func(*Conn) - -func checkOrigin(config *Config, req *http.Request) (err error) { - config.Origin, err = Origin(config, req) - if err == nil && config.Origin == nil { - return fmt.Errorf("null origin") - } - return err -} - -// ServeHTTP implements the http.Handler interface for a WebSocket -func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s := Server{Handler: h, Handshake: checkOrigin} - s.serveWebSocket(w, req) -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go deleted file mode 100644 index 0f4917bf7..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package websocket implements a client and server for the WebSocket protocol -// as specified in RFC 6455. -package websocket - -import ( - "bufio" - "crypto/tls" - "encoding/json" - "errors" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "sync" - "time" -) - -const ( - ProtocolVersionHybi13 = 13 - ProtocolVersionHybi = ProtocolVersionHybi13 - SupportedProtocolVersion = "13" - - ContinuationFrame = 0 - TextFrame = 1 - BinaryFrame = 2 - CloseFrame = 8 - PingFrame = 9 - PongFrame = 10 - UnknownFrame = 255 -) - -// ProtocolError represents WebSocket protocol errors. -type ProtocolError struct { - ErrorString string -} - -func (err *ProtocolError) Error() string { return err.ErrorString } - -var ( - ErrBadProtocolVersion = &ProtocolError{"bad protocol version"} - ErrBadScheme = &ProtocolError{"bad scheme"} - ErrBadStatus = &ProtocolError{"bad status"} - ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"} - ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"} - ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"} - ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"} - ErrBadWebSocketVersion = &ProtocolError{"missing or bad WebSocket Version"} - ErrChallengeResponse = &ProtocolError{"mismatch challenge/response"} - ErrBadFrame = &ProtocolError{"bad frame"} - ErrBadFrameBoundary = &ProtocolError{"not on frame boundary"} - ErrNotWebSocket = &ProtocolError{"not websocket protocol"} - ErrBadRequestMethod = &ProtocolError{"bad method"} - ErrNotSupported = &ProtocolError{"not supported"} -) - -// Addr is an implementation of net.Addr for WebSocket. -type Addr struct { - *url.URL -} - -// Network returns the network type for a WebSocket, "websocket". -func (addr *Addr) Network() string { return "websocket" } - -// Config is a WebSocket configuration -type Config struct { - // A WebSocket server address. - Location *url.URL - - // A Websocket client origin. - Origin *url.URL - - // WebSocket subprotocols. - Protocol []string - - // WebSocket protocol version. - Version int - - // TLS config for secure WebSocket (wss). - TlsConfig *tls.Config - - // Additional header fields to be sent in WebSocket opening handshake. - Header http.Header - - handshakeData map[string]string -} - -// serverHandshaker is an interface to handle WebSocket server side handshake. -type serverHandshaker interface { - // ReadHandshake reads handshake request message from client. - // Returns http response code and error if any. - ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) - - // AcceptHandshake accepts the client handshake request and sends - // handshake response back to client. - AcceptHandshake(buf *bufio.Writer) (err error) - - // NewServerConn creates a new WebSocket connection. - NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn) -} - -// frameReader is an interface to read a WebSocket frame. -type frameReader interface { - // Reader is to read payload of the frame. - io.Reader - - // PayloadType returns payload type. - PayloadType() byte - - // HeaderReader returns a reader to read header of the frame. - HeaderReader() io.Reader - - // TrailerReader returns a reader to read trailer of the frame. - // If it returns nil, there is no trailer in the frame. - TrailerReader() io.Reader - - // Len returns total length of the frame, including header and trailer. - Len() int -} - -// frameReaderFactory is an interface to creates new frame reader. -type frameReaderFactory interface { - NewFrameReader() (r frameReader, err error) -} - -// frameWriter is an interface to write a WebSocket frame. -type frameWriter interface { - // Writer is to write payload of the frame. - io.WriteCloser -} - -// frameWriterFactory is an interface to create new frame writer. -type frameWriterFactory interface { - NewFrameWriter(payloadType byte) (w frameWriter, err error) -} - -type frameHandler interface { - HandleFrame(frame frameReader) (r frameReader, err error) - WriteClose(status int) (err error) -} - -// Conn represents a WebSocket connection. -type Conn struct { - config *Config - request *http.Request - - buf *bufio.ReadWriter - rwc io.ReadWriteCloser - - rio sync.Mutex - frameReaderFactory - frameReader - - wio sync.Mutex - frameWriterFactory - - frameHandler - PayloadType byte - defaultCloseStatus int -} - -// Read implements the io.Reader interface: -// it reads data of a frame from the WebSocket connection. -// if msg is not large enough for the frame data, it fills the msg and next Read -// will read the rest of the frame data. -// it reads Text frame or Binary frame. -func (ws *Conn) Read(msg []byte) (n int, err error) { - ws.rio.Lock() - defer ws.rio.Unlock() -again: - if ws.frameReader == nil { - frame, err := ws.frameReaderFactory.NewFrameReader() - if err != nil { - return 0, err - } - ws.frameReader, err = ws.frameHandler.HandleFrame(frame) - if err != nil { - return 0, err - } - if ws.frameReader == nil { - goto again - } - } - n, err = ws.frameReader.Read(msg) - if err == io.EOF { - if trailer := ws.frameReader.TrailerReader(); trailer != nil { - io.Copy(ioutil.Discard, trailer) - } - ws.frameReader = nil - goto again - } - return n, err -} - -// Write implements the io.Writer interface: -// it writes data as a frame to the WebSocket connection. -func (ws *Conn) Write(msg []byte) (n int, err error) { - ws.wio.Lock() - defer ws.wio.Unlock() - w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType) - if err != nil { - return 0, err - } - n, err = w.Write(msg) - w.Close() - if err != nil { - return n, err - } - return n, err -} - -// Close implements the io.Closer interface. -func (ws *Conn) Close() error { - err := ws.frameHandler.WriteClose(ws.defaultCloseStatus) - if err != nil { - return err - } - return ws.rwc.Close() -} - -func (ws *Conn) IsClientConn() bool { return ws.request == nil } -func (ws *Conn) IsServerConn() bool { return ws.request != nil } - -// LocalAddr returns the WebSocket Origin for the connection for client, or -// the WebSocket location for server. -func (ws *Conn) LocalAddr() net.Addr { - if ws.IsClientConn() { - return &Addr{ws.config.Origin} - } - return &Addr{ws.config.Location} -} - -// RemoteAddr returns the WebSocket location for the connection for client, or -// the Websocket Origin for server. -func (ws *Conn) RemoteAddr() net.Addr { - if ws.IsClientConn() { - return &Addr{ws.config.Location} - } - return &Addr{ws.config.Origin} -} - -var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn") - -// SetDeadline sets the connection's network read & write deadlines. -func (ws *Conn) SetDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetDeadline(t) - } - return errSetDeadline -} - -// SetReadDeadline sets the connection's network read deadline. -func (ws *Conn) SetReadDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetReadDeadline(t) - } - return errSetDeadline -} - -// SetWriteDeadline sets the connection's network write deadline. -func (ws *Conn) SetWriteDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetWriteDeadline(t) - } - return errSetDeadline -} - -// Config returns the WebSocket config. -func (ws *Conn) Config() *Config { return ws.config } - -// Request returns the http request upgraded to the WebSocket. -// It is nil for client side. -func (ws *Conn) Request() *http.Request { return ws.request } - -// Codec represents a symmetric pair of functions that implement a codec. -type Codec struct { - Marshal func(v interface{}) (data []byte, payloadType byte, err error) - Unmarshal func(data []byte, payloadType byte, v interface{}) (err error) -} - -// Send sends v marshaled by cd.Marshal as single frame to ws. -func (cd Codec) Send(ws *Conn, v interface{}) (err error) { - data, payloadType, err := cd.Marshal(v) - if err != nil { - return err - } - ws.wio.Lock() - defer ws.wio.Unlock() - w, err := ws.frameWriterFactory.NewFrameWriter(payloadType) - if err != nil { - return err - } - _, err = w.Write(data) - w.Close() - return err -} - -// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v. -func (cd Codec) Receive(ws *Conn, v interface{}) (err error) { - ws.rio.Lock() - defer ws.rio.Unlock() - if ws.frameReader != nil { - _, err = io.Copy(ioutil.Discard, ws.frameReader) - if err != nil { - return err - } - ws.frameReader = nil - } -again: - frame, err := ws.frameReaderFactory.NewFrameReader() - if err != nil { - return err - } - frame, err = ws.frameHandler.HandleFrame(frame) - if err != nil { - return err - } - if frame == nil { - goto again - } - payloadType := frame.PayloadType() - data, err := ioutil.ReadAll(frame) - if err != nil { - return err - } - return cd.Unmarshal(data, payloadType, v) -} - -func marshal(v interface{}) (msg []byte, payloadType byte, err error) { - switch data := v.(type) { - case string: - return []byte(data), TextFrame, nil - case []byte: - return data, BinaryFrame, nil - } - return nil, UnknownFrame, ErrNotSupported -} - -func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) { - switch data := v.(type) { - case *string: - *data = string(msg) - return nil - case *[]byte: - *data = msg - return nil - } - return ErrNotSupported -} - -/* -Message is a codec to send/receive text/binary data in a frame on WebSocket connection. -To send/receive text frame, use string type. -To send/receive binary frame, use []byte type. - -Trivial usage: - - import "websocket" - - // receive text frame - var message string - websocket.Message.Receive(ws, &message) - - // send text frame - message = "hello" - websocket.Message.Send(ws, message) - - // receive binary frame - var data []byte - websocket.Message.Receive(ws, &data) - - // send binary frame - data = []byte{0, 1, 2} - websocket.Message.Send(ws, data) - -*/ -var Message = Codec{marshal, unmarshal} - -func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) { - msg, err = json.Marshal(v) - return msg, TextFrame, err -} - -func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) { - return json.Unmarshal(msg, v) -} - -/* -JSON is a codec to send/receive JSON data in a frame from a WebSocket connection. - -Trivial usage: - - import "websocket" - - type T struct { - Msg string - Count int - } - - // receive JSON type T - var data T - websocket.JSON.Receive(ws, &data) - - // send JSON type T - websocket.JSON.Send(ws, data) -*/ -var JSON = Codec{jsonMarshal, jsonUnmarshal} diff --git a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go b/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go deleted file mode 100644 index 48f14b696..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket_test.go +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bytes" - "fmt" - "io" - "log" - "net" - "net/http" - "net/http/httptest" - "net/url" - "strings" - "sync" - "testing" -) - -var serverAddr string -var once sync.Once - -func echoServer(ws *Conn) { io.Copy(ws, ws) } - -type Count struct { - S string - N int -} - -func countServer(ws *Conn) { - for { - var count Count - err := JSON.Receive(ws, &count) - if err != nil { - return - } - count.N++ - count.S = strings.Repeat(count.S, count.N) - err = JSON.Send(ws, count) - if err != nil { - return - } - } -} - -func subProtocolHandshake(config *Config, req *http.Request) error { - for _, proto := range config.Protocol { - if proto == "chat" { - config.Protocol = []string{proto} - return nil - } - } - return ErrBadWebSocketProtocol -} - -func subProtoServer(ws *Conn) { - for _, proto := range ws.Config().Protocol { - io.WriteString(ws, proto) - } -} - -func startServer() { - http.Handle("/echo", Handler(echoServer)) - http.Handle("/count", Handler(countServer)) - subproto := Server{ - Handshake: subProtocolHandshake, - Handler: Handler(subProtoServer), - } - http.Handle("/subproto", subproto) - server := httptest.NewServer(nil) - serverAddr = server.Listener.Addr().String() - log.Print("Test WebSocket server listening on ", serverAddr) -} - -func newConfig(t *testing.T, path string) *Config { - config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost") - return config -} - -func TestEcho(t *testing.T) { - once.Do(startServer) - - // websocket.Dial() - client, err := net.Dial("tcp", serverAddr) - if err != nil { - t.Fatal("dialing", err) - } - conn, err := NewClient(newConfig(t, "/echo"), client) - if err != nil { - t.Errorf("WebSocket handshake error: %v", err) - return - } - - msg := []byte("hello, world\n") - if _, err := conn.Write(msg); err != nil { - t.Errorf("Write: %v", err) - } - var actual_msg = make([]byte, 512) - n, err := conn.Read(actual_msg) - if err != nil { - t.Errorf("Read: %v", err) - } - actual_msg = actual_msg[0:n] - if !bytes.Equal(msg, actual_msg) { - t.Errorf("Echo: expected %q got %q", msg, actual_msg) - } - conn.Close() -} - -func TestAddr(t *testing.T) { - once.Do(startServer) - - // websocket.Dial() - client, err := net.Dial("tcp", serverAddr) - if err != nil { - t.Fatal("dialing", err) - } - conn, err := NewClient(newConfig(t, "/echo"), client) - if err != nil { - t.Errorf("WebSocket handshake error: %v", err) - return - } - - ra := conn.RemoteAddr().String() - if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") { - t.Errorf("Bad remote addr: %v", ra) - } - la := conn.LocalAddr().String() - if !strings.HasPrefix(la, "http://") { - t.Errorf("Bad local addr: %v", la) - } - conn.Close() -} - -func TestCount(t *testing.T) { - once.Do(startServer) - - // websocket.Dial() - client, err := net.Dial("tcp", serverAddr) - if err != nil { - t.Fatal("dialing", err) - } - conn, err := NewClient(newConfig(t, "/count"), client) - if err != nil { - t.Errorf("WebSocket handshake error: %v", err) - return - } - - var count Count - count.S = "hello" - if err := JSON.Send(conn, count); err != nil { - t.Errorf("Write: %v", err) - } - if err := JSON.Receive(conn, &count); err != nil { - t.Errorf("Read: %v", err) - } - if count.N != 1 { - t.Errorf("count: expected %d got %d", 1, count.N) - } - if count.S != "hello" { - t.Errorf("count: expected %q got %q", "hello", count.S) - } - if err := JSON.Send(conn, count); err != nil { - t.Errorf("Write: %v", err) - } - if err := JSON.Receive(conn, &count); err != nil { - t.Errorf("Read: %v", err) - } - if count.N != 2 { - t.Errorf("count: expected %d got %d", 2, count.N) - } - if count.S != "hellohello" { - t.Errorf("count: expected %q got %q", "hellohello", count.S) - } - conn.Close() -} - -func TestWithQuery(t *testing.T) { - once.Do(startServer) - - client, err := net.Dial("tcp", serverAddr) - if err != nil { - t.Fatal("dialing", err) - } - - config := newConfig(t, "/echo") - config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr)) - if err != nil { - t.Fatal("location url", err) - } - - ws, err := NewClient(config, client) - if err != nil { - t.Errorf("WebSocket handshake: %v", err) - return - } - ws.Close() -} - -func testWithProtocol(t *testing.T, subproto []string) (string, error) { - once.Do(startServer) - - client, err := net.Dial("tcp", serverAddr) - if err != nil { - t.Fatal("dialing", err) - } - - config := newConfig(t, "/subproto") - config.Protocol = subproto - - ws, err := NewClient(config, client) - if err != nil { - return "", err - } - msg := make([]byte, 16) - n, err := ws.Read(msg) - if err != nil { - return "", err - } - ws.Close() - return string(msg[:n]), nil -} - -func TestWithProtocol(t *testing.T) { - proto, err := testWithProtocol(t, []string{"chat"}) - if err != nil { - t.Errorf("SubProto: unexpected error: %v", err) - } - if proto != "chat" { - t.Errorf("SubProto: expected %q, got %q", "chat", proto) - } -} - -func TestWithTwoProtocol(t *testing.T) { - proto, err := testWithProtocol(t, []string{"test", "chat"}) - if err != nil { - t.Errorf("SubProto: unexpected error: %v", err) - } - if proto != "chat" { - t.Errorf("SubProto: expected %q, got %q", "chat", proto) - } -} - -func TestWithBadProtocol(t *testing.T) { - _, err := testWithProtocol(t, []string{"test"}) - if err != ErrBadStatus { - t.Errorf("SubProto: expected %v, got %v", ErrBadStatus, err) - } -} - -func TestHTTP(t *testing.T) { - once.Do(startServer) - - // If the client did not send a handshake that matches the protocol - // specification, the server MUST return an HTTP response with an - // appropriate error code (such as 400 Bad Request) - resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr)) - if err != nil { - t.Errorf("Get: error %#v", err) - return - } - if resp == nil { - t.Error("Get: resp is null") - return - } - if resp.StatusCode != http.StatusBadRequest { - t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode) - } -} - -func TestTrailingSpaces(t *testing.T) { - // http://code.google.com/p/go/issues/detail?id=955 - // The last runs of this create keys with trailing spaces that should not be - // generated by the client. - once.Do(startServer) - config := newConfig(t, "/echo") - for i := 0; i < 30; i++ { - // body - ws, err := DialConfig(config) - if err != nil { - t.Errorf("Dial #%d failed: %v", i, err) - break - } - ws.Close() - } -} - -func TestDialConfigBadVersion(t *testing.T) { - once.Do(startServer) - config := newConfig(t, "/echo") - config.Version = 1234 - - _, err := DialConfig(config) - - if dialerr, ok := err.(*DialError); ok { - if dialerr.Err != ErrBadProtocolVersion { - t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err) - } - } -} - -func TestSmallBuffer(t *testing.T) { - // http://code.google.com/p/go/issues/detail?id=1145 - // Read should be able to handle reading a fragment of a frame. - once.Do(startServer) - - // websocket.Dial() - client, err := net.Dial("tcp", serverAddr) - if err != nil { - t.Fatal("dialing", err) - } - conn, err := NewClient(newConfig(t, "/echo"), client) - if err != nil { - t.Errorf("WebSocket handshake error: %v", err) - return - } - - msg := []byte("hello, world\n") - if _, err := conn.Write(msg); err != nil { - t.Errorf("Write: %v", err) - } - var small_msg = make([]byte, 8) - n, err := conn.Read(small_msg) - if err != nil { - t.Errorf("Read: %v", err) - } - if !bytes.Equal(msg[:len(small_msg)], small_msg) { - t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg) - } - var second_msg = make([]byte, len(msg)) - n, err = conn.Read(second_msg) - if err != nil { - t.Errorf("Read: %v", err) - } - second_msg = second_msg[0:n] - if !bytes.Equal(msg[len(small_msg):], second_msg) { - t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg) - } - conn.Close() -} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/client.go b/Godeps/_workspace/src/golang.org/x/net/websocket/client.go new file mode 100644 index 000000000..ef11a51e4 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/client.go @@ -0,0 +1,112 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "crypto/tls" + "io" + "net" + "net/http" + "net/url" +) + +// DialError is an error that occurs while dialling a websocket server. +type DialError struct { + *Config + Err error +} + +func (e *DialError) Error() string { + return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error() +} + +// NewConfig creates a new WebSocket config for client connection. +func NewConfig(server, origin string) (config *Config, err error) { + config = new(Config) + config.Version = ProtocolVersionHybi13 + config.Location, err = url.ParseRequestURI(server) + if err != nil { + return + } + config.Origin, err = url.ParseRequestURI(origin) + if err != nil { + return + } + config.Header = http.Header(make(map[string][]string)) + return +} + +// NewClient creates a new WebSocket client connection over rwc. +func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) { + br := bufio.NewReader(rwc) + bw := bufio.NewWriter(rwc) + err = hybiClientHandshake(config, br, bw) + if err != nil { + return + } + buf := bufio.NewReadWriter(br, bw) + ws = newHybiClientConn(config, buf, rwc) + return +} + +// Dial opens a new client connection to a WebSocket. +func Dial(url_, protocol, origin string) (ws *Conn, err error) { + config, err := NewConfig(url_, origin) + if err != nil { + return nil, err + } + if protocol != "" { + config.Protocol = []string{protocol} + } + return DialConfig(config) +} + +var portMap = map[string]string{ + "ws": "80", + "wss": "443", +} + +func parseAuthority(location *url.URL) string { + if _, ok := portMap[location.Scheme]; ok { + if _, _, err := net.SplitHostPort(location.Host); err != nil { + return net.JoinHostPort(location.Host, portMap[location.Scheme]) + } + } + return location.Host +} + +// DialConfig opens a new client connection to a WebSocket with a config. +func DialConfig(config *Config) (ws *Conn, err error) { + var client net.Conn + if config.Location == nil { + return nil, &DialError{config, ErrBadWebSocketLocation} + } + if config.Origin == nil { + return nil, &DialError{config, ErrBadWebSocketOrigin} + } + switch config.Location.Scheme { + case "ws": + client, err = net.Dial("tcp", parseAuthority(config.Location)) + + case "wss": + client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig) + + default: + err = ErrBadScheme + } + if err != nil { + goto Error + } + + ws, err = NewClient(config, client) + if err != nil { + goto Error + } + return + +Error: + return nil, &DialError{config, err} +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go new file mode 100644 index 000000000..72bb9d48e --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/exampledial_test.go @@ -0,0 +1,31 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket_test + +import ( + "fmt" + "log" + + "golang.org/x/net/websocket" +) + +// This example demonstrates a trivial client. +func ExampleDial() { + origin := "http://localhost/" + url := "ws://localhost:12345/ws" + ws, err := websocket.Dial(url, "", origin) + if err != nil { + log.Fatal(err) + } + if _, err := ws.Write([]byte("hello, world!\n")); err != nil { + log.Fatal(err) + } + var msg = make([]byte, 512) + var n int + if n, err = ws.Read(msg); err != nil { + log.Fatal(err) + } + fmt.Printf("Received: %s.\n", msg[:n]) +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go new file mode 100644 index 000000000..f22a98fcd --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/examplehandler_test.go @@ -0,0 +1,26 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket_test + +import ( + "io" + "net/http" + + "golang.org/x/net/websocket" +) + +// Echo the data received on the WebSocket. +func EchoServer(ws *websocket.Conn) { + io.Copy(ws, ws) +} + +// This example demonstrates a trivial echo server. +func ExampleHandler() { + http.Handle("/echo", websocket.Handler(EchoServer)) + err := http.ListenAndServe(":12345", nil) + if err != nil { + panic("ListenAndServe: " + err.Error()) + } +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go new file mode 100644 index 000000000..f8c0b2e29 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go @@ -0,0 +1,564 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +// This file implements a protocol of hybi draft. +// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 + +import ( + "bufio" + "bytes" + "crypto/rand" + "crypto/sha1" + "encoding/base64" + "encoding/binary" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +const ( + websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + + closeStatusNormal = 1000 + closeStatusGoingAway = 1001 + closeStatusProtocolError = 1002 + closeStatusUnsupportedData = 1003 + closeStatusFrameTooLarge = 1004 + closeStatusNoStatusRcvd = 1005 + closeStatusAbnormalClosure = 1006 + closeStatusBadMessageData = 1007 + closeStatusPolicyViolation = 1008 + closeStatusTooBigData = 1009 + closeStatusExtensionMismatch = 1010 + + maxControlFramePayloadLength = 125 +) + +var ( + ErrBadMaskingKey = &ProtocolError{"bad masking key"} + ErrBadPongMessage = &ProtocolError{"bad pong message"} + ErrBadClosingStatus = &ProtocolError{"bad closing status"} + ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"} + ErrNotImplemented = &ProtocolError{"not implemented"} + + handshakeHeader = map[string]bool{ + "Host": true, + "Upgrade": true, + "Connection": true, + "Sec-Websocket-Key": true, + "Sec-Websocket-Origin": true, + "Sec-Websocket-Version": true, + "Sec-Websocket-Protocol": true, + "Sec-Websocket-Accept": true, + } +) + +// A hybiFrameHeader is a frame header as defined in hybi draft. +type hybiFrameHeader struct { + Fin bool + Rsv [3]bool + OpCode byte + Length int64 + MaskingKey []byte + + data *bytes.Buffer +} + +// A hybiFrameReader is a reader for hybi frame. +type hybiFrameReader struct { + reader io.Reader + + header hybiFrameHeader + pos int64 + length int +} + +func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) { + n, err = frame.reader.Read(msg) + if err != nil { + return 0, err + } + if frame.header.MaskingKey != nil { + for i := 0; i < n; i++ { + msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4] + frame.pos++ + } + } + return n, err +} + +func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode } + +func (frame *hybiFrameReader) HeaderReader() io.Reader { + if frame.header.data == nil { + return nil + } + if frame.header.data.Len() == 0 { + return nil + } + return frame.header.data +} + +func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil } + +func (frame *hybiFrameReader) Len() (n int) { return frame.length } + +// A hybiFrameReaderFactory creates new frame reader based on its frame type. +type hybiFrameReaderFactory struct { + *bufio.Reader +} + +// NewFrameReader reads a frame header from the connection, and creates new reader for the frame. +// See Section 5.2 Base Framing protocol for detail. +// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2 +func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) { + hybiFrame := new(hybiFrameReader) + frame = hybiFrame + var header []byte + var b byte + // First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits) + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0 + for i := 0; i < 3; i++ { + j := uint(6 - i) + hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0 + } + hybiFrame.header.OpCode = header[0] & 0x0f + + // Second byte. Mask/Payload len(7bits) + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + mask := (b & 0x80) != 0 + b &= 0x7f + lengthFields := 0 + switch { + case b <= 125: // Payload length 7bits. + hybiFrame.header.Length = int64(b) + case b == 126: // Payload length 7+16bits + lengthFields = 2 + case b == 127: // Payload length 7+64bits + lengthFields = 8 + } + for i := 0; i < lengthFields; i++ { + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b) + } + if mask { + // Masking key. 4 bytes. + for i := 0; i < 4; i++ { + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b) + } + } + hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length) + hybiFrame.header.data = bytes.NewBuffer(header) + hybiFrame.length = len(header) + int(hybiFrame.header.Length) + return +} + +// A HybiFrameWriter is a writer for hybi frame. +type hybiFrameWriter struct { + writer *bufio.Writer + + header *hybiFrameHeader +} + +func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) { + var header []byte + var b byte + if frame.header.Fin { + b |= 0x80 + } + for i := 0; i < 3; i++ { + if frame.header.Rsv[i] { + j := uint(6 - i) + b |= 1 << j + } + } + b |= frame.header.OpCode + header = append(header, b) + if frame.header.MaskingKey != nil { + b = 0x80 + } else { + b = 0 + } + lengthFields := 0 + length := len(msg) + switch { + case length <= 125: + b |= byte(length) + case length < 65536: + b |= 126 + lengthFields = 2 + default: + b |= 127 + lengthFields = 8 + } + header = append(header, b) + for i := 0; i < lengthFields; i++ { + j := uint((lengthFields - i - 1) * 8) + b = byte((length >> j) & 0xff) + header = append(header, b) + } + if frame.header.MaskingKey != nil { + if len(frame.header.MaskingKey) != 4 { + return 0, ErrBadMaskingKey + } + header = append(header, frame.header.MaskingKey...) + frame.writer.Write(header) + data := make([]byte, length) + for i := range data { + data[i] = msg[i] ^ frame.header.MaskingKey[i%4] + } + frame.writer.Write(data) + err = frame.writer.Flush() + return length, err + } + frame.writer.Write(header) + frame.writer.Write(msg) + err = frame.writer.Flush() + return length, err +} + +func (frame *hybiFrameWriter) Close() error { return nil } + +type hybiFrameWriterFactory struct { + *bufio.Writer + needMaskingKey bool +} + +func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType} + if buf.needMaskingKey { + frameHeader.MaskingKey, err = generateMaskingKey() + if err != nil { + return nil, err + } + } + return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil +} + +type hybiFrameHandler struct { + conn *Conn + payloadType byte +} + +func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (r frameReader, err error) { + if handler.conn.IsServerConn() { + // The client MUST mask all frames sent to the server. + if frame.(*hybiFrameReader).header.MaskingKey == nil { + handler.WriteClose(closeStatusProtocolError) + return nil, io.EOF + } + } else { + // The server MUST NOT mask all frames. + if frame.(*hybiFrameReader).header.MaskingKey != nil { + handler.WriteClose(closeStatusProtocolError) + return nil, io.EOF + } + } + if header := frame.HeaderReader(); header != nil { + io.Copy(ioutil.Discard, header) + } + switch frame.PayloadType() { + case ContinuationFrame: + frame.(*hybiFrameReader).header.OpCode = handler.payloadType + case TextFrame, BinaryFrame: + handler.payloadType = frame.PayloadType() + case CloseFrame: + return nil, io.EOF + case PingFrame: + pingMsg := make([]byte, maxControlFramePayloadLength) + n, err := io.ReadFull(frame, pingMsg) + if err != nil && err != io.ErrUnexpectedEOF { + return nil, err + } + io.Copy(ioutil.Discard, frame) + n, err = handler.WritePong(pingMsg[:n]) + if err != nil { + return nil, err + } + return nil, nil + case PongFrame: + return nil, ErrNotImplemented + } + return frame, nil +} + +func (handler *hybiFrameHandler) WriteClose(status int) (err error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() + w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame) + if err != nil { + return err + } + msg := make([]byte, 2) + binary.BigEndian.PutUint16(msg, uint16(status)) + _, err = w.Write(msg) + w.Close() + return err +} + +func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() + w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame) + if err != nil { + return 0, err + } + n, err = w.Write(msg) + w.Close() + return n, err +} + +// newHybiConn creates a new WebSocket connection speaking hybi draft protocol. +func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { + if buf == nil { + br := bufio.NewReader(rwc) + bw := bufio.NewWriter(rwc) + buf = bufio.NewReadWriter(br, bw) + } + ws := &Conn{config: config, request: request, buf: buf, rwc: rwc, + frameReaderFactory: hybiFrameReaderFactory{buf.Reader}, + frameWriterFactory: hybiFrameWriterFactory{ + buf.Writer, request == nil}, + PayloadType: TextFrame, + defaultCloseStatus: closeStatusNormal} + ws.frameHandler = &hybiFrameHandler{conn: ws} + return ws +} + +// generateMaskingKey generates a masking key for a frame. +func generateMaskingKey() (maskingKey []byte, err error) { + maskingKey = make([]byte, 4) + if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil { + return + } + return +} + +// generateNonce generates a nonce consisting of a randomly selected 16-byte +// value that has been base64-encoded. +func generateNonce() (nonce []byte) { + key := make([]byte, 16) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + panic(err) + } + nonce = make([]byte, 24) + base64.StdEncoding.Encode(nonce, key) + return +} + +// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of +// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string. +func getNonceAccept(nonce []byte) (expected []byte, err error) { + h := sha1.New() + if _, err = h.Write(nonce); err != nil { + return + } + if _, err = h.Write([]byte(websocketGUID)); err != nil { + return + } + expected = make([]byte, 28) + base64.StdEncoding.Encode(expected, h.Sum(nil)) + return +} + +// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17 +func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) { + bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n") + + bw.WriteString("Host: " + config.Location.Host + "\r\n") + bw.WriteString("Upgrade: websocket\r\n") + bw.WriteString("Connection: Upgrade\r\n") + nonce := generateNonce() + if config.handshakeData != nil { + nonce = []byte(config.handshakeData["key"]) + } + bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n") + bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n") + + if config.Version != ProtocolVersionHybi13 { + return ErrBadProtocolVersion + } + + bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n") + if len(config.Protocol) > 0 { + bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n") + } + // TODO(ukai): send Sec-WebSocket-Extensions. + err = config.Header.WriteSubset(bw, handshakeHeader) + if err != nil { + return err + } + + bw.WriteString("\r\n") + if err = bw.Flush(); err != nil { + return err + } + + resp, err := http.ReadResponse(br, &http.Request{Method: "GET"}) + if err != nil { + return err + } + if resp.StatusCode != 101 { + return ErrBadStatus + } + if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" || + strings.ToLower(resp.Header.Get("Connection")) != "upgrade" { + return ErrBadUpgrade + } + expectedAccept, err := getNonceAccept(nonce) + if err != nil { + return err + } + if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) { + return ErrChallengeResponse + } + if resp.Header.Get("Sec-WebSocket-Extensions") != "" { + return ErrUnsupportedExtensions + } + offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol") + if offeredProtocol != "" { + protocolMatched := false + for i := 0; i < len(config.Protocol); i++ { + if config.Protocol[i] == offeredProtocol { + protocolMatched = true + break + } + } + if !protocolMatched { + return ErrBadWebSocketProtocol + } + config.Protocol = []string{offeredProtocol} + } + + return nil +} + +// newHybiClientConn creates a client WebSocket connection after handshake. +func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn { + return newHybiConn(config, buf, rwc, nil) +} + +// A HybiServerHandshaker performs a server handshake using hybi draft protocol. +type hybiServerHandshaker struct { + *Config + accept []byte +} + +func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) { + c.Version = ProtocolVersionHybi13 + if req.Method != "GET" { + return http.StatusMethodNotAllowed, ErrBadRequestMethod + } + // HTTP version can be safely ignored. + + if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" || + !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { + return http.StatusBadRequest, ErrNotWebSocket + } + + key := req.Header.Get("Sec-Websocket-Key") + if key == "" { + return http.StatusBadRequest, ErrChallengeResponse + } + version := req.Header.Get("Sec-Websocket-Version") + switch version { + case "13": + c.Version = ProtocolVersionHybi13 + default: + return http.StatusBadRequest, ErrBadWebSocketVersion + } + var scheme string + if req.TLS != nil { + scheme = "wss" + } else { + scheme = "ws" + } + c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI()) + if err != nil { + return http.StatusBadRequest, err + } + protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol")) + if protocol != "" { + protocols := strings.Split(protocol, ",") + for i := 0; i < len(protocols); i++ { + c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) + } + } + c.accept, err = getNonceAccept([]byte(key)) + if err != nil { + return http.StatusInternalServerError, err + } + return http.StatusSwitchingProtocols, nil +} + +// Origin parses Origin header in "req". +// If origin is "null", returns (nil, nil). +func Origin(config *Config, req *http.Request) (*url.URL, error) { + var origin string + switch config.Version { + case ProtocolVersionHybi13: + origin = req.Header.Get("Origin") + } + if origin == "null" { + return nil, nil + } + return url.ParseRequestURI(origin) +} + +func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) { + if len(c.Protocol) > 0 { + if len(c.Protocol) != 1 { + // You need choose a Protocol in Handshake func in Server. + return ErrBadWebSocketProtocol + } + } + buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n") + buf.WriteString("Upgrade: websocket\r\n") + buf.WriteString("Connection: Upgrade\r\n") + buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n") + if len(c.Protocol) > 0 { + buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n") + } + // TODO(ukai): send Sec-WebSocket-Extensions. + if c.Header != nil { + err := c.Header.WriteSubset(buf, handshakeHeader) + if err != nil { + return err + } + } + buf.WriteString("\r\n") + return buf.Flush() +} + +func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { + return newHybiServerConn(c.Config, buf, rwc, request) +} + +// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol. +func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { + return newHybiConn(config, buf, rwc, request) +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go new file mode 100644 index 000000000..d6a19108a --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi_test.go @@ -0,0 +1,590 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "bytes" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "testing" +) + +// Test the getNonceAccept function with values in +// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 +func TestSecWebSocketAccept(t *testing.T) { + nonce := []byte("dGhlIHNhbXBsZSBub25jZQ==") + expected := []byte("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=") + accept, err := getNonceAccept(nonce) + if err != nil { + t.Errorf("getNonceAccept: returned error %v", err) + return + } + if !bytes.Equal(expected, accept) { + t.Errorf("getNonceAccept: expected %q got %q", expected, accept) + } +} + +func TestHybiClientHandshake(t *testing.T) { + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= +Sec-WebSocket-Protocol: chat + +`)) + var err error + config := new(Config) + config.Location, err = url.ParseRequestURI("ws://server.example.com/chat") + if err != nil { + t.Fatal("location url", err) + } + config.Origin, err = url.ParseRequestURI("http://example.com") + if err != nil { + t.Fatal("origin url", err) + } + config.Protocol = append(config.Protocol, "chat") + config.Protocol = append(config.Protocol, "superchat") + config.Version = ProtocolVersionHybi13 + + config.handshakeData = map[string]string{ + "key": "dGhlIHNhbXBsZSBub25jZQ==", + } + err = hybiClientHandshake(config, br, bw) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + req, err := http.ReadRequest(bufio.NewReader(b)) + if err != nil { + t.Fatalf("read request: %v", err) + } + if req.Method != "GET" { + t.Errorf("request method expected GET, but got %q", req.Method) + } + if req.URL.Path != "/chat" { + t.Errorf("request path expected /chat, but got %q", req.URL.Path) + } + if req.Proto != "HTTP/1.1" { + t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) + } + if req.Host != "server.example.com" { + t.Errorf("request Host expected server.example.com, but got %v", req.Host) + } + var expectedHeader = map[string]string{ + "Connection": "Upgrade", + "Upgrade": "websocket", + "Sec-Websocket-Key": config.handshakeData["key"], + "Origin": config.Origin.String(), + "Sec-Websocket-Protocol": "chat, superchat", + "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), + } + for k, v := range expectedHeader { + if req.Header.Get(k) != v { + t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k))) + } + } +} + +func TestHybiClientHandshakeWithHeader(t *testing.T) { + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= +Sec-WebSocket-Protocol: chat + +`)) + var err error + config := new(Config) + config.Location, err = url.ParseRequestURI("ws://server.example.com/chat") + if err != nil { + t.Fatal("location url", err) + } + config.Origin, err = url.ParseRequestURI("http://example.com") + if err != nil { + t.Fatal("origin url", err) + } + config.Protocol = append(config.Protocol, "chat") + config.Protocol = append(config.Protocol, "superchat") + config.Version = ProtocolVersionHybi13 + config.Header = http.Header(make(map[string][]string)) + config.Header.Add("User-Agent", "test") + + config.handshakeData = map[string]string{ + "key": "dGhlIHNhbXBsZSBub25jZQ==", + } + err = hybiClientHandshake(config, br, bw) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + req, err := http.ReadRequest(bufio.NewReader(b)) + if err != nil { + t.Fatalf("read request: %v", err) + } + if req.Method != "GET" { + t.Errorf("request method expected GET, but got %q", req.Method) + } + if req.URL.Path != "/chat" { + t.Errorf("request path expected /chat, but got %q", req.URL.Path) + } + if req.Proto != "HTTP/1.1" { + t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) + } + if req.Host != "server.example.com" { + t.Errorf("request Host expected server.example.com, but got %v", req.Host) + } + var expectedHeader = map[string]string{ + "Connection": "Upgrade", + "Upgrade": "websocket", + "Sec-Websocket-Key": config.handshakeData["key"], + "Origin": config.Origin.String(), + "Sec-Websocket-Protocol": "chat, superchat", + "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), + "User-Agent": "test", + } + for k, v := range expectedHeader { + if req.Header.Get(k) != v { + t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k))) + } + } +} + +func TestHybiServerHandshake(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + expectedProtocols := []string{"chat", "superchat"} + if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) { + t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + config.Protocol = config.Protocol[:1] + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "Sec-WebSocket-Protocol: chat", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} + +func TestHybiServerHandshakeNoSubProtocol(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + if len(config.Protocol) != 0 { + t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol)) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} + +func TestHybiServerHandshakeHybiBadVersion(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 9 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != ErrBadWebSocketVersion { + t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err) + } + if code != http.StatusBadRequest { + t.Errorf("status expected %q but got %q", http.StatusBadRequest, code) + } +} + +func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) { + b := bytes.NewBuffer([]byte{}) + frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false} + w, _ := frameWriterFactory.NewFrameWriter(TextFrame) + w.(*hybiFrameWriter).header = frameHeader + _, err := w.Write(testPayload) + w.Close() + if err != nil { + t.Errorf("Write error %q", err) + } + var expectedFrame []byte + expectedFrame = append(expectedFrame, testHeader...) + expectedFrame = append(expectedFrame, testMaskedPayload...) + if !bytes.Equal(expectedFrame, b.Bytes()) { + t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes()) + } + frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)} + r, err := frameReaderFactory.NewFrameReader() + if err != nil { + t.Errorf("Read error %q", err) + } + if header := r.HeaderReader(); header == nil { + t.Errorf("no header") + } else { + actualHeader := make([]byte, r.Len()) + n, err := header.Read(actualHeader) + if err != nil { + t.Errorf("Read header error %q", err) + } else { + if n < len(testHeader) { + t.Errorf("header too short %q got %q", testHeader, actualHeader[:n]) + } + if !bytes.Equal(testHeader, actualHeader[:n]) { + t.Errorf("header expected %q got %q", testHeader, actualHeader[:n]) + } + } + } + if trailer := r.TrailerReader(); trailer != nil { + t.Errorf("unexpected trailer %q", trailer) + } + frame := r.(*hybiFrameReader) + if frameHeader.Fin != frame.header.Fin || + frameHeader.OpCode != frame.header.OpCode || + len(testPayload) != int(frame.header.Length) { + t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame) + } + payload := make([]byte, len(testPayload)) + _, err = r.Read(payload) + if err != nil { + t.Errorf("read %v", err) + } + if !bytes.Equal(testPayload, payload) { + t.Errorf("payload %q vs %q", testPayload, payload) + } +} + +func TestHybiShortTextFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} + payload := []byte("hello") + testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader) + + payload = make([]byte, 125) + testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader) +} + +func TestHybiShortMaskedTextFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame, + MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}} + payload := []byte("hello") + maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3} + header := []byte{0x81, 0x85} + header = append(header, frameHeader.MaskingKey...) + testHybiFrame(t, header, payload, maskedPayload, frameHeader) +} + +func TestHybiShortBinaryFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame} + payload := []byte("hello") + testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader) + + payload = make([]byte, 125) + testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader) +} + +func TestHybiControlFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame} + payload := []byte("hello") + testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader) + + frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame} + testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader) + + frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame} + payload = []byte{0x03, 0xe8} // 1000 + testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader) +} + +func TestHybiLongFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} + payload := make([]byte, 126) + testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader) + + payload = make([]byte, 65535) + testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader) + + payload = make([]byte, 65536) + testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader) +} + +func TestHybiClientRead(t *testing.T) { + wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', + 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping + 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) + + msg := make([]byte, 512) + n, err := conn.Read(msg) + if err != nil { + t.Errorf("read 1st frame, error %q", err) + } + if n != 5 { + t.Errorf("read 1st frame, expect 5, got %d", n) + } + if !bytes.Equal(wireData[2:7], msg[:n]) { + t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n]) + } + n, err = conn.Read(msg) + if err != nil { + t.Errorf("read 2nd frame, error %q", err) + } + if n != 5 { + t.Errorf("read 2nd frame, expect 5, got %d", n) + } + if !bytes.Equal(wireData[16:21], msg[:n]) { + t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n]) + } + n, err = conn.Read(msg) + if err == nil { + t.Errorf("read not EOF") + } + if n != 0 { + t.Errorf("expect read 0, got %d", n) + } +} + +func TestHybiShortRead(t *testing.T) { + wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', + 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping + 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) + + step := 0 + pos := 0 + expectedPos := []int{2, 5, 16, 19} + expectedLen := []int{3, 2, 3, 2} + for { + msg := make([]byte, 3) + n, err := conn.Read(msg) + if step >= len(expectedPos) { + if err == nil { + t.Errorf("read not EOF") + } + if n != 0 { + t.Errorf("expect read 0, got %d", n) + } + return + } + pos = expectedPos[step] + endPos := pos + expectedLen[step] + if err != nil { + t.Errorf("read from %d, got error %q", pos, err) + return + } + if n != endPos-pos { + t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n) + } + if !bytes.Equal(wireData[pos:endPos], msg[:n]) { + t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n]) + } + step++ + } +} + +func TestHybiServerRead(t *testing.T) { + wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, + 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello + 0x89, 0x85, 0xcc, 0x55, 0x80, 0x20, + 0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello + 0x81, 0x85, 0xed, 0x83, 0xb4, 0x24, + 0x9a, 0xec, 0xc6, 0x48, 0x89, // world + } + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) + + expected := [][]byte{[]byte("hello"), []byte("world")} + + msg := make([]byte, 512) + n, err := conn.Read(msg) + if err != nil { + t.Errorf("read 1st frame, error %q", err) + } + if n != 5 { + t.Errorf("read 1st frame, expect 5, got %d", n) + } + if !bytes.Equal(expected[0], msg[:n]) { + t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n]) + } + + n, err = conn.Read(msg) + if err != nil { + t.Errorf("read 2nd frame, error %q", err) + } + if n != 5 { + t.Errorf("read 2nd frame, expect 5, got %d", n) + } + if !bytes.Equal(expected[1], msg[:n]) { + t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n]) + } + + n, err = conn.Read(msg) + if err == nil { + t.Errorf("read not EOF") + } + if n != 0 { + t.Errorf("expect read 0, got %d", n) + } +} + +func TestHybiServerReadWithoutMasking(t *testing.T) { + wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'} + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) + // server MUST close the connection upon receiving a non-masked frame. + msg := make([]byte, 512) + _, err := conn.Read(msg) + if err != io.EOF { + t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) + } +} + +func TestHybiClientReadWithMasking(t *testing.T) { + wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, + 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello + } + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) + + // client MUST close the connection upon receiving a masked frame. + msg := make([]byte, 512) + _, err := conn.Read(msg) + if err != io.EOF { + t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) + } +} + +// Test the hybiServerHandshaker supports firefox implementation and +// checks Connection request header include (but it's not necessary +// equal to) "upgrade" +func TestHybiServerFirefoxHandshake(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: keep-alive, upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + config.Protocol = []string{"chat"} + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "Sec-WebSocket-Protocol: chat", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/server.go b/Godeps/_workspace/src/golang.org/x/net/websocket/server.go new file mode 100644 index 000000000..70322133c --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/server.go @@ -0,0 +1,114 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "fmt" + "io" + "net/http" +) + +func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) { + var hs serverHandshaker = &hybiServerHandshaker{Config: config} + code, err := hs.ReadHandshake(buf.Reader, req) + if err == ErrBadWebSocketVersion { + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion) + buf.WriteString("\r\n") + buf.WriteString(err.Error()) + buf.Flush() + return + } + if err != nil { + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + buf.WriteString("\r\n") + buf.WriteString(err.Error()) + buf.Flush() + return + } + if handshake != nil { + err = handshake(config, req) + if err != nil { + code = http.StatusForbidden + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + buf.WriteString("\r\n") + buf.Flush() + return + } + } + err = hs.AcceptHandshake(buf.Writer) + if err != nil { + code = http.StatusBadRequest + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + buf.WriteString("\r\n") + buf.Flush() + return + } + conn = hs.NewServerConn(buf, rwc, req) + return +} + +// Server represents a server of a WebSocket. +type Server struct { + // Config is a WebSocket configuration for new WebSocket connection. + Config + + // Handshake is an optional function in WebSocket handshake. + // For example, you can check, or don't check Origin header. + // Another example, you can select config.Protocol. + Handshake func(*Config, *http.Request) error + + // Handler handles a WebSocket connection. + Handler +} + +// ServeHTTP implements the http.Handler interface for a WebSocket +func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { + s.serveWebSocket(w, req) +} + +func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) { + rwc, buf, err := w.(http.Hijacker).Hijack() + if err != nil { + panic("Hijack failed: " + err.Error()) + return + } + // The server should abort the WebSocket connection if it finds + // the client did not send a handshake that matches with protocol + // specification. + defer rwc.Close() + conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake) + if err != nil { + return + } + if conn == nil { + panic("unexpected nil conn") + } + s.Handler(conn) +} + +// Handler is a simple interface to a WebSocket browser client. +// It checks if Origin header is valid URL by default. +// You might want to verify websocket.Conn.Config().Origin in the func. +// If you use Server instead of Handler, you could call websocket.Origin and +// check the origin in your Handshake func. So, if you want to accept +// non-browser client, which doesn't send Origin header, you could use Server +//. that doesn't check origin in its Handshake. +type Handler func(*Conn) + +func checkOrigin(config *Config, req *http.Request) (err error) { + config.Origin, err = Origin(config, req) + if err == nil && config.Origin == nil { + return fmt.Errorf("null origin") + } + return err +} + +// ServeHTTP implements the http.Handler interface for a WebSocket +func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + s := Server{Handler: h, Handshake: checkOrigin} + s.serveWebSocket(w, req) +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go new file mode 100644 index 000000000..0f4917bf7 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go @@ -0,0 +1,411 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package websocket implements a client and server for the WebSocket protocol +// as specified in RFC 6455. +package websocket + +import ( + "bufio" + "crypto/tls" + "encoding/json" + "errors" + "io" + "io/ioutil" + "net" + "net/http" + "net/url" + "sync" + "time" +) + +const ( + ProtocolVersionHybi13 = 13 + ProtocolVersionHybi = ProtocolVersionHybi13 + SupportedProtocolVersion = "13" + + ContinuationFrame = 0 + TextFrame = 1 + BinaryFrame = 2 + CloseFrame = 8 + PingFrame = 9 + PongFrame = 10 + UnknownFrame = 255 +) + +// ProtocolError represents WebSocket protocol errors. +type ProtocolError struct { + ErrorString string +} + +func (err *ProtocolError) Error() string { return err.ErrorString } + +var ( + ErrBadProtocolVersion = &ProtocolError{"bad protocol version"} + ErrBadScheme = &ProtocolError{"bad scheme"} + ErrBadStatus = &ProtocolError{"bad status"} + ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"} + ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"} + ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"} + ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"} + ErrBadWebSocketVersion = &ProtocolError{"missing or bad WebSocket Version"} + ErrChallengeResponse = &ProtocolError{"mismatch challenge/response"} + ErrBadFrame = &ProtocolError{"bad frame"} + ErrBadFrameBoundary = &ProtocolError{"not on frame boundary"} + ErrNotWebSocket = &ProtocolError{"not websocket protocol"} + ErrBadRequestMethod = &ProtocolError{"bad method"} + ErrNotSupported = &ProtocolError{"not supported"} +) + +// Addr is an implementation of net.Addr for WebSocket. +type Addr struct { + *url.URL +} + +// Network returns the network type for a WebSocket, "websocket". +func (addr *Addr) Network() string { return "websocket" } + +// Config is a WebSocket configuration +type Config struct { + // A WebSocket server address. + Location *url.URL + + // A Websocket client origin. + Origin *url.URL + + // WebSocket subprotocols. + Protocol []string + + // WebSocket protocol version. + Version int + + // TLS config for secure WebSocket (wss). + TlsConfig *tls.Config + + // Additional header fields to be sent in WebSocket opening handshake. + Header http.Header + + handshakeData map[string]string +} + +// serverHandshaker is an interface to handle WebSocket server side handshake. +type serverHandshaker interface { + // ReadHandshake reads handshake request message from client. + // Returns http response code and error if any. + ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) + + // AcceptHandshake accepts the client handshake request and sends + // handshake response back to client. + AcceptHandshake(buf *bufio.Writer) (err error) + + // NewServerConn creates a new WebSocket connection. + NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn) +} + +// frameReader is an interface to read a WebSocket frame. +type frameReader interface { + // Reader is to read payload of the frame. + io.Reader + + // PayloadType returns payload type. + PayloadType() byte + + // HeaderReader returns a reader to read header of the frame. + HeaderReader() io.Reader + + // TrailerReader returns a reader to read trailer of the frame. + // If it returns nil, there is no trailer in the frame. + TrailerReader() io.Reader + + // Len returns total length of the frame, including header and trailer. + Len() int +} + +// frameReaderFactory is an interface to creates new frame reader. +type frameReaderFactory interface { + NewFrameReader() (r frameReader, err error) +} + +// frameWriter is an interface to write a WebSocket frame. +type frameWriter interface { + // Writer is to write payload of the frame. + io.WriteCloser +} + +// frameWriterFactory is an interface to create new frame writer. +type frameWriterFactory interface { + NewFrameWriter(payloadType byte) (w frameWriter, err error) +} + +type frameHandler interface { + HandleFrame(frame frameReader) (r frameReader, err error) + WriteClose(status int) (err error) +} + +// Conn represents a WebSocket connection. +type Conn struct { + config *Config + request *http.Request + + buf *bufio.ReadWriter + rwc io.ReadWriteCloser + + rio sync.Mutex + frameReaderFactory + frameReader + + wio sync.Mutex + frameWriterFactory + + frameHandler + PayloadType byte + defaultCloseStatus int +} + +// Read implements the io.Reader interface: +// it reads data of a frame from the WebSocket connection. +// if msg is not large enough for the frame data, it fills the msg and next Read +// will read the rest of the frame data. +// it reads Text frame or Binary frame. +func (ws *Conn) Read(msg []byte) (n int, err error) { + ws.rio.Lock() + defer ws.rio.Unlock() +again: + if ws.frameReader == nil { + frame, err := ws.frameReaderFactory.NewFrameReader() + if err != nil { + return 0, err + } + ws.frameReader, err = ws.frameHandler.HandleFrame(frame) + if err != nil { + return 0, err + } + if ws.frameReader == nil { + goto again + } + } + n, err = ws.frameReader.Read(msg) + if err == io.EOF { + if trailer := ws.frameReader.TrailerReader(); trailer != nil { + io.Copy(ioutil.Discard, trailer) + } + ws.frameReader = nil + goto again + } + return n, err +} + +// Write implements the io.Writer interface: +// it writes data as a frame to the WebSocket connection. +func (ws *Conn) Write(msg []byte) (n int, err error) { + ws.wio.Lock() + defer ws.wio.Unlock() + w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType) + if err != nil { + return 0, err + } + n, err = w.Write(msg) + w.Close() + if err != nil { + return n, err + } + return n, err +} + +// Close implements the io.Closer interface. +func (ws *Conn) Close() error { + err := ws.frameHandler.WriteClose(ws.defaultCloseStatus) + if err != nil { + return err + } + return ws.rwc.Close() +} + +func (ws *Conn) IsClientConn() bool { return ws.request == nil } +func (ws *Conn) IsServerConn() bool { return ws.request != nil } + +// LocalAddr returns the WebSocket Origin for the connection for client, or +// the WebSocket location for server. +func (ws *Conn) LocalAddr() net.Addr { + if ws.IsClientConn() { + return &Addr{ws.config.Origin} + } + return &Addr{ws.config.Location} +} + +// RemoteAddr returns the WebSocket location for the connection for client, or +// the Websocket Origin for server. +func (ws *Conn) RemoteAddr() net.Addr { + if ws.IsClientConn() { + return &Addr{ws.config.Location} + } + return &Addr{ws.config.Origin} +} + +var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn") + +// SetDeadline sets the connection's network read & write deadlines. +func (ws *Conn) SetDeadline(t time.Time) error { + if conn, ok := ws.rwc.(net.Conn); ok { + return conn.SetDeadline(t) + } + return errSetDeadline +} + +// SetReadDeadline sets the connection's network read deadline. +func (ws *Conn) SetReadDeadline(t time.Time) error { + if conn, ok := ws.rwc.(net.Conn); ok { + return conn.SetReadDeadline(t) + } + return errSetDeadline +} + +// SetWriteDeadline sets the connection's network write deadline. +func (ws *Conn) SetWriteDeadline(t time.Time) error { + if conn, ok := ws.rwc.(net.Conn); ok { + return conn.SetWriteDeadline(t) + } + return errSetDeadline +} + +// Config returns the WebSocket config. +func (ws *Conn) Config() *Config { return ws.config } + +// Request returns the http request upgraded to the WebSocket. +// It is nil for client side. +func (ws *Conn) Request() *http.Request { return ws.request } + +// Codec represents a symmetric pair of functions that implement a codec. +type Codec struct { + Marshal func(v interface{}) (data []byte, payloadType byte, err error) + Unmarshal func(data []byte, payloadType byte, v interface{}) (err error) +} + +// Send sends v marshaled by cd.Marshal as single frame to ws. +func (cd Codec) Send(ws *Conn, v interface{}) (err error) { + data, payloadType, err := cd.Marshal(v) + if err != nil { + return err + } + ws.wio.Lock() + defer ws.wio.Unlock() + w, err := ws.frameWriterFactory.NewFrameWriter(payloadType) + if err != nil { + return err + } + _, err = w.Write(data) + w.Close() + return err +} + +// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v. +func (cd Codec) Receive(ws *Conn, v interface{}) (err error) { + ws.rio.Lock() + defer ws.rio.Unlock() + if ws.frameReader != nil { + _, err = io.Copy(ioutil.Discard, ws.frameReader) + if err != nil { + return err + } + ws.frameReader = nil + } +again: + frame, err := ws.frameReaderFactory.NewFrameReader() + if err != nil { + return err + } + frame, err = ws.frameHandler.HandleFrame(frame) + if err != nil { + return err + } + if frame == nil { + goto again + } + payloadType := frame.PayloadType() + data, err := ioutil.ReadAll(frame) + if err != nil { + return err + } + return cd.Unmarshal(data, payloadType, v) +} + +func marshal(v interface{}) (msg []byte, payloadType byte, err error) { + switch data := v.(type) { + case string: + return []byte(data), TextFrame, nil + case []byte: + return data, BinaryFrame, nil + } + return nil, UnknownFrame, ErrNotSupported +} + +func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) { + switch data := v.(type) { + case *string: + *data = string(msg) + return nil + case *[]byte: + *data = msg + return nil + } + return ErrNotSupported +} + +/* +Message is a codec to send/receive text/binary data in a frame on WebSocket connection. +To send/receive text frame, use string type. +To send/receive binary frame, use []byte type. + +Trivial usage: + + import "websocket" + + // receive text frame + var message string + websocket.Message.Receive(ws, &message) + + // send text frame + message = "hello" + websocket.Message.Send(ws, message) + + // receive binary frame + var data []byte + websocket.Message.Receive(ws, &data) + + // send binary frame + data = []byte{0, 1, 2} + websocket.Message.Send(ws, data) + +*/ +var Message = Codec{marshal, unmarshal} + +func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) { + msg, err = json.Marshal(v) + return msg, TextFrame, err +} + +func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) { + return json.Unmarshal(msg, v) +} + +/* +JSON is a codec to send/receive JSON data in a frame from a WebSocket connection. + +Trivial usage: + + import "websocket" + + type T struct { + Msg string + Count int + } + + // receive JSON type T + var data T + websocket.JSON.Receive(ws, &data) + + // send JSON type T + websocket.JSON.Send(ws, data) +*/ +var JSON = Codec{jsonMarshal, jsonUnmarshal} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go new file mode 100644 index 000000000..a376abacf --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket_test.go @@ -0,0 +1,414 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bytes" + "fmt" + "io" + "log" + "net" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "sync" + "testing" +) + +var serverAddr string +var once sync.Once + +func echoServer(ws *Conn) { io.Copy(ws, ws) } + +type Count struct { + S string + N int +} + +func countServer(ws *Conn) { + for { + var count Count + err := JSON.Receive(ws, &count) + if err != nil { + return + } + count.N++ + count.S = strings.Repeat(count.S, count.N) + err = JSON.Send(ws, count) + if err != nil { + return + } + } +} + +func subProtocolHandshake(config *Config, req *http.Request) error { + for _, proto := range config.Protocol { + if proto == "chat" { + config.Protocol = []string{proto} + return nil + } + } + return ErrBadWebSocketProtocol +} + +func subProtoServer(ws *Conn) { + for _, proto := range ws.Config().Protocol { + io.WriteString(ws, proto) + } +} + +func startServer() { + http.Handle("/echo", Handler(echoServer)) + http.Handle("/count", Handler(countServer)) + subproto := Server{ + Handshake: subProtocolHandshake, + Handler: Handler(subProtoServer), + } + http.Handle("/subproto", subproto) + server := httptest.NewServer(nil) + serverAddr = server.Listener.Addr().String() + log.Print("Test WebSocket server listening on ", serverAddr) +} + +func newConfig(t *testing.T, path string) *Config { + config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost") + return config +} + +func TestEcho(t *testing.T) { + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/echo"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + msg := []byte("hello, world\n") + if _, err := conn.Write(msg); err != nil { + t.Errorf("Write: %v", err) + } + var actual_msg = make([]byte, 512) + n, err := conn.Read(actual_msg) + if err != nil { + t.Errorf("Read: %v", err) + } + actual_msg = actual_msg[0:n] + if !bytes.Equal(msg, actual_msg) { + t.Errorf("Echo: expected %q got %q", msg, actual_msg) + } + conn.Close() +} + +func TestAddr(t *testing.T) { + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/echo"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + ra := conn.RemoteAddr().String() + if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") { + t.Errorf("Bad remote addr: %v", ra) + } + la := conn.LocalAddr().String() + if !strings.HasPrefix(la, "http://") { + t.Errorf("Bad local addr: %v", la) + } + conn.Close() +} + +func TestCount(t *testing.T) { + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/count"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + var count Count + count.S = "hello" + if err := JSON.Send(conn, count); err != nil { + t.Errorf("Write: %v", err) + } + if err := JSON.Receive(conn, &count); err != nil { + t.Errorf("Read: %v", err) + } + if count.N != 1 { + t.Errorf("count: expected %d got %d", 1, count.N) + } + if count.S != "hello" { + t.Errorf("count: expected %q got %q", "hello", count.S) + } + if err := JSON.Send(conn, count); err != nil { + t.Errorf("Write: %v", err) + } + if err := JSON.Receive(conn, &count); err != nil { + t.Errorf("Read: %v", err) + } + if count.N != 2 { + t.Errorf("count: expected %d got %d", 2, count.N) + } + if count.S != "hellohello" { + t.Errorf("count: expected %q got %q", "hellohello", count.S) + } + conn.Close() +} + +func TestWithQuery(t *testing.T) { + once.Do(startServer) + + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + + config := newConfig(t, "/echo") + config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr)) + if err != nil { + t.Fatal("location url", err) + } + + ws, err := NewClient(config, client) + if err != nil { + t.Errorf("WebSocket handshake: %v", err) + return + } + ws.Close() +} + +func testWithProtocol(t *testing.T, subproto []string) (string, error) { + once.Do(startServer) + + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + + config := newConfig(t, "/subproto") + config.Protocol = subproto + + ws, err := NewClient(config, client) + if err != nil { + return "", err + } + msg := make([]byte, 16) + n, err := ws.Read(msg) + if err != nil { + return "", err + } + ws.Close() + return string(msg[:n]), nil +} + +func TestWithProtocol(t *testing.T) { + proto, err := testWithProtocol(t, []string{"chat"}) + if err != nil { + t.Errorf("SubProto: unexpected error: %v", err) + } + if proto != "chat" { + t.Errorf("SubProto: expected %q, got %q", "chat", proto) + } +} + +func TestWithTwoProtocol(t *testing.T) { + proto, err := testWithProtocol(t, []string{"test", "chat"}) + if err != nil { + t.Errorf("SubProto: unexpected error: %v", err) + } + if proto != "chat" { + t.Errorf("SubProto: expected %q, got %q", "chat", proto) + } +} + +func TestWithBadProtocol(t *testing.T) { + _, err := testWithProtocol(t, []string{"test"}) + if err != ErrBadStatus { + t.Errorf("SubProto: expected %v, got %v", ErrBadStatus, err) + } +} + +func TestHTTP(t *testing.T) { + once.Do(startServer) + + // If the client did not send a handshake that matches the protocol + // specification, the server MUST return an HTTP response with an + // appropriate error code (such as 400 Bad Request) + resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr)) + if err != nil { + t.Errorf("Get: error %#v", err) + return + } + if resp == nil { + t.Error("Get: resp is null") + return + } + if resp.StatusCode != http.StatusBadRequest { + t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode) + } +} + +func TestTrailingSpaces(t *testing.T) { + // http://code.google.com/p/go/issues/detail?id=955 + // The last runs of this create keys with trailing spaces that should not be + // generated by the client. + once.Do(startServer) + config := newConfig(t, "/echo") + for i := 0; i < 30; i++ { + // body + ws, err := DialConfig(config) + if err != nil { + t.Errorf("Dial #%d failed: %v", i, err) + break + } + ws.Close() + } +} + +func TestDialConfigBadVersion(t *testing.T) { + once.Do(startServer) + config := newConfig(t, "/echo") + config.Version = 1234 + + _, err := DialConfig(config) + + if dialerr, ok := err.(*DialError); ok { + if dialerr.Err != ErrBadProtocolVersion { + t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err) + } + } +} + +func TestSmallBuffer(t *testing.T) { + // http://code.google.com/p/go/issues/detail?id=1145 + // Read should be able to handle reading a fragment of a frame. + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/echo"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + msg := []byte("hello, world\n") + if _, err := conn.Write(msg); err != nil { + t.Errorf("Write: %v", err) + } + var small_msg = make([]byte, 8) + n, err := conn.Read(small_msg) + if err != nil { + t.Errorf("Read: %v", err) + } + if !bytes.Equal(msg[:len(small_msg)], small_msg) { + t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg) + } + var second_msg = make([]byte, len(msg)) + n, err = conn.Read(second_msg) + if err != nil { + t.Errorf("Read: %v", err) + } + second_msg = second_msg[0:n] + if !bytes.Equal(msg[len(small_msg):], second_msg) { + t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg) + } + conn.Close() +} + +var parseAuthorityTests = []struct { + in *url.URL + out string +}{ + { + &url.URL{ + Scheme: "ws", + Host: "www.google.com", + }, + "www.google.com:80", + }, + { + &url.URL{ + Scheme: "wss", + Host: "www.google.com", + }, + "www.google.com:443", + }, + { + &url.URL{ + Scheme: "ws", + Host: "www.google.com:80", + }, + "www.google.com:80", + }, + { + &url.URL{ + Scheme: "wss", + Host: "www.google.com:443", + }, + "www.google.com:443", + }, + // some invalid ones for parseAuthority. parseAuthority doesn't + // concern itself with the scheme unless it actually knows about it + { + &url.URL{ + Scheme: "http", + Host: "www.google.com", + }, + "www.google.com", + }, + { + &url.URL{ + Scheme: "http", + Host: "www.google.com:80", + }, + "www.google.com:80", + }, + { + &url.URL{ + Scheme: "asdf", + Host: "127.0.0.1", + }, + "127.0.0.1", + }, + { + &url.URL{ + Scheme: "asdf", + Host: "www.google.com", + }, + "www.google.com", + }, +} + +func TestParseAuthority(t *testing.T) { + for _, tt := range parseAuthorityTests { + out := parseAuthority(tt.in) + if out != tt.out { + t.Errorf("got %v; want %v", out, tt.out) + } + } +} diff --git a/rpc/ws/server.go b/rpc/ws/server.go index 100713c10..b8cc2fa6b 100644 --- a/rpc/ws/server.go +++ b/rpc/ws/server.go @@ -21,10 +21,10 @@ import ( "net" "net/http" - "code.google.com/p/go.net/websocket" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/xeth" + "golang.org/x/net/websocket" ) var wslogger = logger.NewLogger("RPC-WS") -- cgit v1.2.3 From 119bea22aaf061d5b3e6a9abee9b1b95655b9fbe Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Feb 2015 13:05:58 +0100 Subject: crypto: switch to golang.org/x/crypto code.google.com/p/go.crypto is deprecated and will cause problems in future versions of Go. --- Godeps/Godeps.json | 23 +- .../code.google.com/p/go.crypto/pbkdf2/pbkdf2.go | 77 ------- .../p/go.crypto/pbkdf2/pbkdf2_test.go | 157 ------------- .../p/go.crypto/ripemd160/ripemd160.go | 120 ---------- .../p/go.crypto/ripemd160/ripemd160_test.go | 64 ------ .../p/go.crypto/ripemd160/ripemd160block.go | 161 -------------- .../code.google.com/p/go.crypto/scrypt/scrypt.go | 243 --------------------- .../p/go.crypto/scrypt/scrypt_test.go | 160 -------------- .../src/golang.org/x/crypto/ripemd160/ripemd160.go | 120 ++++++++++ .../x/crypto/ripemd160/ripemd160_test.go | 64 ++++++ .../x/crypto/ripemd160/ripemd160block.go | 161 ++++++++++++++ .../src/golang.org/x/crypto/scrypt/scrypt.go | 243 +++++++++++++++++++++ .../src/golang.org/x/crypto/scrypt/scrypt_test.go | 160 ++++++++++++++ crypto/crypto.go | 4 +- crypto/key_store_passphrase.go | 8 +- 15 files changed, 763 insertions(+), 1002 deletions(-) delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2_test.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160_test.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160block.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt_test.go create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160.go create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160_test.go create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160block.go create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt.go create mode 100644 Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 37176ddba..d91269c1d 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -15,21 +15,6 @@ "Comment": "null-12", "Rev": "7dda39b2e7d5e265014674c5af696ba4186679e9" }, - { - "ImportPath": "code.google.com/p/go.crypto/pbkdf2", - "Comment": "null-236", - "Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" - }, - { - "ImportPath": "code.google.com/p/go.crypto/ripemd160", - "Comment": "null-236", - "Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" - }, - { - "ImportPath": "code.google.com/p/go.crypto/scrypt", - "Comment": "null-236", - "Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" - }, { "ImportPath": "code.google.com/p/snappy-go/snappy", "Comment": "null-15", @@ -100,6 +85,14 @@ "ImportPath": "golang.org/x/crypto/pbkdf2", "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, + { + "ImportPath": "golang.org/x/crypto/ripemd160", + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" + }, + { + "ImportPath": "golang.org/x/crypto/scrypt", + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" + }, { "ImportPath": "golang.org/x/net/websocket", "Rev": "59b0df9b1f7abda5aab0495ee54f408daf182ce7" diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2.go deleted file mode 100644 index c02b4d5a7..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC -2898 / PKCS #5 v2.0. - -A key derivation function is useful when encrypting data based on a password -or any other not-fully-random data. It uses a pseudorandom function to derive -a secure encryption key based on the password. - -While v2.0 of the standard defines only one pseudorandom function to use, -HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved -Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To -choose, you can pass the `New` functions from the different SHA packages to -pbkdf2.Key. -*/ -package pbkdf2 - -import ( - "crypto/hmac" - "hash" -) - -// Key derives a key from the password, salt and iteration count, returning a -// []byte of length keylen that can be used as cryptographic key. The key is -// derived based on the method described as PBKDF2 with the HMAC variant using -// the supplied hash function. -// -// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you -// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by -// doing: -// -// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) -// -// Remember to get a good random salt. At least 8 bytes is recommended by the -// RFC. -// -// Using a higher iteration count will increase the cost of an exhaustive -// search but will also make derivation proportionally slower. -func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { - prf := hmac.New(h, password) - hashLen := prf.Size() - numBlocks := (keyLen + hashLen - 1) / hashLen - - var buf [4]byte - dk := make([]byte, 0, numBlocks*hashLen) - U := make([]byte, hashLen) - for block := 1; block <= numBlocks; block++ { - // N.B.: || means concatenation, ^ means XOR - // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter - // U_1 = PRF(password, salt || uint(i)) - prf.Reset() - prf.Write(salt) - buf[0] = byte(block >> 24) - buf[1] = byte(block >> 16) - buf[2] = byte(block >> 8) - buf[3] = byte(block) - prf.Write(buf[:4]) - dk = prf.Sum(dk) - T := dk[len(dk)-hashLen:] - copy(U, T) - - // U_n = PRF(password, U_(n-1)) - for n := 2; n <= iter; n++ { - prf.Reset() - prf.Write(U) - U = U[:0] - U = prf.Sum(U) - for x := range U { - T[x] ^= U[x] - } - } - } - return dk[:keyLen] -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2_test.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2_test.go deleted file mode 100644 index 137924061..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/pbkdf2/pbkdf2_test.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pbkdf2 - -import ( - "bytes" - "crypto/sha1" - "crypto/sha256" - "hash" - "testing" -) - -type testVector struct { - password string - salt string - iter int - output []byte -} - -// Test vectors from RFC 6070, http://tools.ietf.org/html/rfc6070 -var sha1TestVectors = []testVector{ - { - "password", - "salt", - 1, - []byte{ - 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, - 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, - 0x2f, 0xe0, 0x37, 0xa6, - }, - }, - { - "password", - "salt", - 2, - []byte{ - 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, - 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, - 0xd8, 0xde, 0x89, 0x57, - }, - }, - { - "password", - "salt", - 4096, - []byte{ - 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, - 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, - 0x65, 0xa4, 0x29, 0xc1, - }, - }, - // // This one takes too long - // { - // "password", - // "salt", - // 16777216, - // []byte{ - // 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4, - // 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c, - // 0x26, 0x34, 0xe9, 0x84, - // }, - // }, - { - "passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - []byte{ - 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, - 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, - 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, - 0x38, - }, - }, - { - "pass\000word", - "sa\000lt", - 4096, - []byte{ - 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, - 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3, - }, - }, -} - -// Test vectors from -// http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors -var sha256TestVectors = []testVector{ - { - "password", - "salt", - 1, - []byte{ - 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, - 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, - 0xa8, 0x65, 0x48, 0xc9, - }, - }, - { - "password", - "salt", - 2, - []byte{ - 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, - 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, - 0x2a, 0x30, 0x3f, 0x8e, - }, - }, - { - "password", - "salt", - 4096, - []byte{ - 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, - 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, - 0x96, 0x28, 0x93, 0xa0, - }, - }, - { - "passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - []byte{ - 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, - 0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, - 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, - 0x1c, - }, - }, - { - "pass\000word", - "sa\000lt", - 4096, - []byte{ - 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, - 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87, - }, - }, -} - -func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) { - for i, v := range vectors { - o := Key([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h) - if !bytes.Equal(o, v.output) { - t.Errorf("%s %d: expected %x, got %x", hashName, i, v.output, o) - } - } -} - -func TestWithHMACSHA1(t *testing.T) { - testHash(t, sha1.New, "SHA1", sha1TestVectors) -} - -func TestWithHMACSHA256(t *testing.T) { - testHash(t, sha256.New, "SHA256", sha256TestVectors) -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160.go deleted file mode 100644 index da690f0b9..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ripemd160 implements the RIPEMD-160 hash algorithm. -package ripemd160 - -// RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart -// Preneel with specifications available at: -// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf. - -import ( - "crypto" - "hash" -) - -func init() { - crypto.RegisterHash(crypto.RIPEMD160, New) -} - -// The size of the checksum in bytes. -const Size = 20 - -// The block size of the hash algorithm in bytes. -const BlockSize = 64 - -const ( - _s0 = 0x67452301 - _s1 = 0xefcdab89 - _s2 = 0x98badcfe - _s3 = 0x10325476 - _s4 = 0xc3d2e1f0 -) - -// digest represents the partial evaluation of a checksum. -type digest struct { - s [5]uint32 // running context - x [BlockSize]byte // temporary buffer - nx int // index into x - tc uint64 // total count of bytes processed -} - -func (d *digest) Reset() { - d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4 - d.nx = 0 - d.tc = 0 -} - -// New returns a new hash.Hash computing the checksum. -func New() hash.Hash { - result := new(digest) - result.Reset() - return result -} - -func (d *digest) Size() int { return Size } - -func (d *digest) BlockSize() int { return BlockSize } - -func (d *digest) Write(p []byte) (nn int, err error) { - nn = len(p) - d.tc += uint64(nn) - if d.nx > 0 { - n := len(p) - if n > BlockSize-d.nx { - n = BlockSize - d.nx - } - for i := 0; i < n; i++ { - d.x[d.nx+i] = p[i] - } - d.nx += n - if d.nx == BlockSize { - _Block(d, d.x[0:]) - d.nx = 0 - } - p = p[n:] - } - n := _Block(d, p) - p = p[n:] - if len(p) > 0 { - d.nx = copy(d.x[:], p) - } - return -} - -func (d0 *digest) Sum(in []byte) []byte { - // Make a copy of d0 so that caller can keep writing and summing. - d := *d0 - - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. - tc := d.tc - var tmp [64]byte - tmp[0] = 0x80 - if tc%64 < 56 { - d.Write(tmp[0 : 56-tc%64]) - } else { - d.Write(tmp[0 : 64+56-tc%64]) - } - - // Length in bits. - tc <<= 3 - for i := uint(0); i < 8; i++ { - tmp[i] = byte(tc >> (8 * i)) - } - d.Write(tmp[0:8]) - - if d.nx != 0 { - panic("d.nx != 0") - } - - var digest [Size]byte - for i, s := range d.s { - digest[i*4] = byte(s) - digest[i*4+1] = byte(s >> 8) - digest[i*4+2] = byte(s >> 16) - digest[i*4+3] = byte(s >> 24) - } - - return append(in, digest[:]...) -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160_test.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160_test.go deleted file mode 100644 index 5df1b2593..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ripemd160 - -// Test vectors are from: -// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html - -import ( - "fmt" - "io" - "testing" -) - -type mdTest struct { - out string - in string -} - -var vectors = [...]mdTest{ - {"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, - {"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"}, - {"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"}, - {"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"}, - {"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"}, - {"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - {"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - {"9b752e45573d4b39f4dbd3323cab82bf63326bfb", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, -} - -func TestVectors(t *testing.T) { - for i := 0; i < len(vectors); i++ { - tv := vectors[i] - md := New() - for j := 0; j < 3; j++ { - if j < 2 { - io.WriteString(md, tv.in) - } else { - io.WriteString(md, tv.in[0:len(tv.in)/2]) - md.Sum(nil) - io.WriteString(md, tv.in[len(tv.in)/2:]) - } - s := fmt.Sprintf("%x", md.Sum(nil)) - if s != tv.out { - t.Fatalf("RIPEMD-160[%d](%s) = %s, expected %s", j, tv.in, s, tv.out) - } - md.Reset() - } - } -} - -func TestMillionA(t *testing.T) { - md := New() - for i := 0; i < 100000; i++ { - io.WriteString(md, "aaaaaaaaaa") - } - out := "52783243c1697bdbe16d37f97f68f08325dc1528" - s := fmt.Sprintf("%x", md.Sum(nil)) - if s != out { - t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out) - } - md.Reset() -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160block.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160block.go deleted file mode 100644 index 7bc8e6c48..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160/ripemd160block.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// RIPEMD-160 block step. -// In its own file so that a faster assembly or C version -// can be substituted easily. - -package ripemd160 - -// work buffer indices and roll amounts for one line -var _n = [80]uint{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, - 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, - 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, - 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, -} - -var _r = [80]uint{ - 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, - 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, - 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, - 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, - 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, -} - -// same for the other parallel one -var n_ = [80]uint{ - 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, - 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, - 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, - 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, - 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11, -} - -var r_ = [80]uint{ - 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, - 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, - 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, - 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, - 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11, -} - -func _Block(md *digest, p []byte) int { - n := 0 - var x [16]uint32 - var alpha, beta uint32 - for len(p) >= BlockSize { - a, b, c, d, e := md.s[0], md.s[1], md.s[2], md.s[3], md.s[4] - aa, bb, cc, dd, ee := a, b, c, d, e - j := 0 - for i := 0; i < 16; i++ { - x[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 - j += 4 - } - - // round 1 - i := 0 - for i < 16 { - alpha = a + (b ^ c ^ d) + x[_n[i]] - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd - - i++ - } - - // round 2 - for i < 32 { - alpha = a + (b&c | ^b&d) + x[_n[i]] + 0x5a827999 - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd - - i++ - } - - // round 3 - for i < 48 { - alpha = a + (b | ^c ^ d) + x[_n[i]] + 0x6ed9eba1 - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd - - i++ - } - - // round 4 - for i < 64 { - alpha = a + (b&d | c&^d) + x[_n[i]] + 0x8f1bbcdc - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9 - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd - - i++ - } - - // round 5 - for i < 80 { - alpha = a + (b ^ (c | ^d)) + x[_n[i]] + 0xa953fd4e - s := _r[i] - alpha = (alpha<>(32-s)) + e - beta = c<<10 | c>>22 - a, b, c, d, e = e, alpha, b, beta, d - - // parallel line - alpha = aa + (bb ^ cc ^ dd) + x[n_[i]] - s = r_[i] - alpha = (alpha<>(32-s)) + ee - beta = cc<<10 | cc>>22 - aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd - - i++ - } - - // combine results - dd += c + md.s[1] - md.s[1] = md.s[2] + d + ee - md.s[2] = md.s[3] + e + aa - md.s[3] = md.s[4] + a + bb - md.s[4] = md.s[0] + b + cc - md.s[0] = dd - - p = p[BlockSize:] - n += BlockSize - } - return n -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt.go deleted file mode 100644 index 30737b0a6..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package scrypt implements the scrypt key derivation function as defined in -// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard -// Functions" (http://www.tarsnap.com/scrypt/scrypt.pdf). -package scrypt - -import ( - "crypto/sha256" - "errors" - - "golang.org/x/crypto/pbkdf2" -) - -const maxInt = int(^uint(0) >> 1) - -// blockCopy copies n numbers from src into dst. -func blockCopy(dst, src []uint32, n int) { - copy(dst, src[:n]) -} - -// blockXOR XORs numbers from dst with n numbers from src. -func blockXOR(dst, src []uint32, n int) { - for i, v := range src[:n] { - dst[i] ^= v - } -} - -// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in, -// and puts the result into both both tmp and out. -func salsaXOR(tmp *[16]uint32, in, out []uint32) { - w0 := tmp[0] ^ in[0] - w1 := tmp[1] ^ in[1] - w2 := tmp[2] ^ in[2] - w3 := tmp[3] ^ in[3] - w4 := tmp[4] ^ in[4] - w5 := tmp[5] ^ in[5] - w6 := tmp[6] ^ in[6] - w7 := tmp[7] ^ in[7] - w8 := tmp[8] ^ in[8] - w9 := tmp[9] ^ in[9] - w10 := tmp[10] ^ in[10] - w11 := tmp[11] ^ in[11] - w12 := tmp[12] ^ in[12] - w13 := tmp[13] ^ in[13] - w14 := tmp[14] ^ in[14] - w15 := tmp[15] ^ in[15] - - x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8 - x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15 - - for i := 0; i < 8; i += 2 { - u := x0 + x12 - x4 ^= u<<7 | u>>(32-7) - u = x4 + x0 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x4 - x12 ^= u<<13 | u>>(32-13) - u = x12 + x8 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x1 - x9 ^= u<<7 | u>>(32-7) - u = x9 + x5 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x9 - x1 ^= u<<13 | u>>(32-13) - u = x1 + x13 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x6 - x14 ^= u<<7 | u>>(32-7) - u = x14 + x10 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x14 - x6 ^= u<<13 | u>>(32-13) - u = x6 + x2 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x11 - x3 ^= u<<7 | u>>(32-7) - u = x3 + x15 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x3 - x11 ^= u<<13 | u>>(32-13) - u = x11 + x7 - x15 ^= u<<18 | u>>(32-18) - - u = x0 + x3 - x1 ^= u<<7 | u>>(32-7) - u = x1 + x0 - x2 ^= u<<9 | u>>(32-9) - u = x2 + x1 - x3 ^= u<<13 | u>>(32-13) - u = x3 + x2 - x0 ^= u<<18 | u>>(32-18) - - u = x5 + x4 - x6 ^= u<<7 | u>>(32-7) - u = x6 + x5 - x7 ^= u<<9 | u>>(32-9) - u = x7 + x6 - x4 ^= u<<13 | u>>(32-13) - u = x4 + x7 - x5 ^= u<<18 | u>>(32-18) - - u = x10 + x9 - x11 ^= u<<7 | u>>(32-7) - u = x11 + x10 - x8 ^= u<<9 | u>>(32-9) - u = x8 + x11 - x9 ^= u<<13 | u>>(32-13) - u = x9 + x8 - x10 ^= u<<18 | u>>(32-18) - - u = x15 + x14 - x12 ^= u<<7 | u>>(32-7) - u = x12 + x15 - x13 ^= u<<9 | u>>(32-9) - u = x13 + x12 - x14 ^= u<<13 | u>>(32-13) - u = x14 + x13 - x15 ^= u<<18 | u>>(32-18) - } - x0 += w0 - x1 += w1 - x2 += w2 - x3 += w3 - x4 += w4 - x5 += w5 - x6 += w6 - x7 += w7 - x8 += w8 - x9 += w9 - x10 += w10 - x11 += w11 - x12 += w12 - x13 += w13 - x14 += w14 - x15 += w15 - - out[0], tmp[0] = x0, x0 - out[1], tmp[1] = x1, x1 - out[2], tmp[2] = x2, x2 - out[3], tmp[3] = x3, x3 - out[4], tmp[4] = x4, x4 - out[5], tmp[5] = x5, x5 - out[6], tmp[6] = x6, x6 - out[7], tmp[7] = x7, x7 - out[8], tmp[8] = x8, x8 - out[9], tmp[9] = x9, x9 - out[10], tmp[10] = x10, x10 - out[11], tmp[11] = x11, x11 - out[12], tmp[12] = x12, x12 - out[13], tmp[13] = x13, x13 - out[14], tmp[14] = x14, x14 - out[15], tmp[15] = x15, x15 -} - -func blockMix(tmp *[16]uint32, in, out []uint32, r int) { - blockCopy(tmp[:], in[(2*r-1)*16:], 16) - for i := 0; i < 2*r; i += 2 { - salsaXOR(tmp, in[i*16:], out[i*8:]) - salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:]) - } -} - -func integer(b []uint32, r int) uint64 { - j := (2*r - 1) * 16 - return uint64(b[j]) | uint64(b[j+1])<<32 -} - -func smix(b []byte, r, N int, v, xy []uint32) { - var tmp [16]uint32 - x := xy - y := xy[32*r:] - - j := 0 - for i := 0; i < 32*r; i++ { - x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24 - j += 4 - } - for i := 0; i < N; i += 2 { - blockCopy(v[i*(32*r):], x, 32*r) - blockMix(&tmp, x, y, r) - - blockCopy(v[(i+1)*(32*r):], y, 32*r) - blockMix(&tmp, y, x, r) - } - for i := 0; i < N; i += 2 { - j := int(integer(x, r) & uint64(N-1)) - blockXOR(x, v[j*(32*r):], 32*r) - blockMix(&tmp, x, y, r) - - j = int(integer(y, r) & uint64(N-1)) - blockXOR(y, v[j*(32*r):], 32*r) - blockMix(&tmp, y, x, r) - } - j = 0 - for _, v := range x[:32*r] { - b[j+0] = byte(v >> 0) - b[j+1] = byte(v >> 8) - b[j+2] = byte(v >> 16) - b[j+3] = byte(v >> 24) - j += 4 - } -} - -// Key derives a key from the password, salt, and cost parameters, returning -// a byte slice of length keyLen that can be used as cryptographic key. -// -// N is a CPU/memory cost parameter, which must be a power of two greater than 1. -// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the -// limits, the function returns a nil byte slice and an error. -// -// For example, you can get a derived key for e.g. AES-256 (which needs a -// 32-byte key) by doing: -// -// dk := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32) -// -// The recommended parameters for interactive logins as of 2009 are N=16384, -// r=8, p=1. They should be increased as memory latency and CPU parallelism -// increases. Remember to get a good random salt. -func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) { - if N <= 1 || N&(N-1) != 0 { - return nil, errors.New("scrypt: N must be > 1 and a power of 2") - } - if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r { - return nil, errors.New("scrypt: parameters are too large") - } - - xy := make([]uint32, 64*r) - v := make([]uint32, 32*N*r) - b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New) - - for i := 0; i < p; i++ { - smix(b[i*128*r:], r, N, v, xy) - } - - return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil -} diff --git a/Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt_test.go b/Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt_test.go deleted file mode 100644 index e096c3a31..000000000 --- a/Godeps/_workspace/src/code.google.com/p/go.crypto/scrypt/scrypt_test.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package scrypt - -import ( - "bytes" - "testing" -) - -type testVector struct { - password string - salt string - N, r, p int - output []byte -} - -var good = []testVector{ - { - "password", - "salt", - 2, 10, 10, - []byte{ - 0x48, 0x2c, 0x85, 0x8e, 0x22, 0x90, 0x55, 0xe6, 0x2f, - 0x41, 0xe0, 0xec, 0x81, 0x9a, 0x5e, 0xe1, 0x8b, 0xdb, - 0x87, 0x25, 0x1a, 0x53, 0x4f, 0x75, 0xac, 0xd9, 0x5a, - 0xc5, 0xe5, 0xa, 0xa1, 0x5f, - }, - }, - { - "password", - "salt", - 16, 100, 100, - []byte{ - 0x88, 0xbd, 0x5e, 0xdb, 0x52, 0xd1, 0xdd, 0x0, 0x18, - 0x87, 0x72, 0xad, 0x36, 0x17, 0x12, 0x90, 0x22, 0x4e, - 0x74, 0x82, 0x95, 0x25, 0xb1, 0x8d, 0x73, 0x23, 0xa5, - 0x7f, 0x91, 0x96, 0x3c, 0x37, - }, - }, - { - "this is a long \000 password", - "and this is a long \000 salt", - 16384, 8, 1, - []byte{ - 0xc3, 0xf1, 0x82, 0xee, 0x2d, 0xec, 0x84, 0x6e, 0x70, - 0xa6, 0x94, 0x2f, 0xb5, 0x29, 0x98, 0x5a, 0x3a, 0x09, - 0x76, 0x5e, 0xf0, 0x4c, 0x61, 0x29, 0x23, 0xb1, 0x7f, - 0x18, 0x55, 0x5a, 0x37, 0x07, 0x6d, 0xeb, 0x2b, 0x98, - 0x30, 0xd6, 0x9d, 0xe5, 0x49, 0x26, 0x51, 0xe4, 0x50, - 0x6a, 0xe5, 0x77, 0x6d, 0x96, 0xd4, 0x0f, 0x67, 0xaa, - 0xee, 0x37, 0xe1, 0x77, 0x7b, 0x8a, 0xd5, 0xc3, 0x11, - 0x14, 0x32, 0xbb, 0x3b, 0x6f, 0x7e, 0x12, 0x64, 0x40, - 0x18, 0x79, 0xe6, 0x41, 0xae, - }, - }, - { - "p", - "s", - 2, 1, 1, - []byte{ - 0x48, 0xb0, 0xd2, 0xa8, 0xa3, 0x27, 0x26, 0x11, 0x98, - 0x4c, 0x50, 0xeb, 0xd6, 0x30, 0xaf, 0x52, - }, - }, - - { - "", - "", - 16, 1, 1, - []byte{ - 0x77, 0xd6, 0x57, 0x62, 0x38, 0x65, 0x7b, 0x20, 0x3b, - 0x19, 0xca, 0x42, 0xc1, 0x8a, 0x04, 0x97, 0xf1, 0x6b, - 0x48, 0x44, 0xe3, 0x07, 0x4a, 0xe8, 0xdf, 0xdf, 0xfa, - 0x3f, 0xed, 0xe2, 0x14, 0x42, 0xfc, 0xd0, 0x06, 0x9d, - 0xed, 0x09, 0x48, 0xf8, 0x32, 0x6a, 0x75, 0x3a, 0x0f, - 0xc8, 0x1f, 0x17, 0xe8, 0xd3, 0xe0, 0xfb, 0x2e, 0x0d, - 0x36, 0x28, 0xcf, 0x35, 0xe2, 0x0c, 0x38, 0xd1, 0x89, - 0x06, - }, - }, - { - "password", - "NaCl", - 1024, 8, 16, - []byte{ - 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, 0x78, - 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, 0x7c, 0x6a, - 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, 0xe7, 0x73, 0x76, - 0x63, 0x4b, 0x37, 0x31, 0x62, 0x2e, 0xaf, 0x30, 0xd9, - 0x2e, 0x22, 0xa3, 0x88, 0x6f, 0xf1, 0x09, 0x27, 0x9d, - 0x98, 0x30, 0xda, 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, - 0xee, 0x6d, 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, - 0x40, - }, - }, - { - "pleaseletmein", "SodiumChloride", - 16384, 8, 1, - []byte{ - 0x70, 0x23, 0xbd, 0xcb, 0x3a, 0xfd, 0x73, 0x48, 0x46, - 0x1c, 0x06, 0xcd, 0x81, 0xfd, 0x38, 0xeb, 0xfd, 0xa8, - 0xfb, 0xba, 0x90, 0x4f, 0x8e, 0x3e, 0xa9, 0xb5, 0x43, - 0xf6, 0x54, 0x5d, 0xa1, 0xf2, 0xd5, 0x43, 0x29, 0x55, - 0x61, 0x3f, 0x0f, 0xcf, 0x62, 0xd4, 0x97, 0x05, 0x24, - 0x2a, 0x9a, 0xf9, 0xe6, 0x1e, 0x85, 0xdc, 0x0d, 0x65, - 0x1e, 0x40, 0xdf, 0xcf, 0x01, 0x7b, 0x45, 0x57, 0x58, - 0x87, - }, - }, - /* - // Disabled: needs 1 GiB RAM and takes too long for a simple test. - { - "pleaseletmein", "SodiumChloride", - 1048576, 8, 1, - []byte{ - 0x21, 0x01, 0xcb, 0x9b, 0x6a, 0x51, 0x1a, 0xae, 0xad, - 0xdb, 0xbe, 0x09, 0xcf, 0x70, 0xf8, 0x81, 0xec, 0x56, - 0x8d, 0x57, 0x4a, 0x2f, 0xfd, 0x4d, 0xab, 0xe5, 0xee, - 0x98, 0x20, 0xad, 0xaa, 0x47, 0x8e, 0x56, 0xfd, 0x8f, - 0x4b, 0xa5, 0xd0, 0x9f, 0xfa, 0x1c, 0x6d, 0x92, 0x7c, - 0x40, 0xf4, 0xc3, 0x37, 0x30, 0x40, 0x49, 0xe8, 0xa9, - 0x52, 0xfb, 0xcb, 0xf4, 0x5c, 0x6f, 0xa7, 0x7a, 0x41, - 0xa4, - }, - }, - */ -} - -var bad = []testVector{ - {"p", "s", 0, 1, 1, nil}, // N == 0 - {"p", "s", 1, 1, 1, nil}, // N == 1 - {"p", "s", 7, 8, 1, nil}, // N is not power of 2 - {"p", "s", 16, maxInt / 2, maxInt / 2, nil}, // p * r too large -} - -func TestKey(t *testing.T) { - for i, v := range good { - k, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, len(v.output)) - if err != nil { - t.Errorf("%d: got unexpected error: %s", i, err) - } - if !bytes.Equal(k, v.output) { - t.Errorf("%d: expected %x, got %x", i, v.output, k) - } - } - for i, v := range bad { - _, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, 32) - if err == nil { - t.Errorf("%d: expected error, got nil", i) - } - } -} - -func BenchmarkKey(b *testing.B) { - for i := 0; i < b.N; i++ { - Key([]byte("password"), []byte("salt"), 16384, 8, 1, 64) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160.go b/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160.go new file mode 100644 index 000000000..da690f0b9 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160.go @@ -0,0 +1,120 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ripemd160 implements the RIPEMD-160 hash algorithm. +package ripemd160 + +// RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart +// Preneel with specifications available at: +// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf. + +import ( + "crypto" + "hash" +) + +func init() { + crypto.RegisterHash(crypto.RIPEMD160, New) +} + +// The size of the checksum in bytes. +const Size = 20 + +// The block size of the hash algorithm in bytes. +const BlockSize = 64 + +const ( + _s0 = 0x67452301 + _s1 = 0xefcdab89 + _s2 = 0x98badcfe + _s3 = 0x10325476 + _s4 = 0xc3d2e1f0 +) + +// digest represents the partial evaluation of a checksum. +type digest struct { + s [5]uint32 // running context + x [BlockSize]byte // temporary buffer + nx int // index into x + tc uint64 // total count of bytes processed +} + +func (d *digest) Reset() { + d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4 + d.nx = 0 + d.tc = 0 +} + +// New returns a new hash.Hash computing the checksum. +func New() hash.Hash { + result := new(digest) + result.Reset() + return result +} + +func (d *digest) Size() int { return Size } + +func (d *digest) BlockSize() int { return BlockSize } + +func (d *digest) Write(p []byte) (nn int, err error) { + nn = len(p) + d.tc += uint64(nn) + if d.nx > 0 { + n := len(p) + if n > BlockSize-d.nx { + n = BlockSize - d.nx + } + for i := 0; i < n; i++ { + d.x[d.nx+i] = p[i] + } + d.nx += n + if d.nx == BlockSize { + _Block(d, d.x[0:]) + d.nx = 0 + } + p = p[n:] + } + n := _Block(d, p) + p = p[n:] + if len(p) > 0 { + d.nx = copy(d.x[:], p) + } + return +} + +func (d0 *digest) Sum(in []byte) []byte { + // Make a copy of d0 so that caller can keep writing and summing. + d := *d0 + + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. + tc := d.tc + var tmp [64]byte + tmp[0] = 0x80 + if tc%64 < 56 { + d.Write(tmp[0 : 56-tc%64]) + } else { + d.Write(tmp[0 : 64+56-tc%64]) + } + + // Length in bits. + tc <<= 3 + for i := uint(0); i < 8; i++ { + tmp[i] = byte(tc >> (8 * i)) + } + d.Write(tmp[0:8]) + + if d.nx != 0 { + panic("d.nx != 0") + } + + var digest [Size]byte + for i, s := range d.s { + digest[i*4] = byte(s) + digest[i*4+1] = byte(s >> 8) + digest[i*4+2] = byte(s >> 16) + digest[i*4+3] = byte(s >> 24) + } + + return append(in, digest[:]...) +} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160_test.go b/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160_test.go new file mode 100644 index 000000000..5df1b2593 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160_test.go @@ -0,0 +1,64 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ripemd160 + +// Test vectors are from: +// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + +import ( + "fmt" + "io" + "testing" +) + +type mdTest struct { + out string + in string +} + +var vectors = [...]mdTest{ + {"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, + {"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"}, + {"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"}, + {"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"}, + {"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"}, + {"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + {"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + {"9b752e45573d4b39f4dbd3323cab82bf63326bfb", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, +} + +func TestVectors(t *testing.T) { + for i := 0; i < len(vectors); i++ { + tv := vectors[i] + md := New() + for j := 0; j < 3; j++ { + if j < 2 { + io.WriteString(md, tv.in) + } else { + io.WriteString(md, tv.in[0:len(tv.in)/2]) + md.Sum(nil) + io.WriteString(md, tv.in[len(tv.in)/2:]) + } + s := fmt.Sprintf("%x", md.Sum(nil)) + if s != tv.out { + t.Fatalf("RIPEMD-160[%d](%s) = %s, expected %s", j, tv.in, s, tv.out) + } + md.Reset() + } + } +} + +func TestMillionA(t *testing.T) { + md := New() + for i := 0; i < 100000; i++ { + io.WriteString(md, "aaaaaaaaaa") + } + out := "52783243c1697bdbe16d37f97f68f08325dc1528" + s := fmt.Sprintf("%x", md.Sum(nil)) + if s != out { + t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out) + } + md.Reset() +} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160block.go b/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160block.go new file mode 100644 index 000000000..7bc8e6c48 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/ripemd160/ripemd160block.go @@ -0,0 +1,161 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// RIPEMD-160 block step. +// In its own file so that a faster assembly or C version +// can be substituted easily. + +package ripemd160 + +// work buffer indices and roll amounts for one line +var _n = [80]uint{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, +} + +var _r = [80]uint{ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, +} + +// same for the other parallel one +var n_ = [80]uint{ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11, +} + +var r_ = [80]uint{ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11, +} + +func _Block(md *digest, p []byte) int { + n := 0 + var x [16]uint32 + var alpha, beta uint32 + for len(p) >= BlockSize { + a, b, c, d, e := md.s[0], md.s[1], md.s[2], md.s[3], md.s[4] + aa, bb, cc, dd, ee := a, b, c, d, e + j := 0 + for i := 0; i < 16; i++ { + x[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 + j += 4 + } + + // round 1 + i := 0 + for i < 16 { + alpha = a + (b ^ c ^ d) + x[_n[i]] + s := _r[i] + alpha = (alpha<>(32-s)) + e + beta = c<<10 | c>>22 + a, b, c, d, e = e, alpha, b, beta, d + + // parallel line + alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6 + s = r_[i] + alpha = (alpha<>(32-s)) + ee + beta = cc<<10 | cc>>22 + aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd + + i++ + } + + // round 2 + for i < 32 { + alpha = a + (b&c | ^b&d) + x[_n[i]] + 0x5a827999 + s := _r[i] + alpha = (alpha<>(32-s)) + e + beta = c<<10 | c>>22 + a, b, c, d, e = e, alpha, b, beta, d + + // parallel line + alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124 + s = r_[i] + alpha = (alpha<>(32-s)) + ee + beta = cc<<10 | cc>>22 + aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd + + i++ + } + + // round 3 + for i < 48 { + alpha = a + (b | ^c ^ d) + x[_n[i]] + 0x6ed9eba1 + s := _r[i] + alpha = (alpha<>(32-s)) + e + beta = c<<10 | c>>22 + a, b, c, d, e = e, alpha, b, beta, d + + // parallel line + alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3 + s = r_[i] + alpha = (alpha<>(32-s)) + ee + beta = cc<<10 | cc>>22 + aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd + + i++ + } + + // round 4 + for i < 64 { + alpha = a + (b&d | c&^d) + x[_n[i]] + 0x8f1bbcdc + s := _r[i] + alpha = (alpha<>(32-s)) + e + beta = c<<10 | c>>22 + a, b, c, d, e = e, alpha, b, beta, d + + // parallel line + alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9 + s = r_[i] + alpha = (alpha<>(32-s)) + ee + beta = cc<<10 | cc>>22 + aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd + + i++ + } + + // round 5 + for i < 80 { + alpha = a + (b ^ (c | ^d)) + x[_n[i]] + 0xa953fd4e + s := _r[i] + alpha = (alpha<>(32-s)) + e + beta = c<<10 | c>>22 + a, b, c, d, e = e, alpha, b, beta, d + + // parallel line + alpha = aa + (bb ^ cc ^ dd) + x[n_[i]] + s = r_[i] + alpha = (alpha<>(32-s)) + ee + beta = cc<<10 | cc>>22 + aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd + + i++ + } + + // combine results + dd += c + md.s[1] + md.s[1] = md.s[2] + d + ee + md.s[2] = md.s[3] + e + aa + md.s[3] = md.s[4] + a + bb + md.s[4] = md.s[0] + b + cc + md.s[0] = dd + + p = p[BlockSize:] + n += BlockSize + } + return n +} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt.go b/Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt.go new file mode 100644 index 000000000..30737b0a6 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt.go @@ -0,0 +1,243 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package scrypt implements the scrypt key derivation function as defined in +// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard +// Functions" (http://www.tarsnap.com/scrypt/scrypt.pdf). +package scrypt + +import ( + "crypto/sha256" + "errors" + + "golang.org/x/crypto/pbkdf2" +) + +const maxInt = int(^uint(0) >> 1) + +// blockCopy copies n numbers from src into dst. +func blockCopy(dst, src []uint32, n int) { + copy(dst, src[:n]) +} + +// blockXOR XORs numbers from dst with n numbers from src. +func blockXOR(dst, src []uint32, n int) { + for i, v := range src[:n] { + dst[i] ^= v + } +} + +// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in, +// and puts the result into both both tmp and out. +func salsaXOR(tmp *[16]uint32, in, out []uint32) { + w0 := tmp[0] ^ in[0] + w1 := tmp[1] ^ in[1] + w2 := tmp[2] ^ in[2] + w3 := tmp[3] ^ in[3] + w4 := tmp[4] ^ in[4] + w5 := tmp[5] ^ in[5] + w6 := tmp[6] ^ in[6] + w7 := tmp[7] ^ in[7] + w8 := tmp[8] ^ in[8] + w9 := tmp[9] ^ in[9] + w10 := tmp[10] ^ in[10] + w11 := tmp[11] ^ in[11] + w12 := tmp[12] ^ in[12] + w13 := tmp[13] ^ in[13] + w14 := tmp[14] ^ in[14] + w15 := tmp[15] ^ in[15] + + x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8 + x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15 + + for i := 0; i < 8; i += 2 { + u := x0 + x12 + x4 ^= u<<7 | u>>(32-7) + u = x4 + x0 + x8 ^= u<<9 | u>>(32-9) + u = x8 + x4 + x12 ^= u<<13 | u>>(32-13) + u = x12 + x8 + x0 ^= u<<18 | u>>(32-18) + + u = x5 + x1 + x9 ^= u<<7 | u>>(32-7) + u = x9 + x5 + x13 ^= u<<9 | u>>(32-9) + u = x13 + x9 + x1 ^= u<<13 | u>>(32-13) + u = x1 + x13 + x5 ^= u<<18 | u>>(32-18) + + u = x10 + x6 + x14 ^= u<<7 | u>>(32-7) + u = x14 + x10 + x2 ^= u<<9 | u>>(32-9) + u = x2 + x14 + x6 ^= u<<13 | u>>(32-13) + u = x6 + x2 + x10 ^= u<<18 | u>>(32-18) + + u = x15 + x11 + x3 ^= u<<7 | u>>(32-7) + u = x3 + x15 + x7 ^= u<<9 | u>>(32-9) + u = x7 + x3 + x11 ^= u<<13 | u>>(32-13) + u = x11 + x7 + x15 ^= u<<18 | u>>(32-18) + + u = x0 + x3 + x1 ^= u<<7 | u>>(32-7) + u = x1 + x0 + x2 ^= u<<9 | u>>(32-9) + u = x2 + x1 + x3 ^= u<<13 | u>>(32-13) + u = x3 + x2 + x0 ^= u<<18 | u>>(32-18) + + u = x5 + x4 + x6 ^= u<<7 | u>>(32-7) + u = x6 + x5 + x7 ^= u<<9 | u>>(32-9) + u = x7 + x6 + x4 ^= u<<13 | u>>(32-13) + u = x4 + x7 + x5 ^= u<<18 | u>>(32-18) + + u = x10 + x9 + x11 ^= u<<7 | u>>(32-7) + u = x11 + x10 + x8 ^= u<<9 | u>>(32-9) + u = x8 + x11 + x9 ^= u<<13 | u>>(32-13) + u = x9 + x8 + x10 ^= u<<18 | u>>(32-18) + + u = x15 + x14 + x12 ^= u<<7 | u>>(32-7) + u = x12 + x15 + x13 ^= u<<9 | u>>(32-9) + u = x13 + x12 + x14 ^= u<<13 | u>>(32-13) + u = x14 + x13 + x15 ^= u<<18 | u>>(32-18) + } + x0 += w0 + x1 += w1 + x2 += w2 + x3 += w3 + x4 += w4 + x5 += w5 + x6 += w6 + x7 += w7 + x8 += w8 + x9 += w9 + x10 += w10 + x11 += w11 + x12 += w12 + x13 += w13 + x14 += w14 + x15 += w15 + + out[0], tmp[0] = x0, x0 + out[1], tmp[1] = x1, x1 + out[2], tmp[2] = x2, x2 + out[3], tmp[3] = x3, x3 + out[4], tmp[4] = x4, x4 + out[5], tmp[5] = x5, x5 + out[6], tmp[6] = x6, x6 + out[7], tmp[7] = x7, x7 + out[8], tmp[8] = x8, x8 + out[9], tmp[9] = x9, x9 + out[10], tmp[10] = x10, x10 + out[11], tmp[11] = x11, x11 + out[12], tmp[12] = x12, x12 + out[13], tmp[13] = x13, x13 + out[14], tmp[14] = x14, x14 + out[15], tmp[15] = x15, x15 +} + +func blockMix(tmp *[16]uint32, in, out []uint32, r int) { + blockCopy(tmp[:], in[(2*r-1)*16:], 16) + for i := 0; i < 2*r; i += 2 { + salsaXOR(tmp, in[i*16:], out[i*8:]) + salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:]) + } +} + +func integer(b []uint32, r int) uint64 { + j := (2*r - 1) * 16 + return uint64(b[j]) | uint64(b[j+1])<<32 +} + +func smix(b []byte, r, N int, v, xy []uint32) { + var tmp [16]uint32 + x := xy + y := xy[32*r:] + + j := 0 + for i := 0; i < 32*r; i++ { + x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24 + j += 4 + } + for i := 0; i < N; i += 2 { + blockCopy(v[i*(32*r):], x, 32*r) + blockMix(&tmp, x, y, r) + + blockCopy(v[(i+1)*(32*r):], y, 32*r) + blockMix(&tmp, y, x, r) + } + for i := 0; i < N; i += 2 { + j := int(integer(x, r) & uint64(N-1)) + blockXOR(x, v[j*(32*r):], 32*r) + blockMix(&tmp, x, y, r) + + j = int(integer(y, r) & uint64(N-1)) + blockXOR(y, v[j*(32*r):], 32*r) + blockMix(&tmp, y, x, r) + } + j = 0 + for _, v := range x[:32*r] { + b[j+0] = byte(v >> 0) + b[j+1] = byte(v >> 8) + b[j+2] = byte(v >> 16) + b[j+3] = byte(v >> 24) + j += 4 + } +} + +// Key derives a key from the password, salt, and cost parameters, returning +// a byte slice of length keyLen that can be used as cryptographic key. +// +// N is a CPU/memory cost parameter, which must be a power of two greater than 1. +// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the +// limits, the function returns a nil byte slice and an error. +// +// For example, you can get a derived key for e.g. AES-256 (which needs a +// 32-byte key) by doing: +// +// dk := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32) +// +// The recommended parameters for interactive logins as of 2009 are N=16384, +// r=8, p=1. They should be increased as memory latency and CPU parallelism +// increases. Remember to get a good random salt. +func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) { + if N <= 1 || N&(N-1) != 0 { + return nil, errors.New("scrypt: N must be > 1 and a power of 2") + } + if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r { + return nil, errors.New("scrypt: parameters are too large") + } + + xy := make([]uint32, 64*r) + v := make([]uint32, 32*N*r) + b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New) + + for i := 0; i < p; i++ { + smix(b[i*128*r:], r, N, v, xy) + } + + return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil +} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt_test.go b/Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt_test.go new file mode 100644 index 000000000..e096c3a31 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/scrypt/scrypt_test.go @@ -0,0 +1,160 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package scrypt + +import ( + "bytes" + "testing" +) + +type testVector struct { + password string + salt string + N, r, p int + output []byte +} + +var good = []testVector{ + { + "password", + "salt", + 2, 10, 10, + []byte{ + 0x48, 0x2c, 0x85, 0x8e, 0x22, 0x90, 0x55, 0xe6, 0x2f, + 0x41, 0xe0, 0xec, 0x81, 0x9a, 0x5e, 0xe1, 0x8b, 0xdb, + 0x87, 0x25, 0x1a, 0x53, 0x4f, 0x75, 0xac, 0xd9, 0x5a, + 0xc5, 0xe5, 0xa, 0xa1, 0x5f, + }, + }, + { + "password", + "salt", + 16, 100, 100, + []byte{ + 0x88, 0xbd, 0x5e, 0xdb, 0x52, 0xd1, 0xdd, 0x0, 0x18, + 0x87, 0x72, 0xad, 0x36, 0x17, 0x12, 0x90, 0x22, 0x4e, + 0x74, 0x82, 0x95, 0x25, 0xb1, 0x8d, 0x73, 0x23, 0xa5, + 0x7f, 0x91, 0x96, 0x3c, 0x37, + }, + }, + { + "this is a long \000 password", + "and this is a long \000 salt", + 16384, 8, 1, + []byte{ + 0xc3, 0xf1, 0x82, 0xee, 0x2d, 0xec, 0x84, 0x6e, 0x70, + 0xa6, 0x94, 0x2f, 0xb5, 0x29, 0x98, 0x5a, 0x3a, 0x09, + 0x76, 0x5e, 0xf0, 0x4c, 0x61, 0x29, 0x23, 0xb1, 0x7f, + 0x18, 0x55, 0x5a, 0x37, 0x07, 0x6d, 0xeb, 0x2b, 0x98, + 0x30, 0xd6, 0x9d, 0xe5, 0x49, 0x26, 0x51, 0xe4, 0x50, + 0x6a, 0xe5, 0x77, 0x6d, 0x96, 0xd4, 0x0f, 0x67, 0xaa, + 0xee, 0x37, 0xe1, 0x77, 0x7b, 0x8a, 0xd5, 0xc3, 0x11, + 0x14, 0x32, 0xbb, 0x3b, 0x6f, 0x7e, 0x12, 0x64, 0x40, + 0x18, 0x79, 0xe6, 0x41, 0xae, + }, + }, + { + "p", + "s", + 2, 1, 1, + []byte{ + 0x48, 0xb0, 0xd2, 0xa8, 0xa3, 0x27, 0x26, 0x11, 0x98, + 0x4c, 0x50, 0xeb, 0xd6, 0x30, 0xaf, 0x52, + }, + }, + + { + "", + "", + 16, 1, 1, + []byte{ + 0x77, 0xd6, 0x57, 0x62, 0x38, 0x65, 0x7b, 0x20, 0x3b, + 0x19, 0xca, 0x42, 0xc1, 0x8a, 0x04, 0x97, 0xf1, 0x6b, + 0x48, 0x44, 0xe3, 0x07, 0x4a, 0xe8, 0xdf, 0xdf, 0xfa, + 0x3f, 0xed, 0xe2, 0x14, 0x42, 0xfc, 0xd0, 0x06, 0x9d, + 0xed, 0x09, 0x48, 0xf8, 0x32, 0x6a, 0x75, 0x3a, 0x0f, + 0xc8, 0x1f, 0x17, 0xe8, 0xd3, 0xe0, 0xfb, 0x2e, 0x0d, + 0x36, 0x28, 0xcf, 0x35, 0xe2, 0x0c, 0x38, 0xd1, 0x89, + 0x06, + }, + }, + { + "password", + "NaCl", + 1024, 8, 16, + []byte{ + 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, 0x78, + 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, 0x7c, 0x6a, + 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, 0xe7, 0x73, 0x76, + 0x63, 0x4b, 0x37, 0x31, 0x62, 0x2e, 0xaf, 0x30, 0xd9, + 0x2e, 0x22, 0xa3, 0x88, 0x6f, 0xf1, 0x09, 0x27, 0x9d, + 0x98, 0x30, 0xda, 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, + 0xee, 0x6d, 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, + 0x40, + }, + }, + { + "pleaseletmein", "SodiumChloride", + 16384, 8, 1, + []byte{ + 0x70, 0x23, 0xbd, 0xcb, 0x3a, 0xfd, 0x73, 0x48, 0x46, + 0x1c, 0x06, 0xcd, 0x81, 0xfd, 0x38, 0xeb, 0xfd, 0xa8, + 0xfb, 0xba, 0x90, 0x4f, 0x8e, 0x3e, 0xa9, 0xb5, 0x43, + 0xf6, 0x54, 0x5d, 0xa1, 0xf2, 0xd5, 0x43, 0x29, 0x55, + 0x61, 0x3f, 0x0f, 0xcf, 0x62, 0xd4, 0x97, 0x05, 0x24, + 0x2a, 0x9a, 0xf9, 0xe6, 0x1e, 0x85, 0xdc, 0x0d, 0x65, + 0x1e, 0x40, 0xdf, 0xcf, 0x01, 0x7b, 0x45, 0x57, 0x58, + 0x87, + }, + }, + /* + // Disabled: needs 1 GiB RAM and takes too long for a simple test. + { + "pleaseletmein", "SodiumChloride", + 1048576, 8, 1, + []byte{ + 0x21, 0x01, 0xcb, 0x9b, 0x6a, 0x51, 0x1a, 0xae, 0xad, + 0xdb, 0xbe, 0x09, 0xcf, 0x70, 0xf8, 0x81, 0xec, 0x56, + 0x8d, 0x57, 0x4a, 0x2f, 0xfd, 0x4d, 0xab, 0xe5, 0xee, + 0x98, 0x20, 0xad, 0xaa, 0x47, 0x8e, 0x56, 0xfd, 0x8f, + 0x4b, 0xa5, 0xd0, 0x9f, 0xfa, 0x1c, 0x6d, 0x92, 0x7c, + 0x40, 0xf4, 0xc3, 0x37, 0x30, 0x40, 0x49, 0xe8, 0xa9, + 0x52, 0xfb, 0xcb, 0xf4, 0x5c, 0x6f, 0xa7, 0x7a, 0x41, + 0xa4, + }, + }, + */ +} + +var bad = []testVector{ + {"p", "s", 0, 1, 1, nil}, // N == 0 + {"p", "s", 1, 1, 1, nil}, // N == 1 + {"p", "s", 7, 8, 1, nil}, // N is not power of 2 + {"p", "s", 16, maxInt / 2, maxInt / 2, nil}, // p * r too large +} + +func TestKey(t *testing.T) { + for i, v := range good { + k, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, len(v.output)) + if err != nil { + t.Errorf("%d: got unexpected error: %s", i, err) + } + if !bytes.Equal(k, v.output) { + t.Errorf("%d: expected %x, got %x", i, v.output, k) + } + } + for i, v := range bad { + _, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, 32) + if err == nil { + t.Errorf("%d: expected error, got nil", i) + } + } +} + +func BenchmarkKey(b *testing.B) { + for i := 0; i < b.N; i++ { + Key([]byte("password"), []byte("salt"), 16384, 8, 1, 64) + } +} diff --git a/crypto/crypto.go b/crypto/crypto.go index e59250eb2..90e2c8939 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -16,12 +16,12 @@ import ( "errors" "code.google.com/p/go-uuid/uuid" - "code.google.com/p/go.crypto/pbkdf2" - "code.google.com/p/go.crypto/ripemd160" "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/crypto/secp256k1" "github.com/ethereum/go-ethereum/crypto/sha3" "github.com/ethereum/go-ethereum/ethutil" + "golang.org/x/crypto/pbkdf2" + "golang.org/x/crypto/ripemd160" ) func init() { diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go index 74408f874..7d21b6604 100644 --- a/crypto/key_store_passphrase.go +++ b/crypto/key_store_passphrase.go @@ -20,6 +20,7 @@ * @date 2015 * */ + /* This key store behaves as KeyStorePlain with the difference that @@ -64,17 +65,18 @@ package crypto import ( "bytes" - "code.google.com/p/go-uuid/uuid" - "code.google.com/p/go.crypto/scrypt" "crypto/aes" "crypto/cipher" "encoding/hex" "encoding/json" "errors" - "github.com/ethereum/go-ethereum/crypto/randentropy" "io" "os" "path" + + "code.google.com/p/go-uuid/uuid" + "github.com/ethereum/go-ethereum/crypto/randentropy" + "golang.org/x/crypto/scrypt" ) const ( -- cgit v1.2.3 From f965f41b6e8d177f4f06a8421ee071350813a1ac Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Feb 2015 13:10:11 +0100 Subject: p2p/nat: switch to github.com/huin/goupnp My temporary fix was merged upstream. --- Godeps/Godeps.json | 8 +- .../_workspace/src/github.com/fjl/goupnp/LICENSE | 23 - .../_workspace/src/github.com/fjl/goupnp/README.md | 14 - .../example_httpu_serving/example_httpu_serving.go | 20 - .../example_internetgateway1.go | 67 - .../dcps/internetgateway1/internetgateway1.go | 3957 --------------- .../dcps/internetgateway2/internetgateway2.go | 5271 -------------------- .../_workspace/src/github.com/fjl/goupnp/device.go | 184 - .../src/github.com/fjl/goupnp/example/example.go | 6 - .../github.com/fjl/goupnp/example/example_test.go | 62 - .../github.com/fjl/goupnp/gotasks/specgen_task.go | 539 -- .../_workspace/src/github.com/fjl/goupnp/goupnp.go | 109 - .../src/github.com/fjl/goupnp/httpu/httpu.go | 117 - .../src/github.com/fjl/goupnp/httpu/serve.go | 108 - .../src/github.com/fjl/goupnp/scpd/scpd.go | 167 - .../src/github.com/fjl/goupnp/service_client.go | 57 - .../src/github.com/fjl/goupnp/soap/soap.go | 157 - .../src/github.com/fjl/goupnp/soap/soap_test.go | 85 - .../src/github.com/fjl/goupnp/soap/types.go | 508 -- .../src/github.com/fjl/goupnp/soap/types_test.go | 481 -- .../src/github.com/fjl/goupnp/ssdp/registry.go | 202 - .../src/github.com/fjl/goupnp/ssdp/ssdp.go | 83 - .../_workspace/src/github.com/huin/goupnp/LICENSE | 23 + .../src/github.com/huin/goupnp/README.md | 14 + .../example_httpu_serving/example_httpu_serving.go | 20 + .../example_internetgateway1.go | 67 + .../dcps/internetgateway1/internetgateway1.go | 3957 +++++++++++++++ .../dcps/internetgateway2/internetgateway2.go | 5271 ++++++++++++++++++++ .../src/github.com/huin/goupnp/device.go | 184 + .../src/github.com/huin/goupnp/example/example.go | 6 + .../github.com/huin/goupnp/example/example_test.go | 62 + .../github.com/huin/goupnp/gotasks/specgen_task.go | 539 ++ .../src/github.com/huin/goupnp/goupnp.go | 109 + .../src/github.com/huin/goupnp/httpu/httpu.go | 117 + .../src/github.com/huin/goupnp/httpu/serve.go | 108 + .../src/github.com/huin/goupnp/scpd/scpd.go | 167 + .../src/github.com/huin/goupnp/service_client.go | 56 + .../src/github.com/huin/goupnp/soap/soap.go | 157 + .../src/github.com/huin/goupnp/soap/soap_test.go | 85 + .../src/github.com/huin/goupnp/soap/types.go | 508 ++ .../src/github.com/huin/goupnp/soap/types_test.go | 481 ++ .../src/github.com/huin/goupnp/ssdp/registry.go | 202 + .../src/github.com/huin/goupnp/ssdp/ssdp.go | 83 + p2p/nat/natupnp.go | 6 +- 44 files changed, 12223 insertions(+), 12224 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/README.md delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_httpu_serving/example_httpu_serving.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_internetgateway1/example_internetgateway1.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway1/internetgateway1.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway2/internetgateway2.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/device.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/example/example.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/example/example_test.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/gotasks/specgen_task.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/goupnp.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/httpu/httpu.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/httpu/serve.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/scpd/scpd.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/service_client.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap_test.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/soap/types.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/soap/types_test.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/registry.go delete mode 100644 Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/ssdp.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/LICENSE create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/README.md create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_httpu_serving/example_httpu_serving.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_internetgateway1/example_internetgateway1.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/device.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/example/example.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/example/example_test.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/httpu/serve.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/scpd/scpd.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/service_client.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/soap/soap_test.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/soap/types.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/soap/types_test.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/ssdp/registry.go create mode 100644 Godeps/_workspace/src/github.com/huin/goupnp/ssdp/ssdp.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index d91269c1d..9b7306530 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -24,15 +24,15 @@ "ImportPath": "github.com/ethereum/serpent-go", "Rev": "5767a0dbd759d313df3f404dadb7f98d7ab51443" }, - { - "ImportPath": "github.com/fjl/goupnp", - "Rev": "fa95df6feb61e136b499d01711fcd410ccaf20c1" - }, { "ImportPath": "github.com/howeyc/fsnotify", "Comment": "v0.9.0-11-g6b1ef89", "Rev": "6b1ef893dc11e0447abda6da20a5203481878dda" }, + { + "ImportPath": "github.com/huin/goupnp", + "Rev": "4191d8a85005844ea202fde52799681971b12dfe" + }, { "ImportPath": "github.com/jackpal/go-nat-pmp", "Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1" diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/LICENSE b/Godeps/_workspace/src/github.com/fjl/goupnp/LICENSE deleted file mode 100644 index 252e3d639..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2013, John Beisley -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/README.md b/Godeps/_workspace/src/github.com/fjl/goupnp/README.md deleted file mode 100644 index d464c8288..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/README.md +++ /dev/null @@ -1,14 +0,0 @@ -goupnp is a UPnP client library for Go - -Installation ------------- - -Run `go get -u github.com/fjl/goupnp`. - -Regenerating dcps generated source code: ----------------------------------------- - -1. Install gotasks: `go get -u github.com/jingweno/gotask` -2. Change to the gotasks directory: `cd gotasks` -3. Download UPnP specification data (if not done already): `wget http://upnp.org/resources/upnpresources.zip` -4. Regenerate source code: `gotask specgen -s upnpresources.zip -o ../dcps` diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_httpu_serving/example_httpu_serving.go b/Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_httpu_serving/example_httpu_serving.go deleted file mode 100644 index d56d39572..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_httpu_serving/example_httpu_serving.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "log" - "net/http" - - "github.com/fjl/goupnp/httpu" -) - -func main() { - srv := httpu.Server{ - Addr: "239.255.255.250:1900", - Multicast: true, - Handler: httpu.HandlerFunc(func(r *http.Request) { - log.Printf("Got %s %s message from %v: %v", r.Method, r.URL.Path, r.RemoteAddr, r.Header) - }), - } - err := srv.ListenAndServe() - log.Printf("Serving failed with error: %v", err) -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_internetgateway1/example_internetgateway1.go b/Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_internetgateway1/example_internetgateway1.go deleted file mode 100644 index fda612500..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/cmd/example_internetgateway1/example_internetgateway1.go +++ /dev/null @@ -1,67 +0,0 @@ -package main - -import ( - "fmt" - "log" - - "github.com/fjl/goupnp/dcps/internetgateway1" -) - -func main() { - clients, errors, err := internetgateway1.NewWANPPPConnection1Clients() - if err != nil { - log.Fatal(err) - } - - fmt.Printf("Got %d errors finding servers and %d successfully discovered.\n", - len(errors), len(clients)) - for i, e := range errors { - fmt.Printf("Error finding server #%d: %v\n", i+1, e) - } - - for _, c := range clients { - dev := &c.ServiceClient.RootDevice.Device - srv := c.ServiceClient.Service - fmt.Println(dev.FriendlyName, " :: ", srv.String()) - scpd, err := srv.RequestSCDP() - if err != nil { - fmt.Printf(" Error requesting service SCPD: %v\n", err) - } else { - fmt.Println(" Available actions:") - for _, action := range scpd.Actions { - fmt.Printf(" * %s\n", action.Name) - for _, arg := range action.Arguments { - var varDesc string - if stateVar := scpd.GetStateVariable(arg.RelatedStateVariable); stateVar != nil { - varDesc = fmt.Sprintf(" (%s)", stateVar.DataType.Name) - } - fmt.Printf(" * [%s] %s%s\n", arg.Direction, arg.Name, varDesc) - } - } - } - - if scpd == nil || scpd.GetAction("GetExternalIPAddress") != nil { - ip, err := c.GetExternalIPAddress() - fmt.Println("GetExternalIPAddress: ", ip, err) - } - - if scpd == nil || scpd.GetAction("GetStatusInfo") != nil { - status, lastErr, uptime, err := c.GetStatusInfo() - fmt.Println("GetStatusInfo: ", status, lastErr, uptime, err) - } - - if scpd == nil || scpd.GetAction("GetIdleDisconnectTime") != nil { - idleTime, err := c.GetIdleDisconnectTime() - fmt.Println("GetIdleDisconnectTime: ", idleTime, err) - } - - if scpd == nil || scpd.GetAction("AddPortMapping") != nil { - err := c.AddPortMapping("", 5000, "TCP", 5001, "192.168.1.2", true, "Test port mapping", 0) - fmt.Println("AddPortMapping: ", err) - } - if scpd == nil || scpd.GetAction("DeletePortMapping") != nil { - err := c.DeletePortMapping("", 5000, "TCP") - fmt.Println("DeletePortMapping: ", err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway1/internetgateway1.go b/Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway1/internetgateway1.go deleted file mode 100644 index 49659722c..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway1/internetgateway1.go +++ /dev/null @@ -1,3957 +0,0 @@ -// Client for UPnP Device Control Protocol Internet Gateway Device v1. -// -// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf -// -// Typically, use one of the New* functions to discover services on the local -// network. -package internetgateway1 - -// Generated file - do not edit by hand. See README.md - -import ( - "time" - - "github.com/fjl/goupnp" - "github.com/fjl/goupnp/soap" -) - -// Hack to avoid Go complaining if time isn't used. -var _ time.Time - -// Device URNs: -const ( - URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" - URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" - URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" -) - -// Service URNs: -const ( - URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1" - URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1" - URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1" - URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" - URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1" - URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1" - URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" - URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1" - URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" -) - -// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type LANHostConfigManagement1 struct { - goupnp.ServiceClient -} - -// NewLANHostConfigManagement1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil { - return - } - clients = make([]*LANHostConfigManagement1, len(genericClients)) - for i := range genericClients { - clients[i] = &LANHostConfigManagement1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewDHCPServerConfigurable: -// -// -func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) { - // Request structure. - request := &struct { - NewDHCPServerConfigurable string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDHCPServerConfigurable: -func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDHCPServerConfigurable string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDHCPRelay: -// -// -func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) { - // Request structure. - request := &struct { - NewDHCPRelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDHCPRelay: -func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDHCPRelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewSubnetMask: -// -// -func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) { - // Request structure. - request := &struct { - NewSubnetMask string - }{} - // BEGIN Marshal arguments into request. - - if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewSubnetMask: -func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewSubnetMask string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIPRouters: -// -// -func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) { - // Request structure. - request := &struct { - NewIPRouters string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIPRouters: -// -// -func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) { - // Request structure. - request := &struct { - NewIPRouters string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIPRouters: -func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIPRouters string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDomainName: -// -// -func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) { - // Request structure. - request := &struct { - NewDomainName string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDomainName: -func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDomainName string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewMinAddress: -// -// * NewMaxAddress: -// -// -func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) { - // Request structure. - request := &struct { - NewMinAddress string - - NewMaxAddress string - }{} - // BEGIN Marshal arguments into request. - - if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil { - return - } - if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewMinAddress: -// -// * NewMaxAddress: -func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewMinAddress string - - NewMaxAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil { - return - } - if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewReservedAddresses: -// -// -func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) { - // Request structure. - request := &struct { - NewReservedAddresses string - }{} - // BEGIN Marshal arguments into request. - - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewReservedAddresses: -// -// -func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) { - // Request structure. - request := &struct { - NewReservedAddresses string - }{} - // BEGIN Marshal arguments into request. - - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewReservedAddresses: -func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewReservedAddresses string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDNSServers: -// -// -func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) { - // Request structure. - request := &struct { - NewDNSServers string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDNSServers: -// -// -func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) { - // Request structure. - request := &struct { - NewDNSServers string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDNSServers: -func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDNSServers string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type Layer3Forwarding1 struct { - goupnp.ServiceClient -} - -// NewLayer3Forwarding1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil { - return - } - clients = make([]*Layer3Forwarding1, len(genericClients)) - for i := range genericClients { - clients[i] = &Layer3Forwarding1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewDefaultConnectionService: -// -// -func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) { - // Request structure. - request := &struct { - NewDefaultConnectionService string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDefaultConnectionService: -func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDefaultConnectionService string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANCableLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANCableLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil { - return - } - clients = make([]*WANCableLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANCableLinkConfig1{genericClients[i]} - } - return -} - -// -// -// Return values: -// -// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied -// -// * NewLinkType: allowed values: Ethernet -func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewCableLinkConfigState string - - NewLinkType string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil { - return - } - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDownstreamFrequency: -func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDownstreamFrequency string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDownstreamModulation: allowed values: 64QAM, 256QAM -func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDownstreamModulation string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamFrequency: -func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamFrequency string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamModulation: allowed values: QPSK, 16QAM -func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamModulation string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamChannelID: -func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamChannelID string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamPowerLevel: -func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamPowerLevel string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewBPIEncryptionEnabled: -func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewBPIEncryptionEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConfigFile: -func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConfigFile string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTFTPServer: -func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTFTPServer string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANCommonInterfaceConfig1 struct { - goupnp.ServiceClient -} - -// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil { - return - } - clients = make([]*WANCommonInterfaceConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANCommonInterfaceConfig1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewEnabledForInternet: -// -// -func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) { - // Request structure. - request := &struct { - NewEnabledForInternet string - }{} - // BEGIN Marshal arguments into request. - - if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewEnabledForInternet: -func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewEnabledForInternet string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet -// -// * NewLayer1UpstreamMaxBitRate: -// -// * NewLayer1DownstreamMaxBitRate: -// -// * NewPhysicalLinkStatus: allowed values: Up, Down -func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWANAccessType string - - NewLayer1UpstreamMaxBitRate string - - NewLayer1DownstreamMaxBitRate string - - NewPhysicalLinkStatus string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil { - return - } - if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil { - return - } - if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil { - return - } - if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWANAccessProvider: -func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWANAccessProvider string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1 -func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewMaximumActiveConnections string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalBytesSent: -func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalBytesSent string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalBytesReceived: -func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalBytesReceived string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalPacketsSent: -func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalPacketsSent string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalPacketsReceived: -func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalPacketsReceived string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewActiveConnectionIndex: -// -// Return values: -// -// * NewActiveConnDeviceContainer: -// -// * NewActiveConnectionServiceID: -func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { - // Request structure. - request := &struct { - NewActiveConnectionIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewActiveConnDeviceContainer string - - NewActiveConnectionServiceID string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil { - return - } - if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANDSLLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANDSLLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil { - return - } - clients = make([]*WANDSLLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANDSLLinkConfig1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewLinkType: -// -// -func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) { - // Request structure. - request := &struct { - NewLinkType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewLinkType: -// -// * NewLinkStatus: allowed values: Up, Down -func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewLinkType string - - NewLinkStatus string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { - return - } - if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoConfig: -func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoConfig string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewModulationType: -func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewModulationType string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDestinationAddress: -// -// -func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) { - // Request structure. - request := &struct { - NewDestinationAddress string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDestinationAddress: -func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDestinationAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewATMEncapsulation: -// -// -func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) { - // Request structure. - request := &struct { - NewATMEncapsulation string - }{} - // BEGIN Marshal arguments into request. - - if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewATMEncapsulation: -func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewATMEncapsulation string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewFCSPreserved: -// -// -func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) { - // Request structure. - request := &struct { - NewFCSPreserved string - }{} - // BEGIN Marshal arguments into request. - - if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewFCSPreserved: -func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewFCSPreserved string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANEthernetLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil { - return - } - clients = make([]*WANEthernetLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANEthernetLinkConfig1{genericClients[i]} - } - return -} - -// -// -// Return values: -// -// * NewEthernetLinkStatus: allowed values: Up, Down -func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewEthernetLinkStatus string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANIPConnection1 struct { - goupnp.ServiceClient -} - -// NewWANIPConnection1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil { - return - } - clients = make([]*WANIPConnection1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANIPConnection1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewConnectionType: -// -// -func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionType: -// -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged -func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection1) RequestConnection() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection1) RequestTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection1) ForceTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewAutoDisconnectTime: -// -// -func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIdleDisconnectTime: -// -// -func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewWarnDisconnectDelay: -// -// -func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -// -// * NewUptime: -func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - - NewLastConnectionError string - - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoDisconnectTime: -func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIdleDisconnectTime: -func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWarnDisconnectDelay: -func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewRSIPAvailable: -// -// * NewNATEnabled: -func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewPortMappingIndex: -// -// Return values: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// Return values: -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -// -// -func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// -func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewExternalIPAddress: -func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANPOTSLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil { - return - } - clients = make([]*WANPOTSLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANPOTSLinkConfig1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewISPPhoneNumber: -// -// * NewISPInfo: -// -// * NewLinkType: allowed values: PPP_Dialup -// -// -func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) { - // Request structure. - request := &struct { - NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil { - return - } - if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil { - return - } - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewNumberOfRetries: -// -// * NewDelayBetweenRetries: -// -// -func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { - // Request structure. - request := &struct { - NewNumberOfRetries string - - NewDelayBetweenRetries string - }{} - // BEGIN Marshal arguments into request. - - if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil { - return - } - if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewISPPhoneNumber: -// -// * NewISPInfo: -// -// * NewLinkType: allowed values: PPP_Dialup -func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil { - return - } - if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil { - return - } - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewNumberOfRetries: -// -// * NewDelayBetweenRetries: -func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewNumberOfRetries string - - NewDelayBetweenRetries string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil { - return - } - if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewFclass: -func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewFclass string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDataModulationSupported: -func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDataModulationSupported string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDataProtocol: -func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDataProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDataCompression: -func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDataCompression string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPlusVTRCommandSupported: -func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPlusVTRCommandSupported string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANPPPConnection1 struct { - goupnp.ServiceClient -} - -// NewWANPPPConnection1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil { - return - } - clients = make([]*WANPPPConnection1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANPPPConnection1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewConnectionType: -// -// -func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionType: -// -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay -func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewUserName: -// -// * NewPassword: -// -// -func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) { - // Request structure. - request := &struct { - NewUserName string - - NewPassword string - }{} - // BEGIN Marshal arguments into request. - - if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { - return - } - if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANPPPConnection1) RequestConnection() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANPPPConnection1) RequestTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANPPPConnection1) ForceTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewAutoDisconnectTime: -// -// -func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIdleDisconnectTime: -// -// -func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewWarnDisconnectDelay: -// -// -func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -// -// * NewUptime: -func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - - NewLastConnectionError string - - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamMaxBitRate: -// -// * NewDownstreamMaxBitRate: -func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamMaxBitRate string - - NewDownstreamMaxBitRate string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { - return - } - if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPPPEncryptionProtocol: -func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPEncryptionProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPPPCompressionProtocol: -func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPCompressionProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPPPAuthenticationProtocol: -func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPAuthenticationProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUserName: -func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUserName string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPassword: -func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPassword string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoDisconnectTime: -func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIdleDisconnectTime: -func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWarnDisconnectDelay: -func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewRSIPAvailable: -// -// * NewNATEnabled: -func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewPortMappingIndex: -// -// Return values: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// Return values: -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -// -// -func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// -func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewExternalIPAddress: -func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway2/internetgateway2.go b/Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway2/internetgateway2.go deleted file mode 100644 index cf34c61f0..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/dcps/internetgateway2/internetgateway2.go +++ /dev/null @@ -1,5271 +0,0 @@ -// Client for UPnP Device Control Protocol Internet Gateway Device v2. -// -// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf -// -// Typically, use one of the New* functions to discover services on the local -// network. -package internetgateway2 - -// Generated file - do not edit by hand. See README.md - -import ( - "time" - - "github.com/fjl/goupnp" - "github.com/fjl/goupnp/soap" -) - -// Hack to avoid Go complaining if time isn't used. -var _ time.Time - -// Device URNs: -const ( - URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" - URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" - URN_WANConnectionDevice_2 = "urn:schemas-upnp-org:device:WANConnectionDevice:2" - URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" - URN_WANDevice_2 = "urn:schemas-upnp-org:device:WANDevice:2" -) - -// Service URNs: -const ( - URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1" - URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1" - URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1" - URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" - URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1" - URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1" - URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" - URN_WANIPConnection_2 = "urn:schemas-upnp-org:service:WANIPConnection:2" - URN_WANIPv6FirewallControl_1 = "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" - URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1" - URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" -) - -// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type LANHostConfigManagement1 struct { - goupnp.ServiceClient -} - -// NewLANHostConfigManagement1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil { - return - } - clients = make([]*LANHostConfigManagement1, len(genericClients)) - for i := range genericClients { - clients[i] = &LANHostConfigManagement1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewDHCPServerConfigurable: -// -// -func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) { - // Request structure. - request := &struct { - NewDHCPServerConfigurable string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDHCPServerConfigurable: -func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDHCPServerConfigurable string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDHCPRelay: -// -// -func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) { - // Request structure. - request := &struct { - NewDHCPRelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDHCPRelay: -func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDHCPRelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewSubnetMask: -// -// -func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) { - // Request structure. - request := &struct { - NewSubnetMask string - }{} - // BEGIN Marshal arguments into request. - - if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewSubnetMask: -func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewSubnetMask string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIPRouters: -// -// -func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) { - // Request structure. - request := &struct { - NewIPRouters string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIPRouters: -// -// -func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) { - // Request structure. - request := &struct { - NewIPRouters string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIPRouters: -func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIPRouters string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDomainName: -// -// -func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) { - // Request structure. - request := &struct { - NewDomainName string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDomainName: -func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDomainName string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewMinAddress: -// -// * NewMaxAddress: -// -// -func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) { - // Request structure. - request := &struct { - NewMinAddress string - - NewMaxAddress string - }{} - // BEGIN Marshal arguments into request. - - if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil { - return - } - if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewMinAddress: -// -// * NewMaxAddress: -func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewMinAddress string - - NewMaxAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil { - return - } - if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewReservedAddresses: -// -// -func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) { - // Request structure. - request := &struct { - NewReservedAddresses string - }{} - // BEGIN Marshal arguments into request. - - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewReservedAddresses: -// -// -func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) { - // Request structure. - request := &struct { - NewReservedAddresses string - }{} - // BEGIN Marshal arguments into request. - - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewReservedAddresses: -func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewReservedAddresses string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDNSServers: -// -// -func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) { - // Request structure. - request := &struct { - NewDNSServers string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDNSServers: -// -// -func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) { - // Request structure. - request := &struct { - NewDNSServers string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDNSServers: -func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDNSServers string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type Layer3Forwarding1 struct { - goupnp.ServiceClient -} - -// NewLayer3Forwarding1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil { - return - } - clients = make([]*Layer3Forwarding1, len(genericClients)) - for i := range genericClients { - clients[i] = &Layer3Forwarding1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewDefaultConnectionService: -// -// -func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) { - // Request structure. - request := &struct { - NewDefaultConnectionService string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDefaultConnectionService: -func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDefaultConnectionService string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANCableLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANCableLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil { - return - } - clients = make([]*WANCableLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANCableLinkConfig1{genericClients[i]} - } - return -} - -// -// -// Return values: -// -// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied -// -// * NewLinkType: allowed values: Ethernet -func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewCableLinkConfigState string - - NewLinkType string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil { - return - } - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDownstreamFrequency: -func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDownstreamFrequency string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDownstreamModulation: allowed values: 64QAM, 256QAM -func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDownstreamModulation string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamFrequency: -func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamFrequency string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamModulation: allowed values: QPSK, 16QAM -func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamModulation string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamChannelID: -func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamChannelID string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamPowerLevel: -func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamPowerLevel string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewBPIEncryptionEnabled: -func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewBPIEncryptionEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConfigFile: -func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConfigFile string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTFTPServer: -func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTFTPServer string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANCommonInterfaceConfig1 struct { - goupnp.ServiceClient -} - -// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil { - return - } - clients = make([]*WANCommonInterfaceConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANCommonInterfaceConfig1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewEnabledForInternet: -// -// -func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) { - // Request structure. - request := &struct { - NewEnabledForInternet string - }{} - // BEGIN Marshal arguments into request. - - if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewEnabledForInternet: -func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewEnabledForInternet string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet -// -// * NewLayer1UpstreamMaxBitRate: -// -// * NewLayer1DownstreamMaxBitRate: -// -// * NewPhysicalLinkStatus: allowed values: Up, Down -func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWANAccessType string - - NewLayer1UpstreamMaxBitRate string - - NewLayer1DownstreamMaxBitRate string - - NewPhysicalLinkStatus string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil { - return - } - if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil { - return - } - if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil { - return - } - if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWANAccessProvider: -func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWANAccessProvider string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1 -func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewMaximumActiveConnections string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalBytesSent: -func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalBytesSent string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalBytesReceived: -func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalBytesReceived string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalPacketsSent: -func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalPacketsSent string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewTotalPacketsReceived: -func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewTotalPacketsReceived string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewActiveConnectionIndex: -// -// Return values: -// -// * NewActiveConnDeviceContainer: -// -// * NewActiveConnectionServiceID: -func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { - // Request structure. - request := &struct { - NewActiveConnectionIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewActiveConnDeviceContainer string - - NewActiveConnectionServiceID string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil { - return - } - if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANDSLLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANDSLLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil { - return - } - clients = make([]*WANDSLLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANDSLLinkConfig1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewLinkType: -// -// -func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) { - // Request structure. - request := &struct { - NewLinkType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewLinkType: -// -// * NewLinkStatus: allowed values: Up, Down -func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewLinkType string - - NewLinkStatus string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { - return - } - if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoConfig: -func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoConfig string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewModulationType: -func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewModulationType string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewDestinationAddress: -// -// -func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) { - // Request structure. - request := &struct { - NewDestinationAddress string - }{} - // BEGIN Marshal arguments into request. - - if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDestinationAddress: -func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDestinationAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewATMEncapsulation: -// -// -func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) { - // Request structure. - request := &struct { - NewATMEncapsulation string - }{} - // BEGIN Marshal arguments into request. - - if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewATMEncapsulation: -func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewATMEncapsulation string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewFCSPreserved: -// -// -func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) { - // Request structure. - request := &struct { - NewFCSPreserved string - }{} - // BEGIN Marshal arguments into request. - - if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewFCSPreserved: -func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewFCSPreserved string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANEthernetLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil { - return - } - clients = make([]*WANEthernetLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANEthernetLinkConfig1{genericClients[i]} - } - return -} - -// -// -// Return values: -// -// * NewEthernetLinkStatus: allowed values: Up, Down -func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewEthernetLinkStatus string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANIPConnection1 struct { - goupnp.ServiceClient -} - -// NewWANIPConnection1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil { - return - } - clients = make([]*WANIPConnection1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANIPConnection1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewConnectionType: -// -// -func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionType: -// -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged -func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection1) RequestConnection() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection1) RequestTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection1) ForceTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewAutoDisconnectTime: -// -// -func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIdleDisconnectTime: -// -// -func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewWarnDisconnectDelay: -// -// -func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -// -// * NewUptime: -func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - - NewLastConnectionError string - - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoDisconnectTime: -func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIdleDisconnectTime: -func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWarnDisconnectDelay: -func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewRSIPAvailable: -// -// * NewNATEnabled: -func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewPortMappingIndex: -// -// Return values: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// Return values: -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -// -// -func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// -func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewExternalIPAddress: -func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANIPConnection2 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:2". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANIPConnection2 struct { - goupnp.ServiceClient -} - -// NewWANIPConnection2Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_2); err != nil { - return - } - clients = make([]*WANIPConnection2, len(genericClients)) - for i := range genericClients { - clients[i] = &WANIPConnection2{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged -// -// -func (client *WANIPConnection2) SetConnectionType(NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged -// -// * NewPossibleConnectionTypes: -func (client *WANIPConnection2) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection2) RequestConnection() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection2) RequestTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANIPConnection2) ForceTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewAutoDisconnectTime: -// -// -func (client *WANIPConnection2) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIdleDisconnectTime: -// -// -func (client *WANIPConnection2) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewWarnDisconnectDelay: -// -// -func (client *WANIPConnection2) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -// -// * NewUptime: -func (client *WANIPConnection2) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - - NewLastConnectionError string - - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoDisconnectTime: -func (client *WANIPConnection2) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIdleDisconnectTime: -func (client *WANIPConnection2) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWarnDisconnectDelay: -func (client *WANIPConnection2) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewRSIPAvailable: -// -// * NewNATEnabled: -func (client *WANIPConnection2) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewPortMappingIndex: -// -// Return values: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: allowed value range: minimum=1, maximum=65535 -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 -func (client *WANIPConnection2) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// Return values: -// -// * NewInternalPort: allowed value range: minimum=1, maximum=65535 -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 -func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: allowed value range: minimum=1, maximum=65535 -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 -// -// -func (client *WANIPConnection2) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// -func (client *WANIPConnection2) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewStartPort: -// -// * NewEndPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewManage: -// -// -func (client *WANIPConnection2) DeletePortMappingRange(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool) (err error) { - // Request structure. - request := &struct { - NewStartPort string - - NewEndPort string - - NewProtocol string - - NewManage string - }{} - // BEGIN Marshal arguments into request. - - if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { - return - } - if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "DeletePortMappingRange", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewExternalIPAddress: -func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewStartPort: -// -// * NewEndPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewManage: -// -// * NewNumberOfPorts: -// -// Return values: -// -// * NewPortListing: -func (client *WANIPConnection2) GetListOfPortMappings(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool, NewNumberOfPorts uint16) (NewPortListing string, err error) { - // Request structure. - request := &struct { - NewStartPort string - - NewEndPort string - - NewProtocol string - - NewManage string - - NewNumberOfPorts string - }{} - // BEGIN Marshal arguments into request. - - if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { - return - } - if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { - return - } - if request.NewNumberOfPorts, err = soap.MarshalUi2(NewNumberOfPorts); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPortListing string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetListOfPortMappings", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPortListing, err = soap.UnmarshalString(response.NewPortListing); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: allowed value range: minimum=1, maximum=65535 -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 -// -// Return values: -// -// * NewReservedPort: -func (client *WANIPConnection2) AddAnyPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (NewReservedPort uint16, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewReservedPort string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "AddAnyPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewReservedPort, err = soap.UnmarshalUi2(response.NewReservedPort); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANIPv6FirewallControl1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANIPv6FirewallControl1 struct { - goupnp.ServiceClient -} - -// NewWANIPv6FirewallControl1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPv6FirewallControl_1); err != nil { - return - } - clients = make([]*WANIPv6FirewallControl1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANIPv6FirewallControl1{genericClients[i]} - } - return -} - -// -// -// Return values: -// -// * FirewallEnabled: -// -// * InboundPinholeAllowed: -func (client *WANIPv6FirewallControl1) GetFirewallStatus() (FirewallEnabled bool, InboundPinholeAllowed bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - FirewallEnabled string - - InboundPinholeAllowed string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetFirewallStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if FirewallEnabled, err = soap.UnmarshalBoolean(response.FirewallEnabled); err != nil { - return - } - if InboundPinholeAllowed, err = soap.UnmarshalBoolean(response.InboundPinholeAllowed); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * RemoteHost: -// -// * RemotePort: -// -// * InternalClient: -// -// * InternalPort: -// -// * Protocol: -// -// Return values: -// -// * OutboundPinholeTimeout: -func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeout(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16) (OutboundPinholeTimeout uint32, err error) { - // Request structure. - request := &struct { - RemoteHost string - - RemotePort string - - InternalClient string - - InternalPort string - - Protocol string - }{} - // BEGIN Marshal arguments into request. - - if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil { - return - } - if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil { - return - } - if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil { - return - } - if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil { - return - } - if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - OutboundPinholeTimeout string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetOutboundPinholeTimeout", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if OutboundPinholeTimeout, err = soap.UnmarshalUi4(response.OutboundPinholeTimeout); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * RemoteHost: -// -// * RemotePort: -// -// * InternalClient: -// -// * InternalPort: -// -// * Protocol: -// -// * LeaseTime: allowed value range: minimum=1, maximum=86400 -// -// Return values: -// -// * UniqueID: -func (client *WANIPv6FirewallControl1) AddPinhole(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16, LeaseTime uint32) (UniqueID uint16, err error) { - // Request structure. - request := &struct { - RemoteHost string - - RemotePort string - - InternalClient string - - InternalPort string - - Protocol string - - LeaseTime string - }{} - // BEGIN Marshal arguments into request. - - if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil { - return - } - if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil { - return - } - if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil { - return - } - if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil { - return - } - if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil { - return - } - if request.LeaseTime, err = soap.MarshalUi4(LeaseTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - UniqueID string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "AddPinhole", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if UniqueID, err = soap.UnmarshalUi2(response.UniqueID); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * UniqueID: -// -// * NewLeaseTime: allowed value range: minimum=1, maximum=86400 -// -// -func (client *WANIPv6FirewallControl1) UpdatePinhole(UniqueID uint16, NewLeaseTime uint32) (err error) { - // Request structure. - request := &struct { - UniqueID string - - NewLeaseTime string - }{} - // BEGIN Marshal arguments into request. - - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { - return - } - if request.NewLeaseTime, err = soap.MarshalUi4(NewLeaseTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "UpdatePinhole", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * UniqueID: -// -// -func (client *WANIPv6FirewallControl1) DeletePinhole(UniqueID uint16) (err error) { - // Request structure. - request := &struct { - UniqueID string - }{} - // BEGIN Marshal arguments into request. - - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "DeletePinhole", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * UniqueID: -// -// Return values: -// -// * PinholePackets: -func (client *WANIPv6FirewallControl1) GetPinholePackets(UniqueID uint16) (PinholePackets uint32, err error) { - // Request structure. - request := &struct { - UniqueID string - }{} - // BEGIN Marshal arguments into request. - - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - PinholePackets string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetPinholePackets", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if PinholePackets, err = soap.UnmarshalUi4(response.PinholePackets); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * UniqueID: -// -// Return values: -// -// * IsWorking: -func (client *WANIPv6FirewallControl1) CheckPinholeWorking(UniqueID uint16) (IsWorking bool, err error) { - // Request structure. - request := &struct { - UniqueID string - }{} - // BEGIN Marshal arguments into request. - - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - IsWorking string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "CheckPinholeWorking", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if IsWorking, err = soap.UnmarshalBoolean(response.IsWorking); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANPOTSLinkConfig1 struct { - goupnp.ServiceClient -} - -// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil { - return - } - clients = make([]*WANPOTSLinkConfig1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANPOTSLinkConfig1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewISPPhoneNumber: -// -// * NewISPInfo: -// -// * NewLinkType: allowed values: PPP_Dialup -// -// -func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) { - // Request structure. - request := &struct { - NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil { - return - } - if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil { - return - } - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewNumberOfRetries: -// -// * NewDelayBetweenRetries: -// -// -func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { - // Request structure. - request := &struct { - NewNumberOfRetries string - - NewDelayBetweenRetries string - }{} - // BEGIN Marshal arguments into request. - - if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil { - return - } - if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewISPPhoneNumber: -// -// * NewISPInfo: -// -// * NewLinkType: allowed values: PPP_Dialup -func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil { - return - } - if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil { - return - } - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewNumberOfRetries: -// -// * NewDelayBetweenRetries: -func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewNumberOfRetries string - - NewDelayBetweenRetries string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil { - return - } - if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewFclass: -func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewFclass string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDataModulationSupported: -func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDataModulationSupported string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDataProtocol: -func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDataProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewDataCompression: -func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewDataCompression string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPlusVTRCommandSupported: -func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPlusVTRCommandSupported string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANPPPConnection1 struct { - goupnp.ServiceClient -} - -// NewWANPPPConnection1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil { - return - } - clients = make([]*WANPPPConnection1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANPPPConnection1{genericClients[i]} - } - return -} - -// Arguments: -// -// * NewConnectionType: -// -// -func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionType: -// -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay -func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewUserName: -// -// * NewPassword: -// -// -func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) { - // Request structure. - request := &struct { - NewUserName string - - NewPassword string - }{} - // BEGIN Marshal arguments into request. - - if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { - return - } - if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANPPPConnection1) RequestConnection() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANPPPConnection1) RequestTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// -func (client *WANPPPConnection1) ForceTermination() (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewAutoDisconnectTime: -// -// -func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewIdleDisconnectTime: -// -// -func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewWarnDisconnectDelay: -// -// -func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -// -// * NewUptime: -func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - - NewLastConnectionError string - - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUpstreamMaxBitRate: -// -// * NewDownstreamMaxBitRate: -func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamMaxBitRate string - - NewDownstreamMaxBitRate string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { - return - } - if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPPPEncryptionProtocol: -func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPEncryptionProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPPPCompressionProtocol: -func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPCompressionProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPPPAuthenticationProtocol: -func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPAuthenticationProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewUserName: -func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUserName string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewPassword: -func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPassword string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewAutoDisconnectTime: -func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewIdleDisconnectTime: -func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewWarnDisconnectDelay: -func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewRSIPAvailable: -// -// * NewNATEnabled: -func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewPortMappingIndex: -// -// Return values: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// Return values: -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// * NewInternalPort: -// -// * NewInternalClient: -// -// * NewEnabled: -// -// * NewPortMappingDescription: -// -// * NewLeaseDuration: -// -// -func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - - NewPortMappingDescription string - - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// Arguments: -// -// * NewRemoteHost: -// -// * NewExternalPort: -// -// * NewProtocol: allowed values: TCP, UDP -// -// -func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// -// Return values: -// -// * NewExternalIPAddress: -func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/device.go b/Godeps/_workspace/src/github.com/fjl/goupnp/device.go deleted file mode 100644 index 2b8e9bb07..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/device.go +++ /dev/null @@ -1,184 +0,0 @@ -// This file contains XML structures for communicating with UPnP devices. - -package goupnp - -import ( - "encoding/xml" - "errors" - "fmt" - "net/url" - - "github.com/fjl/goupnp/scpd" - "github.com/fjl/goupnp/soap" -) - -const ( - DeviceXMLNamespace = "urn:schemas-upnp-org:device-1-0" -) - -// RootDevice is the device description as described by section 2.3 "Device -// description" in -// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf -type RootDevice struct { - XMLName xml.Name `xml:"root"` - SpecVersion SpecVersion `xml:"specVersion"` - URLBase url.URL `xml:"-"` - URLBaseStr string `xml:"URLBase"` - Device Device `xml:"device"` -} - -// SetURLBase sets the URLBase for the RootDevice and its underlying components. -func (root *RootDevice) SetURLBase(urlBase *url.URL) { - root.URLBase = *urlBase - root.URLBaseStr = urlBase.String() - root.Device.SetURLBase(urlBase) -} - -// SpecVersion is part of a RootDevice, describes the version of the -// specification that the data adheres to. -type SpecVersion struct { - Major int32 `xml:"major"` - Minor int32 `xml:"minor"` -} - -// Device is a UPnP device. It can have child devices. -type Device struct { - DeviceType string `xml:"deviceType"` - FriendlyName string `xml:"friendlyName"` - Manufacturer string `xml:"manufacturer"` - ManufacturerURL URLField `xml:"manufacturerURL"` - ModelDescription string `xml:"modelDescription"` - ModelName string `xml:"modelName"` - ModelNumber string `xml:"modelNumber"` - ModelURL URLField `xml:"modelURL"` - SerialNumber string `xml:"serialNumber"` - UDN string `xml:"UDN"` - UPC string `xml:"UPC,omitempty"` - Icons []Icon `xml:"iconList>icon,omitempty"` - Services []Service `xml:"serviceList>service,omitempty"` - Devices []Device `xml:"deviceList>device,omitempty"` - - // Extra observed elements: - PresentationURL URLField `xml:"presentationURL"` -} - -// VisitDevices calls visitor for the device, and all its descendent devices. -func (device *Device) VisitDevices(visitor func(*Device)) { - visitor(device) - for i := range device.Devices { - device.Devices[i].VisitDevices(visitor) - } -} - -// VisitServices calls visitor for all Services under the device and all its -// descendent devices. -func (device *Device) VisitServices(visitor func(*Service)) { - device.VisitDevices(func(d *Device) { - for i := range d.Services { - visitor(&d.Services[i]) - } - }) -} - -// FindService finds all (if any) Services under the device and its descendents -// that have the given ServiceType. -func (device *Device) FindService(serviceType string) []*Service { - var services []*Service - device.VisitServices(func(s *Service) { - if s.ServiceType == serviceType { - services = append(services, s) - } - }) - return services -} - -// SetURLBase sets the URLBase for the Device and its underlying components. -func (device *Device) SetURLBase(urlBase *url.URL) { - device.ManufacturerURL.SetURLBase(urlBase) - device.ModelURL.SetURLBase(urlBase) - device.PresentationURL.SetURLBase(urlBase) - for i := range device.Icons { - device.Icons[i].SetURLBase(urlBase) - } - for i := range device.Services { - device.Services[i].SetURLBase(urlBase) - } - for i := range device.Devices { - device.Devices[i].SetURLBase(urlBase) - } -} - -func (device *Device) String() string { - return fmt.Sprintf("Device ID %s : %s (%s)", device.UDN, device.DeviceType, device.FriendlyName) -} - -// Icon is a representative image that a device might include in its -// description. -type Icon struct { - Mimetype string `xml:"mimetype"` - Width int32 `xml:"width"` - Height int32 `xml:"height"` - Depth int32 `xml:"depth"` - URL URLField `xml:"url"` -} - -// SetURLBase sets the URLBase for the Icon. -func (icon *Icon) SetURLBase(url *url.URL) { - icon.URL.SetURLBase(url) -} - -// Service is a service provided by a UPnP Device. -type Service struct { - ServiceType string `xml:"serviceType"` - ServiceId string `xml:"serviceId"` - SCPDURL URLField `xml:"SCPDURL"` - ControlURL URLField `xml:"controlURL"` - EventSubURL URLField `xml:"eventSubURL"` -} - -// SetURLBase sets the URLBase for the Service. -func (srv *Service) SetURLBase(urlBase *url.URL) { - srv.SCPDURL.SetURLBase(urlBase) - srv.ControlURL.SetURLBase(urlBase) - srv.EventSubURL.SetURLBase(urlBase) -} - -func (srv *Service) String() string { - return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType) -} - -// RequestSCDP requests the SCPD (soap actions and state variables description) -// for the service. -func (srv *Service) RequestSCDP() (*scpd.SCPD, error) { - if !srv.SCPDURL.Ok { - return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set") - } - s := new(scpd.SCPD) - if err := requestXml(srv.SCPDURL.URL.String(), scpd.SCPDXMLNamespace, s); err != nil { - return nil, err - } - return s, nil -} - -func (srv *Service) NewSOAPClient() *soap.SOAPClient { - return soap.NewSOAPClient(srv.ControlURL.URL) -} - -// URLField is a URL that is part of a device description. -type URLField struct { - URL url.URL `xml:"-"` - Ok bool `xml:"-"` - Str string `xml:",chardata"` -} - -func (uf *URLField) SetURLBase(urlBase *url.URL) { - refUrl, err := url.Parse(uf.Str) - if err != nil { - uf.URL = url.URL{} - uf.Ok = false - return - } - - uf.URL = *urlBase.ResolveReference(refUrl) - uf.Ok = true -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/example/example.go b/Godeps/_workspace/src/github.com/fjl/goupnp/example/example.go deleted file mode 100644 index aae4c28f4..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/example/example.go +++ /dev/null @@ -1,6 +0,0 @@ -// Serves as examples of using the goupnp library. -// -// To run examples and see the output for your local network, run the following -// command (specifically including the -v flag): -// go test -v github.com/fjl/goupnp/example -package example diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/example/example_test.go b/Godeps/_workspace/src/github.com/fjl/goupnp/example/example_test.go deleted file mode 100644 index d926a06b0..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/example/example_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package example_test - -import ( - "fmt" - "os" - - "github.com/fjl/goupnp" - "github.com/fjl/goupnp/dcps/internetgateway1" -) - -// Use discovered WANPPPConnection1 services to find external IP addresses. -func Example_WANPPPConnection1_GetExternalIPAddress() { - clients, errors, err := internetgateway1.NewWANPPPConnection1Clients() - extIPClients := make([]GetExternalIPAddresser, len(clients)) - for i, client := range clients { - extIPClients[i] = client - } - DisplayExternalIPResults(extIPClients, errors, err) - // Output: -} - -// Use discovered WANIPConnection services to find external IP addresses. -func Example_WANIPConnection_GetExternalIPAddress() { - clients, errors, err := internetgateway1.NewWANIPConnection1Clients() - extIPClients := make([]GetExternalIPAddresser, len(clients)) - for i, client := range clients { - extIPClients[i] = client - } - DisplayExternalIPResults(extIPClients, errors, err) - // Output: -} - -type GetExternalIPAddresser interface { - GetExternalIPAddress() (NewExternalIPAddress string, err error) - GetServiceClient() *goupnp.ServiceClient -} - -func DisplayExternalIPResults(clients []GetExternalIPAddresser, errors []error, err error) { - if err != nil { - fmt.Fprintln(os.Stderr, "Error discovering service with UPnP: ", err) - return - } - - if len(errors) > 0 { - fmt.Fprintf(os.Stderr, "Error discovering %d services:\n", len(errors)) - for _, err := range errors { - fmt.Println(" ", err) - } - } - - fmt.Fprintf(os.Stderr, "Successfully discovered %d services:\n", len(clients)) - for _, client := range clients { - device := &client.GetServiceClient().RootDevice.Device - - fmt.Fprintln(os.Stderr, " Device:", device.FriendlyName) - if addr, err := client.GetExternalIPAddress(); err != nil { - fmt.Fprintf(os.Stderr, " Failed to get external IP address: %v\n", err) - } else { - fmt.Fprintf(os.Stderr, " External IP address: %v\n", addr) - } - } -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/gotasks/specgen_task.go b/Godeps/_workspace/src/github.com/fjl/goupnp/gotasks/specgen_task.go deleted file mode 100644 index 006e8fef3..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/gotasks/specgen_task.go +++ /dev/null @@ -1,539 +0,0 @@ -// +build gotask - -package gotasks - -import ( - "archive/zip" - "bytes" - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "path" - "path/filepath" - "regexp" - "strings" - "text/template" - - "github.com/fjl/goupnp" - "github.com/fjl/goupnp/scpd" - "github.com/huin/goutil/codegen" - "github.com/jingweno/gotask/tasking" -) - -var ( - deviceURNPrefix = "urn:schemas-upnp-org:device:" - serviceURNPrefix = "urn:schemas-upnp-org:service:" -) - -// NAME -// specgen - generates Go code from the UPnP specification files. -// -// DESCRIPTION -// The specification is available for download from: -// -// OPTIONS -// -s, --spec_filename= -// Path to the specification file, available from http://upnp.org/resources/upnpresources.zip -// -o, --out_dir= -// Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/fjl/goupnp/dcps -// --nogofmt -// Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt. -func TaskSpecgen(t *tasking.T) { - specFilename := t.Flags.String("spec-filename") - if specFilename == "" { - specFilename = t.Flags.String("s") - } - if specFilename == "" { - t.Fatal("--spec_filename is required") - } - outDir := t.Flags.String("out-dir") - if outDir == "" { - outDir = t.Flags.String("o") - } - if outDir == "" { - log.Fatal("--out_dir is required") - } - useGofmt := !t.Flags.Bool("nogofmt") - - specArchive, err := openZipfile(specFilename) - if err != nil { - t.Fatalf("Error opening spec file: %v", err) - } - defer specArchive.Close() - - dcpCol := newDcpsCollection() - for _, f := range globFiles("standardizeddcps/*/*.zip", specArchive.Reader) { - dirName := strings.TrimPrefix(f.Name, "standardizeddcps/") - slashIndex := strings.Index(dirName, "/") - if slashIndex == -1 { - // Should not happen. - t.Logf("Could not find / in %q", dirName) - return - } - dirName = dirName[:slashIndex] - - dcp := dcpCol.dcpForDir(dirName) - if dcp == nil { - t.Logf("No alias defined for directory %q: skipping %s\n", dirName, f.Name) - continue - } else { - t.Logf("Alias found for directory %q: processing %s\n", dirName, f.Name) - } - - dcp.processZipFile(f) - } - - for _, dcp := range dcpCol.dcpByAlias { - if err := dcp.writePackage(outDir, useGofmt); err != nil { - log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err) - } - } -} - -// DCP contains extra metadata to use when generating DCP source files. -type DCPMetadata struct { - Name string // What to name the Go DCP package. - OfficialName string // Official name for the DCP. - DocURL string // Optional - URL for futher documentation about the DCP. -} - -var dcpMetadataByDir = map[string]DCPMetadata{ - "Internet Gateway_1": { - Name: "internetgateway1", - OfficialName: "Internet Gateway Device v1", - DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf", - }, - "Internet Gateway_2": { - Name: "internetgateway2", - OfficialName: "Internet Gateway Device v2", - DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf", - }, -} - -type dcpCollection struct { - dcpByAlias map[string]*DCP -} - -func newDcpsCollection() *dcpCollection { - c := &dcpCollection{ - dcpByAlias: make(map[string]*DCP), - } - for _, metadata := range dcpMetadataByDir { - c.dcpByAlias[metadata.Name] = newDCP(metadata) - } - return c -} - -func (c *dcpCollection) dcpForDir(dirName string) *DCP { - metadata, ok := dcpMetadataByDir[dirName] - if !ok { - return nil - } - return c.dcpByAlias[metadata.Name] -} - -// DCP collects together information about a UPnP Device Control Protocol. -type DCP struct { - Metadata DCPMetadata - DeviceTypes map[string]*URNParts - ServiceTypes map[string]*URNParts - Services []SCPDWithURN -} - -func newDCP(metadata DCPMetadata) *DCP { - return &DCP{ - Metadata: metadata, - DeviceTypes: make(map[string]*URNParts), - ServiceTypes: make(map[string]*URNParts), - } -} - -func (dcp *DCP) processZipFile(file *zip.File) { - archive, err := openChildZip(file) - if err != nil { - log.Println("Error reading child zip file:", err) - return - } - for _, deviceFile := range globFiles("*/device/*.xml", archive) { - dcp.processDeviceFile(deviceFile) - } - for _, scpdFile := range globFiles("*/service/*.xml", archive) { - dcp.processSCPDFile(scpdFile) - } -} - -func (dcp *DCP) processDeviceFile(file *zip.File) { - var device goupnp.Device - if err := unmarshalXmlFile(file, &device); err != nil { - log.Printf("Error decoding device XML from file %q: %v", file.Name, err) - return - } - device.VisitDevices(func(d *goupnp.Device) { - t := strings.TrimSpace(d.DeviceType) - if t != "" { - u, err := extractURNParts(t, deviceURNPrefix) - if err != nil { - log.Println(err) - return - } - dcp.DeviceTypes[t] = u - } - }) - device.VisitServices(func(s *goupnp.Service) { - u, err := extractURNParts(s.ServiceType, serviceURNPrefix) - if err != nil { - log.Println(err) - return - } - dcp.ServiceTypes[s.ServiceType] = u - }) -} - -func (dcp *DCP) writePackage(outDir string, useGofmt bool) error { - packageDirname := filepath.Join(outDir, dcp.Metadata.Name) - err := os.MkdirAll(packageDirname, os.ModePerm) - if err != nil && !os.IsExist(err) { - return err - } - packageFilename := filepath.Join(packageDirname, dcp.Metadata.Name+".go") - packageFile, err := os.Create(packageFilename) - if err != nil { - return err - } - var output io.WriteCloser = packageFile - if useGofmt { - if output, err = codegen.NewGofmtWriteCloser(output); err != nil { - packageFile.Close() - return err - } - } - if err = packageTmpl.Execute(output, dcp); err != nil { - output.Close() - return err - } - return output.Close() -} - -func (dcp *DCP) processSCPDFile(file *zip.File) { - scpd := new(scpd.SCPD) - if err := unmarshalXmlFile(file, scpd); err != nil { - log.Printf("Error decoding SCPD XML from file %q: %v", file.Name, err) - return - } - scpd.Clean() - urnParts, err := urnPartsFromSCPDFilename(file.Name) - if err != nil { - log.Printf("Could not recognize SCPD filename %q: %v", file.Name, err) - return - } - dcp.Services = append(dcp.Services, SCPDWithURN{ - URNParts: urnParts, - SCPD: scpd, - }) -} - -type SCPDWithURN struct { - *URNParts - SCPD *scpd.SCPD -} - -func (s *SCPDWithURN) WrapArgument(arg scpd.Argument) (*argumentWrapper, error) { - relVar := s.SCPD.GetStateVariable(arg.RelatedStateVariable) - if relVar == nil { - return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name) - } - cnv, ok := typeConvs[relVar.DataType.Name] - if !ok { - return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name) - } - return &argumentWrapper{ - Argument: arg, - relVar: relVar, - conv: cnv, - }, nil -} - -type argumentWrapper struct { - scpd.Argument - relVar *scpd.StateVariable - conv conv -} - -func (arg *argumentWrapper) AsParameter() string { - return fmt.Sprintf("%s %s", arg.Name, arg.conv.ExtType) -} - -func (arg *argumentWrapper) Document() string { - relVar := arg.relVar - if rng := relVar.AllowedValueRange; rng != nil { - var parts []string - if rng.Minimum != "" { - parts = append(parts, fmt.Sprintf("minimum=%s", rng.Minimum)) - } - if rng.Maximum != "" { - parts = append(parts, fmt.Sprintf("maximum=%s", rng.Maximum)) - } - if rng.Step != "" { - parts = append(parts, fmt.Sprintf("step=%s", rng.Step)) - } - return "allowed value range: " + strings.Join(parts, ", ") - } - if len(relVar.AllowedValues) != 0 { - return "allowed values: " + strings.Join(relVar.AllowedValues, ", ") - } - return "" -} - -func (arg *argumentWrapper) Marshal() string { - return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name) -} - -func (arg *argumentWrapper) Unmarshal(objVar string) string { - return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name) -} - -type conv struct { - FuncSuffix string - ExtType string -} - -// typeConvs maps from a SOAP type (e.g "fixed.14.4") to the function name -// suffix inside the soap module (e.g "Fixed14_4") and the Go type. -var typeConvs = map[string]conv{ - "ui1": conv{"Ui1", "uint8"}, - "ui2": conv{"Ui2", "uint16"}, - "ui4": conv{"Ui4", "uint32"}, - "i1": conv{"I1", "int8"}, - "i2": conv{"I2", "int16"}, - "i4": conv{"I4", "int32"}, - "int": conv{"Int", "int64"}, - "r4": conv{"R4", "float32"}, - "r8": conv{"R8", "float64"}, - "number": conv{"R8", "float64"}, // Alias for r8. - "fixed.14.4": conv{"Fixed14_4", "float64"}, - "float": conv{"R8", "float64"}, - "char": conv{"Char", "rune"}, - "string": conv{"String", "string"}, - "date": conv{"Date", "time.Time"}, - "dateTime": conv{"DateTime", "time.Time"}, - "dateTime.tz": conv{"DateTimeTz", "time.Time"}, - "time": conv{"TimeOfDay", "soap.TimeOfDay"}, - "time.tz": conv{"TimeOfDayTz", "soap.TimeOfDay"}, - "boolean": conv{"Boolean", "bool"}, - "bin.base64": conv{"BinBase64", "[]byte"}, - "bin.hex": conv{"BinHex", "[]byte"}, -} - -type closeableZipReader struct { - io.Closer - *zip.Reader -} - -func openZipfile(filename string) (*closeableZipReader, error) { - file, err := os.Open(filename) - if err != nil { - return nil, err - } - fi, err := file.Stat() - if err != nil { - return nil, err - } - archive, err := zip.NewReader(file, fi.Size()) - if err != nil { - return nil, err - } - return &closeableZipReader{ - Closer: file, - Reader: archive, - }, nil -} - -// openChildZip opens a zip file within another zip file. -func openChildZip(file *zip.File) (*zip.Reader, error) { - zipFile, err := file.Open() - if err != nil { - return nil, err - } - defer zipFile.Close() - - zipBytes, err := ioutil.ReadAll(zipFile) - if err != nil { - return nil, err - } - - return zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes))) -} - -func globFiles(pattern string, archive *zip.Reader) []*zip.File { - var files []*zip.File - for _, f := range archive.File { - if matched, err := path.Match(pattern, f.Name); err != nil { - // This shouldn't happen - all patterns are hard-coded, errors in them - // are a programming error. - panic(err) - } else if matched { - files = append(files, f) - } - } - return files -} - -func unmarshalXmlFile(file *zip.File, data interface{}) error { - r, err := file.Open() - if err != nil { - return err - } - decoder := xml.NewDecoder(r) - r.Close() - return decoder.Decode(data) -} - -type URNParts struct { - URN string - Name string - Version string -} - -func (u *URNParts) Const() string { - return fmt.Sprintf("URN_%s_%s", u.Name, u.Version) -} - -// extractURNParts extracts the name and version from a URN string. -func extractURNParts(urn, expectedPrefix string) (*URNParts, error) { - if !strings.HasPrefix(urn, expectedPrefix) { - return nil, fmt.Errorf("%q does not have expected prefix %q", urn, expectedPrefix) - } - parts := strings.SplitN(strings.TrimPrefix(urn, expectedPrefix), ":", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("%q does not have a name and version", urn) - } - name, version := parts[0], parts[1] - return &URNParts{urn, name, version}, nil -} - -var scpdFilenameRe = regexp.MustCompile( - `.*/([a-zA-Z0-9]+)([0-9]+)\.xml`) - -func urnPartsFromSCPDFilename(filename string) (*URNParts, error) { - parts := scpdFilenameRe.FindStringSubmatch(filename) - if len(parts) != 3 { - return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename) - } - name, version := parts[1], parts[2] - return &URNParts{ - URN: serviceURNPrefix + name + ":" + version, - Name: name, - Version: version, - }, nil -} - -var packageTmpl = template.Must(template.New("package").Parse(`{{$name := .Metadata.Name}} -// Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}. -// {{if .Metadata.DocURL}} -// This DCP is documented in detail at: {{.Metadata.DocURL}}{{end}} -// -// Typically, use one of the New* functions to discover services on the local -// network. -package {{$name}} - -// Generated file - do not edit by hand. See README.md - - -import ( - "time" - - "github.com/fjl/goupnp" - "github.com/fjl/goupnp/soap" -) - -// Hack to avoid Go complaining if time isn't used. -var _ time.Time - -// Device URNs: -const ({{range .DeviceTypes}} - {{.Const}} = "{{.URN}}"{{end}} -) - -// Service URNs: -const ({{range .ServiceTypes}} - {{.Const}} = "{{.URN}}"{{end}} -) - -{{range .Services}} -{{$srv := .}} -{{$srvIdent := printf "%s%s" .Name .Version}} - -// {{$srvIdent}} is a client for UPnP SOAP service with URN "{{.URN}}". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type {{$srvIdent}} struct { - goupnp.ServiceClient -} - -// New{{$srvIdent}}Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients({{$srv.Const}}); err != nil { - return - } - clients = make([]*{{$srvIdent}}, len(genericClients)) - for i := range genericClients { - clients[i] = &{{$srvIdent}}{genericClients[i]} - } - return -} - -{{range .SCPD.Actions}}{{/* loops over *SCPDWithURN values */}} - -{{$inargs := .InputArguments}}{{$outargs := .OutputArguments}} -// {{if $inargs}}Arguments:{{range $inargs}}{{$argWrap := $srv.WrapArgument .}} -// -// * {{.Name}}: {{$argWrap.Document}}{{end}}{{end}} -// -// {{if $outargs}}Return values:{{range $outargs}}{{$argWrap := $srv.WrapArgument .}} -// -// * {{.Name}}: {{$argWrap.Document}}{{end}}{{end}} -func (client *{{$srvIdent}}) {{.Name}}({{range $inargs}}{{/* -*/}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}}{{/* -*/}}) ({{range $outargs}}{{/* -*/}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}} err error) { - // Request structure. - request := {{if $inargs}}&{{template "argstruct" $inargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} - // BEGIN Marshal arguments into request. -{{range $inargs}}{{$argWrap := $srv.WrapArgument .}} - if request.{{.Name}}, err = {{$argWrap.Marshal}}; err != nil { - return - }{{end}} - // END Marshal arguments into request. - - // Response structure. - response := {{if $outargs}}&{{template "argstruct" $outargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. -{{range $outargs}}{{$argWrap := $srv.WrapArgument .}} - if {{.Name}}, err = {{$argWrap.Unmarshal "response"}}; err != nil { - return - }{{end}} - // END Unmarshal arguments from response. - return -} -{{end}}{{/* range .SCPD.Actions */}} -{{end}}{{/* range .Services */}} - -{{define "argstruct"}}struct {{"{"}}{{range .}} -{{.Name}} string -{{end}}{{"}"}}{{end}} -`)) diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/goupnp.go b/Godeps/_workspace/src/github.com/fjl/goupnp/goupnp.go deleted file mode 100644 index c962fbc57..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/goupnp.go +++ /dev/null @@ -1,109 +0,0 @@ -// goupnp is an implementation of a client for various UPnP services. -// -// For most uses, it is recommended to use the code-generated packages under -// github.com/fjl/goupnp/dcps. Example use is shown at -// http://godoc.org/github.com/fjl/goupnp/example -// -// A commonly used client is internetgateway1.WANPPPConnection1: -// http://godoc.org/github.com/fjl/goupnp/dcps/internetgateway1#WANPPPConnection1 -// -// Currently only a couple of schemas have code generated for them from the -// UPnP example XML specifications. Not all methods will work on these clients, -// because the generated stubs contain the full set of specified methods from -// the XML specifications, and the discovered services will likely support a -// subset of those methods. -package goupnp - -import ( - "encoding/xml" - "fmt" - "net/http" - "net/url" - - "github.com/fjl/goupnp/httpu" - "github.com/fjl/goupnp/ssdp" -) - -// ContextError is an error that wraps an error with some context information. -type ContextError struct { - Context string - Err error -} - -func (err ContextError) Error() string { - return fmt.Sprintf("%s: %v", err.Context, err.Err) -} - -// MaybeRootDevice contains either a RootDevice or an error. -type MaybeRootDevice struct { - Root *RootDevice - Err error -} - -// DiscoverDevices attempts to find targets of the given type. This is -// typically the entry-point for this package. searchTarget is typically a URN -// in the form "urn:schemas-upnp-org:device:..." or -// "urn:schemas-upnp-org:service:...". A single error is returned for errors -// while attempting to send the query. An error or RootDevice is returned for -// each discovered RootDevice. -func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) { - httpu, err := httpu.NewHTTPUClient() - if err != nil { - return nil, err - } - defer httpu.Close() - responses, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 2, 3) - if err != nil { - return nil, err - } - - results := make([]MaybeRootDevice, len(responses)) - for i, response := range responses { - maybe := &results[i] - loc, err := response.Location() - if err != nil { - - maybe.Err = ContextError{"unexpected bad location from search", err} - continue - } - locStr := loc.String() - root := new(RootDevice) - if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil { - maybe.Err = ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err} - continue - } - var urlBaseStr string - if root.URLBaseStr != "" { - urlBaseStr = root.URLBaseStr - } else { - urlBaseStr = locStr - } - urlBase, err := url.Parse(urlBaseStr) - if err != nil { - maybe.Err = ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err} - continue - } - root.SetURLBase(urlBase) - maybe.Root = root - } - - return results, nil -} - -func requestXml(url string, defaultSpace string, doc interface{}) error { - resp, err := http.Get(url) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - return fmt.Errorf("goupnp: got response status %s from %q", - resp.Status, url) - } - - decoder := xml.NewDecoder(resp.Body) - decoder.DefaultSpace = defaultSpace - - return decoder.Decode(doc) -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/httpu/httpu.go b/Godeps/_workspace/src/github.com/fjl/goupnp/httpu/httpu.go deleted file mode 100644 index 862c3def4..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/httpu/httpu.go +++ /dev/null @@ -1,117 +0,0 @@ -package httpu - -import ( - "bufio" - "bytes" - "fmt" - "log" - "net" - "net/http" - "sync" - "time" -) - -// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical -// function is for HTTPMU, and particularly SSDP. -type HTTPUClient struct { - connLock sync.Mutex // Protects use of conn. - conn net.PacketConn -} - -// NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the -// purpose. -func NewHTTPUClient() (*HTTPUClient, error) { - conn, err := net.ListenPacket("udp", ":0") - if err != nil { - return nil, err - } - return &HTTPUClient{conn: conn}, nil -} - -// Close shuts down the client. The client will no longer be useful following -// this. -func (httpu *HTTPUClient) Close() error { - httpu.connLock.Lock() - defer httpu.connLock.Unlock() - return httpu.conn.Close() -} - -// Do performs a request. The timeout is how long to wait for before returning -// the responses that were received. An error is only returned for failing to -// send the request. Failures in receipt simply do not add to the resulting -// responses. -// -// Note that at present only one concurrent connection will happen per -// HTTPUClient. -func (httpu *HTTPUClient) Do(req *http.Request, timeout time.Duration, numSends int) ([]*http.Response, error) { - httpu.connLock.Lock() - defer httpu.connLock.Unlock() - - // Create the request. This is a subset of what http.Request.Write does - // deliberately to avoid creating extra fields which may confuse some - // devices. - var requestBuf bytes.Buffer - method := req.Method - if method == "" { - method = "GET" - } - if _, err := fmt.Fprintf(&requestBuf, "%s %s HTTP/1.1\r\n", method, req.URL.RequestURI()); err != nil { - return nil, err - } - if err := req.Header.Write(&requestBuf); err != nil { - return nil, err - } - if _, err := requestBuf.Write([]byte{'\r', '\n'}); err != nil { - return nil, err - } - - destAddr, err := net.ResolveUDPAddr("udp", req.Host) - if err != nil { - return nil, err - } - if err = httpu.conn.SetDeadline(time.Now().Add(timeout)); err != nil { - return nil, err - } - - // Send request. - for i := 0; i < numSends; i++ { - if n, err := httpu.conn.WriteTo(requestBuf.Bytes(), destAddr); err != nil { - return nil, err - } else if n < len(requestBuf.Bytes()) { - return nil, fmt.Errorf("httpu: wrote %d bytes rather than full %d in request", - n, len(requestBuf.Bytes())) - } - time.Sleep(5 * time.Millisecond) - } - - // Await responses until timeout. - var responses []*http.Response - responseBytes := make([]byte, 2048) - for { - // 2048 bytes should be sufficient for most networks. - n, _, err := httpu.conn.ReadFrom(responseBytes) - if err != nil { - if err, ok := err.(net.Error); ok { - if err.Timeout() { - break - } - if err.Temporary() { - // Sleep in case this is a persistent error to avoid pegging CPU until deadline. - time.Sleep(10 * time.Millisecond) - continue - } - } - return nil, err - } - - // Parse response. - response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(responseBytes[:n])), req) - if err != nil { - log.Print("httpu: error while parsing response: %v", err) - continue - } - - responses = append(responses, response) - } - return responses, err -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/httpu/serve.go b/Godeps/_workspace/src/github.com/fjl/goupnp/httpu/serve.go deleted file mode 100644 index 9f67af85b..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/httpu/serve.go +++ /dev/null @@ -1,108 +0,0 @@ -package httpu - -import ( - "bufio" - "bytes" - "log" - "net" - "net/http" - "regexp" -) - -const ( - DefaultMaxMessageBytes = 2048 -) - -var ( - trailingWhitespaceRx = regexp.MustCompile(" +\r\n") - crlf = []byte("\r\n") -) - -// Handler is the interface by which received HTTPU messages are passed to -// handling code. -type Handler interface { - // ServeMessage is called for each HTTPU message received. peerAddr contains - // the address that the message was received from. - ServeMessage(r *http.Request) -} - -// HandlerFunc is a function-to-Handler adapter. -type HandlerFunc func(r *http.Request) - -func (f HandlerFunc) ServeMessage(r *http.Request) { - f(r) -} - -// A Server defines parameters for running an HTTPU server. -type Server struct { - Addr string // UDP address to listen on - Multicast bool // Should listen for multicast? - Interface *net.Interface // Network interface to listen on for multicast, nil for default multicast interface - Handler Handler // handler to invoke - MaxMessageBytes int // maximum number of bytes to read from a packet, DefaultMaxMessageBytes if 0 -} - -// ListenAndServe listens on the UDP network address srv.Addr. If srv.Multicast -// is true, then a multicast UDP listener will be used on srv.Interface (or -// default interface if nil). -func (srv *Server) ListenAndServe() error { - var err error - - var addr *net.UDPAddr - if addr, err = net.ResolveUDPAddr("udp", srv.Addr); err != nil { - log.Fatal(err) - } - - var conn net.PacketConn - if srv.Multicast { - if conn, err = net.ListenMulticastUDP("udp", srv.Interface, addr); err != nil { - return err - } - } else { - if conn, err = net.ListenUDP("udp", addr); err != nil { - return err - } - } - - return srv.Serve(conn) -} - -// Serve messages received on the given packet listener to the srv.Handler. -func (srv *Server) Serve(l net.PacketConn) error { - maxMessageBytes := DefaultMaxMessageBytes - if srv.MaxMessageBytes != 0 { - maxMessageBytes = srv.MaxMessageBytes - } - for { - buf := make([]byte, maxMessageBytes) - n, peerAddr, err := l.ReadFrom(buf) - if err != nil { - return err - } - buf = buf[:n] - - go func(buf []byte, peerAddr net.Addr) { - // At least one router's UPnP implementation has added a trailing space - // after "HTTP/1.1" - trim it. - buf = trailingWhitespaceRx.ReplaceAllLiteral(buf, crlf) - - req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(buf))) - if err != nil { - log.Printf("httpu: Failed to parse request: %v", err) - return - } - req.RemoteAddr = peerAddr.String() - srv.Handler.ServeMessage(req) - // No need to call req.Body.Close - underlying reader is bytes.Buffer. - }(buf, peerAddr) - } -} - -// Serve messages received on the given packet listener to the given handler. -func Serve(l net.PacketConn, handler Handler) error { - srv := Server{ - Handler: handler, - MaxMessageBytes: DefaultMaxMessageBytes, - } - return srv.Serve(l) -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/scpd/scpd.go b/Godeps/_workspace/src/github.com/fjl/goupnp/scpd/scpd.go deleted file mode 100644 index c9d2e69e8..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/scpd/scpd.go +++ /dev/null @@ -1,167 +0,0 @@ -package scpd - -import ( - "encoding/xml" - "strings" -) - -const ( - SCPDXMLNamespace = "urn:schemas-upnp-org:service-1-0" -) - -func cleanWhitespace(s *string) { - *s = strings.TrimSpace(*s) -} - -// SCPD is the service description as described by section 2.5 "Service -// description" in -// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf -type SCPD struct { - XMLName xml.Name `xml:"scpd"` - ConfigId string `xml:"configId,attr"` - SpecVersion SpecVersion `xml:"specVersion"` - Actions []Action `xml:"actionList>action"` - StateVariables []StateVariable `xml:"serviceStateTable>stateVariable"` -} - -// Clean attempts to remove stray whitespace etc. in the structure. It seems -// unfortunately common for stray whitespace to be present in SCPD documents, -// this method attempts to make it easy to clean them out. -func (scpd *SCPD) Clean() { - cleanWhitespace(&scpd.ConfigId) - for i := range scpd.Actions { - scpd.Actions[i].clean() - } - for i := range scpd.StateVariables { - scpd.StateVariables[i].clean() - } -} - -func (scpd *SCPD) GetStateVariable(variable string) *StateVariable { - for i := range scpd.StateVariables { - v := &scpd.StateVariables[i] - if v.Name == variable { - return v - } - } - return nil -} - -func (scpd *SCPD) GetAction(action string) *Action { - for i := range scpd.Actions { - a := &scpd.Actions[i] - if a.Name == action { - return a - } - } - return nil -} - -// SpecVersion is part of a SCPD document, describes the version of the -// specification that the data adheres to. -type SpecVersion struct { - Major int32 `xml:"major"` - Minor int32 `xml:"minor"` -} - -type Action struct { - Name string `xml:"name"` - Arguments []Argument `xml:"argumentList>argument"` -} - -func (action *Action) clean() { - cleanWhitespace(&action.Name) - for i := range action.Arguments { - action.Arguments[i].clean() - } -} - -func (action *Action) InputArguments() []*Argument { - var result []*Argument - for i := range action.Arguments { - arg := &action.Arguments[i] - if arg.IsInput() { - result = append(result, arg) - } - } - return result -} - -func (action *Action) OutputArguments() []*Argument { - var result []*Argument - for i := range action.Arguments { - arg := &action.Arguments[i] - if arg.IsOutput() { - result = append(result, arg) - } - } - return result -} - -type Argument struct { - Name string `xml:"name"` - Direction string `xml:"direction"` // in|out - RelatedStateVariable string `xml:"relatedStateVariable"` // ? - Retval string `xml:"retval"` // ? -} - -func (arg *Argument) clean() { - cleanWhitespace(&arg.Name) - cleanWhitespace(&arg.Direction) - cleanWhitespace(&arg.RelatedStateVariable) - cleanWhitespace(&arg.Retval) -} - -func (arg *Argument) IsInput() bool { - return arg.Direction == "in" -} - -func (arg *Argument) IsOutput() bool { - return arg.Direction == "out" -} - -type StateVariable struct { - Name string `xml:"name"` - SendEvents string `xml:"sendEvents,attr"` // yes|no - Multicast string `xml:"multicast,attr"` // yes|no - DataType DataType `xml:"dataType"` - DefaultValue string `xml:"defaultValue"` - AllowedValueRange *AllowedValueRange `xml:"allowedValueRange"` - AllowedValues []string `xml:"allowedValueList>allowedValue"` -} - -func (v *StateVariable) clean() { - cleanWhitespace(&v.Name) - cleanWhitespace(&v.SendEvents) - cleanWhitespace(&v.Multicast) - v.DataType.clean() - cleanWhitespace(&v.DefaultValue) - if v.AllowedValueRange != nil { - v.AllowedValueRange.clean() - } - for i := range v.AllowedValues { - cleanWhitespace(&v.AllowedValues[i]) - } -} - -type AllowedValueRange struct { - Minimum string `xml:"minimum"` - Maximum string `xml:"maximum"` - Step string `xml:"step"` -} - -func (r *AllowedValueRange) clean() { - cleanWhitespace(&r.Minimum) - cleanWhitespace(&r.Maximum) - cleanWhitespace(&r.Step) -} - -type DataType struct { - Name string `xml:",chardata"` - Type string `xml:"type,attr"` -} - -func (dt *DataType) clean() { - cleanWhitespace(&dt.Name) - cleanWhitespace(&dt.Type) -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/service_client.go b/Godeps/_workspace/src/github.com/fjl/goupnp/service_client.go deleted file mode 100644 index 258b7593b..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/service_client.go +++ /dev/null @@ -1,57 +0,0 @@ -package goupnp - -import ( - "fmt" - - "github.com/fjl/goupnp/soap" -) - -// ServiceClient is a SOAP client, root device and the service for the SOAP -// client rolled into one value. The root device and service are intended to be -// informational. -type ServiceClient struct { - SOAPClient *soap.SOAPClient - RootDevice *RootDevice - Service *Service -} - -func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) { - var maybeRootDevices []MaybeRootDevice - if maybeRootDevices, err = DiscoverDevices(searchTarget); err != nil { - return - } - - clients = make([]ServiceClient, 0, len(maybeRootDevices)) - - for _, maybeRootDevice := range maybeRootDevices { - if maybeRootDevice.Err != nil { - errors = append(errors, maybeRootDevice.Err) - continue - } - - device := &maybeRootDevice.Root.Device - srvs := device.FindService(searchTarget) - if len(srvs) == 0 { - errors = append(errors, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)", - searchTarget, device.FriendlyName, device.UDN)) - continue - } - - for _, srv := range srvs { - clients = append(clients, ServiceClient{ - SOAPClient: srv.NewSOAPClient(), - RootDevice: maybeRootDevice.Root, - Service: srv, - }) - } - } - - return -} - -// GetServiceClient returns the ServiceClient itself. This is provided so that the -// service client attributes can be accessed via an interface method on a -// wrapping type. -func (client *ServiceClient) GetServiceClient() *ServiceClient { - return client -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap.go b/Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap.go deleted file mode 100644 index 815610734..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap.go +++ /dev/null @@ -1,157 +0,0 @@ -// Definition for the SOAP structure required for UPnP's SOAP usage. - -package soap - -import ( - "bytes" - "encoding/xml" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "reflect" -) - -const ( - soapEncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" - soapPrefix = xml.Header + `` - soapSuffix = `` -) - -type SOAPClient struct { - EndpointURL url.URL - HTTPClient http.Client -} - -func NewSOAPClient(endpointURL url.URL) *SOAPClient { - return &SOAPClient{ - EndpointURL: endpointURL, - } -} - -// PerformSOAPAction makes a SOAP request, with the given action. -// inAction and outAction must both be pointers to structs with string fields -// only. -func (client *SOAPClient) PerformAction(actionNamespace, actionName string, inAction interface{}, outAction interface{}) error { - requestBytes, err := encodeRequestAction(actionNamespace, actionName, inAction) - if err != nil { - return err - } - - response, err := client.HTTPClient.Do(&http.Request{ - Method: "POST", - URL: &client.EndpointURL, - Header: http.Header{ - "SOAPACTION": []string{`"` + actionNamespace + "#" + actionName + `"`}, - "CONTENT-TYPE": []string{"text/xml; charset=\"utf-8\""}, - }, - Body: ioutil.NopCloser(bytes.NewBuffer(requestBytes)), - // Set ContentLength to avoid chunked encoding - some servers might not support it. - ContentLength: int64(len(requestBytes)), - }) - if err != nil { - return fmt.Errorf("goupnp: error performing SOAP HTTP request: %v", err) - } - defer response.Body.Close() - if response.StatusCode != 200 { - return fmt.Errorf("goupnp: SOAP request got HTTP %s", response.Status) - } - - responseEnv := newSOAPEnvelope() - decoder := xml.NewDecoder(response.Body) - if err := decoder.Decode(responseEnv); err != nil { - return fmt.Errorf("goupnp: error decoding response body: %v", err) - } - - if responseEnv.Body.Fault != nil { - return responseEnv.Body.Fault - } - - if outAction != nil { - if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { - return fmt.Errorf("goupnp: error unmarshalling out action: %v, %v", err, responseEnv.Body.RawAction) - } - } - - return nil -} - -// newSOAPAction creates a soapEnvelope with the given action and arguments. -func newSOAPEnvelope() *soapEnvelope { - return &soapEnvelope{ - EncodingStyle: soapEncodingStyle, - } -} - -// encodeRequestAction is a hacky way to create an encoded SOAP envelope -// containing the given action. Experiments with one router have shown that it -// 500s for requests where the outer default xmlns is set to the SOAP -// namespace, and then reassigning the default namespace within that to the -// service namespace. Hand-coding the outer XML to work-around this. -func encodeRequestAction(actionNamespace, actionName string, inAction interface{}) ([]byte, error) { - requestBuf := new(bytes.Buffer) - requestBuf.WriteString(soapPrefix) - requestBuf.WriteString(``) - if inAction != nil { - if err := encodeRequestArgs(requestBuf, inAction); err != nil { - return nil, err - } - } - requestBuf.WriteString(``) - requestBuf.WriteString(soapSuffix) - return requestBuf.Bytes(), nil -} - -func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error { - in := reflect.Indirect(reflect.ValueOf(inAction)) - if in.Kind() != reflect.Struct { - return fmt.Errorf("goupnp: SOAP inAction is not a struct but of type %v", in.Type()) - } - enc := xml.NewEncoder(w) - nFields := in.NumField() - inType := in.Type() - for i := 0; i < nFields; i++ { - field := inType.Field(i) - argName := field.Name - if nameOverride := field.Tag.Get("soap"); nameOverride != "" { - argName = nameOverride - } - value := in.Field(i) - if value.Kind() != reflect.String { - return fmt.Errorf("goupnp: SOAP arg %q is not of type string, but of type %v", argName, value.Type()) - } - if err := enc.EncodeElement(value.Interface(), xml.StartElement{xml.Name{"", argName}, nil}); err != nil { - return fmt.Errorf("goupnp: error encoding SOAP arg %q: %v", argName, err) - } - } - enc.Flush() - return nil -} - -type soapEnvelope struct { - XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` - EncodingStyle string `xml:"http://schemas.xmlsoap.org/soap/envelope/ encodingStyle,attr"` - Body soapBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` -} - -type soapBody struct { - Fault *SOAPFaultError `xml:"Fault"` - RawAction []byte `xml:",innerxml"` -} - -// SOAPFaultError implements error, and contains SOAP fault information. -type SOAPFaultError struct { - FaultCode string `xml:"faultcode"` - FaultString string `xml:"faultstring"` - Detail string `xml:"detail"` -} - -func (err *SOAPFaultError) Error() string { - return fmt.Sprintf("SOAP fault: %s", err.FaultString) -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap_test.go b/Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap_test.go deleted file mode 100644 index 75dbbdbf1..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/soap_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package soap - -import ( - "bytes" - "io/ioutil" - "net/http" - "net/url" - "reflect" - "testing" -) - -type capturingRoundTripper struct { - err error - resp *http.Response - capturedReq *http.Request -} - -func (rt *capturingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - rt.capturedReq = req - return rt.resp, rt.err -} - -func TestActionInputs(t *testing.T) { - url, err := url.Parse("http://example.com/soap") - if err != nil { - t.Fatal(err) - } - rt := &capturingRoundTripper{ - err: nil, - resp: &http.Response{ - StatusCode: 200, - Body: ioutil.NopCloser(bytes.NewBufferString(` - - - - valueA - valueB - - - - `)), - }, - } - client := SOAPClient{ - EndpointURL: *url, - HTTPClient: http.Client{ - Transport: rt, - }, - } - - type In struct { - Foo string - Bar string `soap:"bar"` - } - type Out struct { - A string - B string - } - in := In{"foo", "bar"} - gotOut := Out{} - err = client.PerformAction("mynamespace", "myaction", &in, &gotOut) - if err != nil { - t.Fatal(err) - } - - wantBody := (soapPrefix + - `` + - `foo` + - `bar` + - `` + - soapSuffix) - body, err := ioutil.ReadAll(rt.capturedReq.Body) - if err != nil { - t.Fatal(err) - } - gotBody := string(body) - if wantBody != gotBody { - t.Errorf("Bad request body\nwant: %q\n got: %q", wantBody, gotBody) - } - - wantOut := Out{"valueA", "valueB"} - if !reflect.DeepEqual(wantOut, gotOut) { - t.Errorf("Bad output\nwant: %+v\n got: %+v", wantOut, gotOut) - } -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/types.go b/Godeps/_workspace/src/github.com/fjl/goupnp/soap/types.go deleted file mode 100644 index cd16510e3..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/types.go +++ /dev/null @@ -1,508 +0,0 @@ -package soap - -import ( - "encoding/base64" - "encoding/hex" - "errors" - "fmt" - "regexp" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -var ( - // localLoc acts like time.Local for this package, but is faked out by the - // unit tests to ensure that things stay constant (especially when running - // this test in a place where local time is UTC which might mask bugs). - localLoc = time.Local -) - -func MarshalUi1(v uint8) (string, error) { - return strconv.FormatUint(uint64(v), 10), nil -} - -func UnmarshalUi1(s string) (uint8, error) { - v, err := strconv.ParseUint(s, 10, 8) - return uint8(v), err -} - -func MarshalUi2(v uint16) (string, error) { - return strconv.FormatUint(uint64(v), 10), nil -} - -func UnmarshalUi2(s string) (uint16, error) { - v, err := strconv.ParseUint(s, 10, 16) - return uint16(v), err -} - -func MarshalUi4(v uint32) (string, error) { - return strconv.FormatUint(uint64(v), 10), nil -} - -func UnmarshalUi4(s string) (uint32, error) { - v, err := strconv.ParseUint(s, 10, 32) - return uint32(v), err -} - -func MarshalI1(v int8) (string, error) { - return strconv.FormatInt(int64(v), 10), nil -} - -func UnmarshalI1(s string) (int8, error) { - v, err := strconv.ParseInt(s, 10, 8) - return int8(v), err -} - -func MarshalI2(v int16) (string, error) { - return strconv.FormatInt(int64(v), 10), nil -} - -func UnmarshalI2(s string) (int16, error) { - v, err := strconv.ParseInt(s, 10, 16) - return int16(v), err -} - -func MarshalI4(v int32) (string, error) { - return strconv.FormatInt(int64(v), 10), nil -} - -func UnmarshalI4(s string) (int32, error) { - v, err := strconv.ParseInt(s, 10, 32) - return int32(v), err -} - -func MarshalInt(v int64) (string, error) { - return strconv.FormatInt(v, 10), nil -} - -func UnmarshalInt(s string) (int64, error) { - return strconv.ParseInt(s, 10, 64) -} - -func MarshalR4(v float32) (string, error) { - return strconv.FormatFloat(float64(v), 'G', -1, 32), nil -} - -func UnmarshalR4(s string) (float32, error) { - v, err := strconv.ParseFloat(s, 32) - return float32(v), err -} - -func MarshalR8(v float64) (string, error) { - return strconv.FormatFloat(v, 'G', -1, 64), nil -} - -func UnmarshalR8(s string) (float64, error) { - v, err := strconv.ParseFloat(s, 64) - return float64(v), err -} - -// MarshalFixed14_4 marshals float64 to SOAP "fixed.14.4" type. -func MarshalFixed14_4(v float64) (string, error) { - if v >= 1e14 || v <= -1e14 { - return "", fmt.Errorf("soap fixed14.4: value %v out of bounds", v) - } - return strconv.FormatFloat(v, 'f', 4, 64), nil -} - -// UnmarshalFixed14_4 unmarshals float64 from SOAP "fixed.14.4" type. -func UnmarshalFixed14_4(s string) (float64, error) { - v, err := strconv.ParseFloat(s, 64) - if err != nil { - return 0, err - } - if v >= 1e14 || v <= -1e14 { - return 0, fmt.Errorf("soap fixed14.4: value %q out of bounds", s) - } - return v, nil -} - -// MarshalChar marshals rune to SOAP "char" type. -func MarshalChar(v rune) (string, error) { - if v == 0 { - return "", errors.New("soap char: rune 0 is not allowed") - } - return string(v), nil -} - -// UnmarshalChar unmarshals rune from SOAP "char" type. -func UnmarshalChar(s string) (rune, error) { - if len(s) == 0 { - return 0, errors.New("soap char: got empty string") - } - r, n := utf8.DecodeRune([]byte(s)) - if n != len(s) { - return 0, fmt.Errorf("soap char: value %q is not a single rune", s) - } - return r, nil -} - -func MarshalString(v string) (string, error) { - return v, nil -} - -func UnmarshalString(v string) (string, error) { - return v, nil -} - -func parseInt(s string, err *error) int { - v, parseErr := strconv.ParseInt(s, 10, 64) - if parseErr != nil { - *err = parseErr - } - return int(v) -} - -var dateRegexps = []*regexp.Regexp{ - // yyyy[-mm[-dd]] - regexp.MustCompile(`^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$`), - // yyyy[mm[dd]] - regexp.MustCompile(`^(\d{4})(?:(\d{2})(?:(\d{2}))?)?$`), -} - -func parseDateParts(s string) (year, month, day int, err error) { - var parts []string - for _, re := range dateRegexps { - parts = re.FindStringSubmatch(s) - if parts != nil { - break - } - } - if parts == nil { - err = fmt.Errorf("soap date: value %q is not in a recognized ISO8601 date format", s) - return - } - - year = parseInt(parts[1], &err) - month = 1 - day = 1 - if len(parts[2]) != 0 { - month = parseInt(parts[2], &err) - if len(parts[3]) != 0 { - day = parseInt(parts[3], &err) - } - } - - if err != nil { - err = fmt.Errorf("soap date: %q: %v", s, err) - } - - return -} - -var timeRegexps = []*regexp.Regexp{ - // hh[:mm[:ss]] - regexp.MustCompile(`^(\d{2})(?::(\d{2})(?::(\d{2}))?)?$`), - // hh[mm[ss]] - regexp.MustCompile(`^(\d{2})(?:(\d{2})(?:(\d{2}))?)?$`), -} - -func parseTimeParts(s string) (hour, minute, second int, err error) { - var parts []string - for _, re := range timeRegexps { - parts = re.FindStringSubmatch(s) - if parts != nil { - break - } - } - if parts == nil { - err = fmt.Errorf("soap time: value %q is not in ISO8601 time format", s) - return - } - - hour = parseInt(parts[1], &err) - if len(parts[2]) != 0 { - minute = parseInt(parts[2], &err) - if len(parts[3]) != 0 { - second = parseInt(parts[3], &err) - } - } - - if err != nil { - err = fmt.Errorf("soap time: %q: %v", s, err) - } - - return -} - -// (+|-)hh[[:]mm] -var timezoneRegexp = regexp.MustCompile(`^([+-])(\d{2})(?::?(\d{2}))?$`) - -func parseTimezone(s string) (offset int, err error) { - if s == "Z" { - return 0, nil - } - parts := timezoneRegexp.FindStringSubmatch(s) - if parts == nil { - err = fmt.Errorf("soap timezone: value %q is not in ISO8601 timezone format", s) - return - } - - offset = parseInt(parts[2], &err) * 3600 - if len(parts[3]) != 0 { - offset += parseInt(parts[3], &err) * 60 - } - if parts[1] == "-" { - offset = -offset - } - - if err != nil { - err = fmt.Errorf("soap timezone: %q: %v", s, err) - } - - return -} - -var completeDateTimeZoneRegexp = regexp.MustCompile(`^([^T]+)(?:T([^-+Z]+)(.+)?)?$`) - -// splitCompleteDateTimeZone splits date, time and timezone apart from an -// ISO8601 string. It does not ensure that the contents of each part are -// correct, it merely splits on certain delimiters. -// e.g "2010-09-08T12:15:10+0700" => "2010-09-08", "12:15:10", "+0700". -// Timezone can only be present if time is also present. -func splitCompleteDateTimeZone(s string) (dateStr, timeStr, zoneStr string, err error) { - parts := completeDateTimeZoneRegexp.FindStringSubmatch(s) - if parts == nil { - err = fmt.Errorf("soap date/time/zone: value %q is not in ISO8601 datetime format", s) - return - } - dateStr = parts[1] - timeStr = parts[2] - zoneStr = parts[3] - return -} - -// MarshalDate marshals time.Time to SOAP "date" type. Note that this converts -// to local time, and discards the time-of-day components. -func MarshalDate(v time.Time) (string, error) { - return v.In(localLoc).Format("2006-01-02"), nil -} - -var dateFmts = []string{"2006-01-02", "20060102"} - -// UnmarshalDate unmarshals time.Time from SOAP "date" type. This outputs the -// date as midnight in the local time zone. -func UnmarshalDate(s string) (time.Time, error) { - year, month, day, err := parseDateParts(s) - if err != nil { - return time.Time{}, err - } - return time.Date(year, time.Month(month), day, 0, 0, 0, 0, localLoc), nil -} - -// TimeOfDay is used in cases where SOAP "time" or "time.tz" is used. -type TimeOfDay struct { - // Duration of time since midnight. - FromMidnight time.Duration - - // Set to true if Offset is specified. If false, then the timezone is - // unspecified (and by ISO8601 - implies some "local" time). - HasOffset bool - - // Offset is non-zero only if time.tz is used. It is otherwise ignored. If - // non-zero, then it is regarded as a UTC offset in seconds. Note that the - // sub-minutes is ignored by the marshal function. - Offset int -} - -// MarshalTimeOfDay marshals TimeOfDay to the "time" type. -func MarshalTimeOfDay(v TimeOfDay) (string, error) { - d := int64(v.FromMidnight / time.Second) - hour := d / 3600 - d = d % 3600 - minute := d / 60 - second := d % 60 - - return fmt.Sprintf("%02d:%02d:%02d", hour, minute, second), nil -} - -// UnmarshalTimeOfDay unmarshals TimeOfDay from the "time" type. -func UnmarshalTimeOfDay(s string) (TimeOfDay, error) { - t, err := UnmarshalTimeOfDayTz(s) - if err != nil { - return TimeOfDay{}, err - } else if t.HasOffset { - return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone") - } - return t, nil -} - -// MarshalTimeOfDayTz marshals TimeOfDay to the "time.tz" type. -func MarshalTimeOfDayTz(v TimeOfDay) (string, error) { - d := int64(v.FromMidnight / time.Second) - hour := d / 3600 - d = d % 3600 - minute := d / 60 - second := d % 60 - - tz := "" - if v.HasOffset { - if v.Offset == 0 { - tz = "Z" - } else { - offsetMins := v.Offset / 60 - sign := '+' - if offsetMins < 1 { - offsetMins = -offsetMins - sign = '-' - } - tz = fmt.Sprintf("%c%02d:%02d", sign, offsetMins/60, offsetMins%60) - } - } - - return fmt.Sprintf("%02d:%02d:%02d%s", hour, minute, second, tz), nil -} - -// UnmarshalTimeOfDayTz unmarshals TimeOfDay from the "time.tz" type. -func UnmarshalTimeOfDayTz(s string) (tod TimeOfDay, err error) { - zoneIndex := strings.IndexAny(s, "Z+-") - var timePart string - var hasOffset bool - var offset int - if zoneIndex == -1 { - hasOffset = false - timePart = s - } else { - hasOffset = true - timePart = s[:zoneIndex] - if offset, err = parseTimezone(s[zoneIndex:]); err != nil { - return - } - } - - hour, minute, second, err := parseTimeParts(timePart) - if err != nil { - return - } - - fromMidnight := time.Duration(hour*3600+minute*60+second) * time.Second - - // ISO8601 special case - values up to 24:00:00 are allowed, so using - // strictly greater-than for the maximum value. - if fromMidnight > 24*time.Hour || minute >= 60 || second >= 60 { - return TimeOfDay{}, fmt.Errorf("soap time.tz: value %q has value(s) out of range", s) - } - - return TimeOfDay{ - FromMidnight: time.Duration(hour*3600+minute*60+second) * time.Second, - HasOffset: hasOffset, - Offset: offset, - }, nil -} - -// MarshalDateTime marshals time.Time to SOAP "dateTime" type. Note that this -// converts to local time. -func MarshalDateTime(v time.Time) (string, error) { - return v.In(localLoc).Format("2006-01-02T15:04:05"), nil -} - -// UnmarshalDateTime unmarshals time.Time from the SOAP "dateTime" type. This -// returns a value in the local timezone. -func UnmarshalDateTime(s string) (result time.Time, err error) { - dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) - if err != nil { - return - } - - if len(zoneStr) != 0 { - err = fmt.Errorf("soap datetime: unexpected timezone in %q", s) - return - } - - year, month, day, err := parseDateParts(dateStr) - if err != nil { - return - } - - var hour, minute, second int - if len(timeStr) != 0 { - hour, minute, second, err = parseTimeParts(timeStr) - if err != nil { - return - } - } - - result = time.Date(year, time.Month(month), day, hour, minute, second, 0, localLoc) - return -} - -// MarshalDateTimeTz marshals time.Time to SOAP "dateTime.tz" type. -func MarshalDateTimeTz(v time.Time) (string, error) { - return v.Format("2006-01-02T15:04:05-07:00"), nil -} - -// UnmarshalDateTimeTz unmarshals time.Time from the SOAP "dateTime.tz" type. -// This returns a value in the local timezone when the timezone is unspecified. -func UnmarshalDateTimeTz(s string) (result time.Time, err error) { - dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) - if err != nil { - return - } - - year, month, day, err := parseDateParts(dateStr) - if err != nil { - return - } - - var hour, minute, second int - var location *time.Location = localLoc - if len(timeStr) != 0 { - hour, minute, second, err = parseTimeParts(timeStr) - if err != nil { - return - } - if len(zoneStr) != 0 { - var offset int - offset, err = parseTimezone(zoneStr) - if offset == 0 { - location = time.UTC - } else { - location = time.FixedZone("", offset) - } - } - } - - result = time.Date(year, time.Month(month), day, hour, minute, second, 0, location) - return -} - -// MarshalBoolean marshals bool to SOAP "boolean" type. -func MarshalBoolean(v bool) (string, error) { - if v { - return "1", nil - } - return "0", nil -} - -// UnmarshalBoolean unmarshals bool from the SOAP "boolean" type. -func UnmarshalBoolean(s string) (bool, error) { - switch s { - case "0", "false", "no": - return false, nil - case "1", "true", "yes": - return true, nil - } - return false, fmt.Errorf("soap boolean: %q is not a valid boolean value", s) -} - -// MarshalBinBase64 marshals []byte to SOAP "bin.base64" type. -func MarshalBinBase64(v []byte) (string, error) { - return base64.StdEncoding.EncodeToString(v), nil -} - -// UnmarshalBinBase64 unmarshals []byte from the SOAP "bin.base64" type. -func UnmarshalBinBase64(s string) ([]byte, error) { - return base64.StdEncoding.DecodeString(s) -} - -// MarshalBinHex marshals []byte to SOAP "bin.hex" type. -func MarshalBinHex(v []byte) (string, error) { - return hex.EncodeToString(v), nil -} - -// UnmarshalBinHex unmarshals []byte from the SOAP "bin.hex" type. -func UnmarshalBinHex(s string) ([]byte, error) { - return hex.DecodeString(s) -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/types_test.go b/Godeps/_workspace/src/github.com/fjl/goupnp/soap/types_test.go deleted file mode 100644 index da6816190..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/soap/types_test.go +++ /dev/null @@ -1,481 +0,0 @@ -package soap - -import ( - "bytes" - "math" - "testing" - "time" -) - -type convTest interface { - Marshal() (string, error) - Unmarshal(string) (interface{}, error) - Equal(result interface{}) bool -} - -// duper is an interface that convTest values may optionally also implement to -// generate another convTest for a value in an otherwise identical testCase. -type duper interface { - Dupe(tag string) []convTest -} - -type testCase struct { - value convTest - str string - wantMarshalErr bool - wantUnmarshalErr bool - noMarshal bool - noUnMarshal bool - tag string -} - -type Ui1Test uint8 - -func (v Ui1Test) Marshal() (string, error) { - return MarshalUi1(uint8(v)) -} -func (v Ui1Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalUi1(s) -} -func (v Ui1Test) Equal(result interface{}) bool { - return uint8(v) == result.(uint8) -} -func (v Ui1Test) Dupe(tag string) []convTest { - if tag == "dupe" { - return []convTest{ - Ui2Test(v), - Ui4Test(v), - } - } - return nil -} - -type Ui2Test uint16 - -func (v Ui2Test) Marshal() (string, error) { - return MarshalUi2(uint16(v)) -} -func (v Ui2Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalUi2(s) -} -func (v Ui2Test) Equal(result interface{}) bool { - return uint16(v) == result.(uint16) -} - -type Ui4Test uint32 - -func (v Ui4Test) Marshal() (string, error) { - return MarshalUi4(uint32(v)) -} -func (v Ui4Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalUi4(s) -} -func (v Ui4Test) Equal(result interface{}) bool { - return uint32(v) == result.(uint32) -} - -type I1Test int8 - -func (v I1Test) Marshal() (string, error) { - return MarshalI1(int8(v)) -} -func (v I1Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalI1(s) -} -func (v I1Test) Equal(result interface{}) bool { - return int8(v) == result.(int8) -} -func (v I1Test) Dupe(tag string) []convTest { - if tag == "dupe" { - return []convTest{ - I2Test(v), - I4Test(v), - } - } - return nil -} - -type I2Test int16 - -func (v I2Test) Marshal() (string, error) { - return MarshalI2(int16(v)) -} -func (v I2Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalI2(s) -} -func (v I2Test) Equal(result interface{}) bool { - return int16(v) == result.(int16) -} - -type I4Test int32 - -func (v I4Test) Marshal() (string, error) { - return MarshalI4(int32(v)) -} -func (v I4Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalI4(s) -} -func (v I4Test) Equal(result interface{}) bool { - return int32(v) == result.(int32) -} - -type IntTest int64 - -func (v IntTest) Marshal() (string, error) { - return MarshalInt(int64(v)) -} -func (v IntTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalInt(s) -} -func (v IntTest) Equal(result interface{}) bool { - return int64(v) == result.(int64) -} - -type Fixed14_4Test float64 - -func (v Fixed14_4Test) Marshal() (string, error) { - return MarshalFixed14_4(float64(v)) -} -func (v Fixed14_4Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalFixed14_4(s) -} -func (v Fixed14_4Test) Equal(result interface{}) bool { - return math.Abs(float64(v)-result.(float64)) < 0.001 -} - -type CharTest rune - -func (v CharTest) Marshal() (string, error) { - return MarshalChar(rune(v)) -} -func (v CharTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalChar(s) -} -func (v CharTest) Equal(result interface{}) bool { - return rune(v) == result.(rune) -} - -type DateTest struct{ time.Time } - -func (v DateTest) Marshal() (string, error) { - return MarshalDate(time.Time(v.Time)) -} -func (v DateTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalDate(s) -} -func (v DateTest) Equal(result interface{}) bool { - return v.Time.Equal(result.(time.Time)) -} -func (v DateTest) Dupe(tag string) []convTest { - if tag != "no:dateTime" { - return []convTest{DateTimeTest{v.Time}} - } - return nil -} - -type TimeOfDayTest struct { - TimeOfDay -} - -func (v TimeOfDayTest) Marshal() (string, error) { - return MarshalTimeOfDay(v.TimeOfDay) -} -func (v TimeOfDayTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalTimeOfDay(s) -} -func (v TimeOfDayTest) Equal(result interface{}) bool { - return v.TimeOfDay == result.(TimeOfDay) -} -func (v TimeOfDayTest) Dupe(tag string) []convTest { - if tag != "no:time.tz" { - return []convTest{TimeOfDayTzTest{v.TimeOfDay}} - } - return nil -} - -type TimeOfDayTzTest struct { - TimeOfDay -} - -func (v TimeOfDayTzTest) Marshal() (string, error) { - return MarshalTimeOfDayTz(v.TimeOfDay) -} -func (v TimeOfDayTzTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalTimeOfDayTz(s) -} -func (v TimeOfDayTzTest) Equal(result interface{}) bool { - return v.TimeOfDay == result.(TimeOfDay) -} - -type DateTimeTest struct{ time.Time } - -func (v DateTimeTest) Marshal() (string, error) { - return MarshalDateTime(time.Time(v.Time)) -} -func (v DateTimeTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalDateTime(s) -} -func (v DateTimeTest) Equal(result interface{}) bool { - return v.Time.Equal(result.(time.Time)) -} -func (v DateTimeTest) Dupe(tag string) []convTest { - if tag != "no:dateTime.tz" { - return []convTest{DateTimeTzTest{v.Time}} - } - return nil -} - -type DateTimeTzTest struct{ time.Time } - -func (v DateTimeTzTest) Marshal() (string, error) { - return MarshalDateTimeTz(time.Time(v.Time)) -} -func (v DateTimeTzTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalDateTimeTz(s) -} -func (v DateTimeTzTest) Equal(result interface{}) bool { - return v.Time.Equal(result.(time.Time)) -} - -type BooleanTest bool - -func (v BooleanTest) Marshal() (string, error) { - return MarshalBoolean(bool(v)) -} -func (v BooleanTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalBoolean(s) -} -func (v BooleanTest) Equal(result interface{}) bool { - return bool(v) == result.(bool) -} - -type BinBase64Test []byte - -func (v BinBase64Test) Marshal() (string, error) { - return MarshalBinBase64([]byte(v)) -} -func (v BinBase64Test) Unmarshal(s string) (interface{}, error) { - return UnmarshalBinBase64(s) -} -func (v BinBase64Test) Equal(result interface{}) bool { - return bytes.Equal([]byte(v), result.([]byte)) -} - -type BinHexTest []byte - -func (v BinHexTest) Marshal() (string, error) { - return MarshalBinHex([]byte(v)) -} -func (v BinHexTest) Unmarshal(s string) (interface{}, error) { - return UnmarshalBinHex(s) -} -func (v BinHexTest) Equal(result interface{}) bool { - return bytes.Equal([]byte(v), result.([]byte)) -} - -func Test(t *testing.T) { - const time010203 time.Duration = (1*3600 + 2*60 + 3) * time.Second - const time0102 time.Duration = (1*3600 + 2*60) * time.Second - const time01 time.Duration = (1 * 3600) * time.Second - const time235959 time.Duration = (23*3600 + 59*60 + 59) * time.Second - - // Fake out the local time for the implementation. - localLoc = time.FixedZone("Fake/Local", 6*3600) - defer func() { - localLoc = time.Local - }() - - tests := []testCase{ - // ui1 - {str: "", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: " ", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: "abc", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: "-1", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: "0", value: Ui1Test(0), tag: "dupe"}, - {str: "1", value: Ui1Test(1), tag: "dupe"}, - {str: "255", value: Ui1Test(255), tag: "dupe"}, - {str: "256", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true}, - - // ui2 - {str: "65535", value: Ui2Test(65535)}, - {str: "65536", value: Ui2Test(0), wantUnmarshalErr: true, noMarshal: true}, - - // ui4 - {str: "4294967295", value: Ui4Test(4294967295)}, - {str: "4294967296", value: Ui4Test(0), wantUnmarshalErr: true, noMarshal: true}, - - // i1 - {str: "", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: " ", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: "abc", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, - {str: "0", value: I1Test(0), tag: "dupe"}, - {str: "-1", value: I1Test(-1), tag: "dupe"}, - {str: "127", value: I1Test(127), tag: "dupe"}, - {str: "-128", value: I1Test(-128), tag: "dupe"}, - {str: "128", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true}, - {str: "-129", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true}, - - // i2 - {str: "32767", value: I2Test(32767)}, - {str: "-32768", value: I2Test(-32768)}, - {str: "32768", value: I2Test(0), wantUnmarshalErr: true, noMarshal: true}, - {str: "-32769", value: I2Test(0), wantUnmarshalErr: true, noMarshal: true}, - - // i4 - {str: "2147483647", value: I4Test(2147483647)}, - {str: "-2147483648", value: I4Test(-2147483648)}, - {str: "2147483648", value: I4Test(0), wantUnmarshalErr: true, noMarshal: true}, - {str: "-2147483649", value: I4Test(0), wantUnmarshalErr: true, noMarshal: true}, - - // int - {str: "9223372036854775807", value: IntTest(9223372036854775807)}, - {str: "-9223372036854775808", value: IntTest(-9223372036854775808)}, - {str: "9223372036854775808", value: IntTest(0), wantUnmarshalErr: true, noMarshal: true}, - {str: "-9223372036854775809", value: IntTest(0), wantUnmarshalErr: true, noMarshal: true}, - - // fixed.14.4 - {str: "0.0000", value: Fixed14_4Test(0)}, - {str: "1.0000", value: Fixed14_4Test(1)}, - {str: "1.2346", value: Fixed14_4Test(1.23456)}, - {str: "-1.0000", value: Fixed14_4Test(-1)}, - {str: "-1.2346", value: Fixed14_4Test(-1.23456)}, - {str: "10000000000000.0000", value: Fixed14_4Test(1e13)}, - {str: "100000000000000.0000", value: Fixed14_4Test(1e14), wantMarshalErr: true, wantUnmarshalErr: true}, - {str: "-10000000000000.0000", value: Fixed14_4Test(-1e13)}, - {str: "-100000000000000.0000", value: Fixed14_4Test(-1e14), wantMarshalErr: true, wantUnmarshalErr: true}, - - // char - {str: "a", value: CharTest('a')}, - {str: "z", value: CharTest('z')}, - {str: "\u1234", value: CharTest(0x1234)}, - {str: "aa", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true}, - {str: "", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true}, - - // date - {str: "2013-10-08", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, tag: "no:dateTime"}, - {str: "20131008", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, noMarshal: true, tag: "no:dateTime"}, - {str: "2013-10-08T10:30:50", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime"}, - {str: "2013-10-08T10:30:50Z", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime"}, - {str: "", value: DateTest{}, wantMarshalErr: true, wantUnmarshalErr: true, noMarshal: true}, - {str: "-1", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true}, - - // time - {str: "00:00:00", value: TimeOfDayTest{TimeOfDay{FromMidnight: 0}}}, - {str: "000000", value: TimeOfDayTest{TimeOfDay{FromMidnight: 0}}, noMarshal: true}, - {str: "24:00:00", value: TimeOfDayTest{TimeOfDay{FromMidnight: 24 * time.Hour}}, noMarshal: true}, // ISO8601 special case - {str: "24:01:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "24:00:01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "25:00:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "00:60:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "00:00:60", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "01:02:03", value: TimeOfDayTest{TimeOfDay{FromMidnight: time010203}}}, - {str: "010203", value: TimeOfDayTest{TimeOfDay{FromMidnight: time010203}}, noMarshal: true}, - {str: "23:59:59", value: TimeOfDayTest{TimeOfDay{FromMidnight: time235959}}}, - {str: "235959", value: TimeOfDayTest{TimeOfDay{FromMidnight: time235959}}, noMarshal: true}, - {str: "01:02", value: TimeOfDayTest{TimeOfDay{FromMidnight: time0102}}, noMarshal: true}, - {str: "0102", value: TimeOfDayTest{TimeOfDay{FromMidnight: time0102}}, noMarshal: true}, - {str: "01", value: TimeOfDayTest{TimeOfDay{FromMidnight: time01}}, noMarshal: true}, - {str: "foo 01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "foo\n01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03 foo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03\nfoo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03Z", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03+01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03+01:23", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03+0123", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03-01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03-01:23", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - {str: "01:02:03-0123", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, - - // time.tz - {str: "24:00:01", value: TimeOfDayTzTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "01Z", value: TimeOfDayTzTest{TimeOfDay{time01, true, 0}}, noMarshal: true}, - {str: "01:02:03Z", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 0}}}, - {str: "01+01", value: TimeOfDayTzTest{TimeOfDay{time01, true, 3600}}, noMarshal: true}, - {str: "01:02:03+01", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600}}, noMarshal: true}, - {str: "01:02:03+01:23", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600 + 23*60}}}, - {str: "01:02:03+0123", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600 + 23*60}}, noMarshal: true}, - {str: "01:02:03-01", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -3600}}, noMarshal: true}, - {str: "01:02:03-01:23", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -(3600 + 23*60)}}}, - {str: "01:02:03-0123", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -(3600 + 23*60)}}, noMarshal: true}, - - // dateTime - {str: "2013-10-08T00:00:00", value: DateTimeTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, tag: "no:dateTime.tz"}, - {str: "20131008", value: DateTimeTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, noMarshal: true}, - {str: "2013-10-08T10:30:50", value: DateTimeTest{time.Date(2013, 10, 8, 10, 30, 50, 0, localLoc)}, tag: "no:dateTime.tz"}, - {str: "2013-10-08T10:30:50T", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true}, - {str: "2013-10-08T10:30:50+01", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, - {str: "2013-10-08T10:30:50+01:23", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, - {str: "2013-10-08T10:30:50+0123", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, - {str: "2013-10-08T10:30:50-01", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, - {str: "2013-10-08T10:30:50-01:23", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, - {str: "2013-10-08T10:30:50-0123", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, - - // dateTime.tz - {str: "2013-10-08T10:30:50", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, localLoc)}, noMarshal: true}, - {str: "2013-10-08T10:30:50+01", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:00", 3600))}, noMarshal: true}, - {str: "2013-10-08T10:30:50+01:23", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:23", 3600+23*60))}}, - {str: "2013-10-08T10:30:50+0123", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:23", 3600+23*60))}, noMarshal: true}, - {str: "2013-10-08T10:30:50-01", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:00", -3600))}, noMarshal: true}, - {str: "2013-10-08T10:30:50-01:23", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:23", -(3600+23*60)))}}, - {str: "2013-10-08T10:30:50-0123", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:23", -(3600+23*60)))}, noMarshal: true}, - - // boolean - {str: "0", value: BooleanTest(false)}, - {str: "1", value: BooleanTest(true)}, - {str: "false", value: BooleanTest(false), noMarshal: true}, - {str: "true", value: BooleanTest(true), noMarshal: true}, - {str: "no", value: BooleanTest(false), noMarshal: true}, - {str: "yes", value: BooleanTest(true), noMarshal: true}, - {str: "", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, - {str: "other", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, - {str: "2", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, - {str: "-1", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, - - // bin.base64 - {str: "", value: BinBase64Test{}}, - {str: "YQ==", value: BinBase64Test("a")}, - {str: "TG9uZ2VyIFN0cmluZy4=", value: BinBase64Test("Longer String.")}, - {str: "TG9uZ2VyIEFsaWduZWQu", value: BinBase64Test("Longer Aligned.")}, - - // bin.hex - {str: "", value: BinHexTest{}}, - {str: "61", value: BinHexTest("a")}, - {str: "4c6f6e67657220537472696e672e", value: BinHexTest("Longer String.")}, - {str: "4C6F6E67657220537472696E672E", value: BinHexTest("Longer String."), noMarshal: true}, - } - - // Generate extra test cases from convTests that implement duper. - var extras []testCase - for i := range tests { - if duper, ok := tests[i].value.(duper); ok { - dupes := duper.Dupe(tests[i].tag) - for _, duped := range dupes { - dupedCase := testCase(tests[i]) - dupedCase.value = duped - extras = append(extras, dupedCase) - } - } - } - tests = append(tests, extras...) - - for _, test := range tests { - if test.noMarshal { - } else if resultStr, err := test.value.Marshal(); err != nil && !test.wantMarshalErr { - t.Errorf("For %T marshal %v, want %q, got error: %v", test.value, test.value, test.str, err) - } else if err == nil && test.wantMarshalErr { - t.Errorf("For %T marshal %v, want error, got %q", test.value, test.value, resultStr) - } else if err == nil && resultStr != test.str { - t.Errorf("For %T marshal %v, want %q, got %q", test.value, test.value, test.str, resultStr) - } - - if test.noUnMarshal { - } else if resultValue, err := test.value.Unmarshal(test.str); err != nil && !test.wantUnmarshalErr { - t.Errorf("For %T unmarshal %q, want %v, got error: %v", test.value, test.str, test.value, err) - } else if err == nil && test.wantUnmarshalErr { - t.Errorf("For %T unmarshal %q, want error, got %v", test.value, test.str, resultValue) - } else if err == nil && !test.value.Equal(resultValue) { - t.Errorf("For %T unmarshal %q, want %v, got %v", test.value, test.str, test.value, resultValue) - } - } -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/registry.go b/Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/registry.go deleted file mode 100644 index 9e2611b7f..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/registry.go +++ /dev/null @@ -1,202 +0,0 @@ -package ssdp - -import ( - "fmt" - "log" - "net/http" - "net/url" - "regexp" - "strconv" - "sync" - "time" - - "github.com/fjl/goupnp/httpu" -) - -const ( - maxExpiryTimeSeconds = 24 * 60 * 60 -) - -var ( - maxAgeRx = regexp.MustCompile("max-age=([0-9]+)") -) - -type Entry struct { - // The address that the entry data was actually received from. - RemoteAddr string - // Unique Service Name. Identifies a unique instance of a device or service. - USN string - // Notfication Type. The type of device or service being announced. - NT string - // Server's self-identifying string. - Server string - Host string - // Location of the UPnP root device description. - Location *url.URL - - // Despite BOOTID,CONFIGID being required fields, apparently they are not - // always set by devices. Set to -1 if not present. - - BootID int32 - ConfigID int32 - - SearchPort uint16 - - // When the last update was received for this entry identified by this USN. - LastUpdate time.Time - // When the last update's cached values are advised to expire. - CacheExpiry time.Time -} - -func newEntryFromRequest(r *http.Request) (*Entry, error) { - now := time.Now() - expiryDuration, err := parseCacheControlMaxAge(r.Header.Get("CACHE-CONTROL")) - if err != nil { - return nil, fmt.Errorf("ssdp: error parsing CACHE-CONTROL max age: %v", err) - } - - loc, err := url.Parse(r.Header.Get("LOCATION")) - if err != nil { - return nil, fmt.Errorf("ssdp: error parsing entry Location URL: %v", err) - } - - bootID, err := parseUpnpIntHeader(r.Header, "BOOTID.UPNP.ORG", -1) - if err != nil { - return nil, err - } - configID, err := parseUpnpIntHeader(r.Header, "CONFIGID.UPNP.ORG", -1) - if err != nil { - return nil, err - } - searchPort, err := parseUpnpIntHeader(r.Header, "SEARCHPORT.UPNP.ORG", ssdpSearchPort) - if err != nil { - return nil, err - } - - if searchPort < 1 || searchPort > 65535 { - return nil, fmt.Errorf("ssdp: search port %d is out of range", searchPort) - } - - return &Entry{ - RemoteAddr: r.RemoteAddr, - USN: r.Header.Get("USN"), - NT: r.Header.Get("NT"), - Server: r.Header.Get("SERVER"), - Host: r.Header.Get("HOST"), - Location: loc, - BootID: bootID, - ConfigID: configID, - SearchPort: uint16(searchPort), - LastUpdate: now, - CacheExpiry: now.Add(expiryDuration), - }, nil -} - -func parseCacheControlMaxAge(cc string) (time.Duration, error) { - matches := maxAgeRx.FindStringSubmatch(cc) - if len(matches) != 2 { - return 0, fmt.Errorf("did not find exactly one max-age in cache control header: %q", cc) - } - expirySeconds, err := strconv.ParseInt(matches[1], 10, 16) - if err != nil { - return 0, err - } - if expirySeconds < 1 || expirySeconds > maxExpiryTimeSeconds { - return 0, fmt.Errorf("rejecting bad expiry time of %d seconds", expirySeconds) - } - return time.Duration(expirySeconds) * time.Second, nil -} - -// parseUpnpIntHeader is intended to parse the -// {BOOT,CONFIGID,SEARCHPORT}.UPNP.ORG header fields. It returns the def if -// the head is empty or missing. -func parseUpnpIntHeader(headers http.Header, headerName string, def int32) (int32, error) { - s := headers.Get(headerName) - if s == "" { - return def, nil - } - v, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return 0, fmt.Errorf("ssdp: could not parse header %s: %v", headerName, err) - } - return int32(v), nil -} - -var _ httpu.Handler = new(Registry) - -// Registry maintains knowledge of discovered devices and services. -type Registry struct { - lock sync.Mutex - byUSN map[string]*Entry -} - -func NewRegistry() *Registry { - return &Registry{ - byUSN: make(map[string]*Entry), - } -} - -// ServeMessage implements httpu.Handler, and uses SSDP NOTIFY requests to -// maintain the registry of devices and services. -func (reg *Registry) ServeMessage(r *http.Request) { - if r.Method != methodNotify { - return - } - - nts := r.Header.Get("nts") - - var err error - switch nts { - case ntsAlive: - err = reg.handleNTSAlive(r) - case ntsUpdate: - err = reg.handleNTSUpdate(r) - case ntsByebye: - err = reg.handleNTSByebye(r) - default: - err = fmt.Errorf("unknown NTS value: %q", nts) - } - log.Printf("In %s request from %s: %v", nts, r.RemoteAddr, err) -} - -func (reg *Registry) handleNTSAlive(r *http.Request) error { - entry, err := newEntryFromRequest(r) - if err != nil { - return err - } - - reg.lock.Lock() - defer reg.lock.Unlock() - - reg.byUSN[entry.USN] = entry - - return nil -} - -func (reg *Registry) handleNTSUpdate(r *http.Request) error { - entry, err := newEntryFromRequest(r) - if err != nil { - return err - } - nextBootID, err := parseUpnpIntHeader(r.Header, "NEXTBOOTID.UPNP.ORG", -1) - if err != nil { - return err - } - entry.BootID = nextBootID - - reg.lock.Lock() - defer reg.lock.Unlock() - - reg.byUSN[entry.USN] = entry - - return nil -} - -func (reg *Registry) handleNTSByebye(r *http.Request) error { - reg.lock.Lock() - defer reg.lock.Unlock() - - delete(reg.byUSN, r.Header.Get("USN")) - - return nil -} diff --git a/Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/ssdp.go b/Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/ssdp.go deleted file mode 100644 index 6a186afa5..000000000 --- a/Godeps/_workspace/src/github.com/fjl/goupnp/ssdp/ssdp.go +++ /dev/null @@ -1,83 +0,0 @@ -package ssdp - -import ( - "errors" - "log" - "net/http" - "net/url" - "strconv" - "time" - - "github.com/fjl/goupnp/httpu" -) - -const ( - ssdpDiscover = `"ssdp:discover"` - ntsAlive = `ssdp:alive` - ntsByebye = `ssdp:byebye` - ntsUpdate = `ssdp:update` - ssdpUDP4Addr = "239.255.255.250:1900" - ssdpSearchPort = 1900 - methodSearch = "M-SEARCH" - methodNotify = "NOTIFY" -) - -// SSDPRawSearch performs a fairly raw SSDP search request, and returns the -// unique response(s) that it receives. Each response has the requested -// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to -// wait for responses in seconds, and must be a minimum of 1 (the -// implementation waits an additional 100ms for responses to arrive), 2 is a -// reasonable value for this. numSends is the number of requests to send - 3 is -// a reasonable value for this. -func SSDPRawSearch(httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) { - if maxWaitSeconds < 1 { - return nil, errors.New("ssdp: maxWaitSeconds must be >= 1") - } - - seenUsns := make(map[string]bool) - var responses []*http.Response - req := http.Request{ - Method: methodSearch, - // TODO: Support both IPv4 and IPv6. - Host: ssdpUDP4Addr, - URL: &url.URL{Opaque: "*"}, - Header: http.Header{ - // Putting headers in here avoids them being title-cased. - // (The UPnP discovery protocol uses case-sensitive headers) - "HOST": []string{ssdpUDP4Addr}, - "MX": []string{strconv.FormatInt(int64(maxWaitSeconds), 10)}, - "MAN": []string{ssdpDiscover}, - "ST": []string{searchTarget}, - }, - } - allResponses, err := httpu.Do(&req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends) - if err != nil { - return nil, err - } - for _, response := range allResponses { - if response.StatusCode != 200 { - log.Printf("ssdp: got response status code %q in search response", response.Status) - continue - } - if st := response.Header.Get("ST"); st != searchTarget { - log.Printf("ssdp: got unexpected search target result %q", st) - continue - } - location, err := response.Location() - if err != nil { - log.Printf("ssdp: no usable location in search response (discarding): %v", err) - continue - } - usn := response.Header.Get("USN") - if usn == "" { - log.Printf("ssdp: empty/missing USN in search response (using location instead): %v", err) - usn = location.String() - } - if _, alreadySeen := seenUsns[usn]; !alreadySeen { - seenUsns[usn] = true - responses = append(responses, response) - } - } - - return responses, nil -} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/LICENSE b/Godeps/_workspace/src/github.com/huin/goupnp/LICENSE new file mode 100644 index 000000000..252e3d639 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2013, John Beisley +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/README.md b/Godeps/_workspace/src/github.com/huin/goupnp/README.md new file mode 100644 index 000000000..ea2c155a1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/README.md @@ -0,0 +1,14 @@ +goupnp is a UPnP client library for Go + +Installation +------------ + +Run `go get -u github.com/huin/goupnp`. + +Regenerating dcps generated source code: +---------------------------------------- + +1. Install gotasks: `go get -u github.com/jingweno/gotask` +2. Change to the gotasks directory: `cd gotasks` +3. Download UPnP specification data (if not done already): `wget http://upnp.org/resources/upnpresources.zip` +4. Regenerate source code: `gotask specgen -s upnpresources.zip -o ../dcps` diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_httpu_serving/example_httpu_serving.go b/Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_httpu_serving/example_httpu_serving.go new file mode 100644 index 000000000..d9d9daa93 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_httpu_serving/example_httpu_serving.go @@ -0,0 +1,20 @@ +package main + +import ( + "log" + "net/http" + + "github.com/huin/goupnp/httpu" +) + +func main() { + srv := httpu.Server{ + Addr: "239.255.255.250:1900", + Multicast: true, + Handler: httpu.HandlerFunc(func(r *http.Request) { + log.Printf("Got %s %s message from %v: %v", r.Method, r.URL.Path, r.RemoteAddr, r.Header) + }), + } + err := srv.ListenAndServe() + log.Printf("Serving failed with error: %v", err) +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_internetgateway1/example_internetgateway1.go b/Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_internetgateway1/example_internetgateway1.go new file mode 100644 index 000000000..29e8adc8b --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_internetgateway1/example_internetgateway1.go @@ -0,0 +1,67 @@ +package main + +import ( + "fmt" + "log" + + "github.com/huin/goupnp/dcps/internetgateway1" +) + +func main() { + clients, errors, err := internetgateway1.NewWANPPPConnection1Clients() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Got %d errors finding servers and %d successfully discovered.\n", + len(errors), len(clients)) + for i, e := range errors { + fmt.Printf("Error finding server #%d: %v\n", i+1, e) + } + + for _, c := range clients { + dev := &c.ServiceClient.RootDevice.Device + srv := c.ServiceClient.Service + fmt.Println(dev.FriendlyName, " :: ", srv.String()) + scpd, err := srv.RequestSCDP() + if err != nil { + fmt.Printf(" Error requesting service SCPD: %v\n", err) + } else { + fmt.Println(" Available actions:") + for _, action := range scpd.Actions { + fmt.Printf(" * %s\n", action.Name) + for _, arg := range action.Arguments { + var varDesc string + if stateVar := scpd.GetStateVariable(arg.RelatedStateVariable); stateVar != nil { + varDesc = fmt.Sprintf(" (%s)", stateVar.DataType.Name) + } + fmt.Printf(" * [%s] %s%s\n", arg.Direction, arg.Name, varDesc) + } + } + } + + if scpd == nil || scpd.GetAction("GetExternalIPAddress") != nil { + ip, err := c.GetExternalIPAddress() + fmt.Println("GetExternalIPAddress: ", ip, err) + } + + if scpd == nil || scpd.GetAction("GetStatusInfo") != nil { + status, lastErr, uptime, err := c.GetStatusInfo() + fmt.Println("GetStatusInfo: ", status, lastErr, uptime, err) + } + + if scpd == nil || scpd.GetAction("GetIdleDisconnectTime") != nil { + idleTime, err := c.GetIdleDisconnectTime() + fmt.Println("GetIdleDisconnectTime: ", idleTime, err) + } + + if scpd == nil || scpd.GetAction("AddPortMapping") != nil { + err := c.AddPortMapping("", 5000, "TCP", 5001, "192.168.1.2", true, "Test port mapping", 0) + fmt.Println("AddPortMapping: ", err) + } + if scpd == nil || scpd.GetAction("DeletePortMapping") != nil { + err := c.DeletePortMapping("", 5000, "TCP") + fmt.Println("DeletePortMapping: ", err) + } + } +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go b/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go new file mode 100644 index 000000000..be71855a9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go @@ -0,0 +1,3957 @@ +// Client for UPnP Device Control Protocol Internet Gateway Device v1. +// +// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf +// +// Typically, use one of the New* functions to discover services on the local +// network. +package internetgateway1 + +// Generated file - do not edit by hand. See README.md + +import ( + "time" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/soap" +) + +// Hack to avoid Go complaining if time isn't used. +var _ time.Time + +// Device URNs: +const ( + URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" + URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" + URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" +) + +// Service URNs: +const ( + URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1" + URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1" + URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1" + URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" + URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1" + URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1" + URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" + URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1" + URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" +) + +// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type LANHostConfigManagement1 struct { + goupnp.ServiceClient +} + +// NewLANHostConfigManagement1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil { + return + } + clients = make([]*LANHostConfigManagement1, len(genericClients)) + for i := range genericClients { + clients[i] = &LANHostConfigManagement1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewDHCPServerConfigurable: +// +// +func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) { + // Request structure. + request := &struct { + NewDHCPServerConfigurable string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDHCPServerConfigurable: +func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDHCPServerConfigurable string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDHCPRelay: +// +// +func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) { + // Request structure. + request := &struct { + NewDHCPRelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDHCPRelay: +func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDHCPRelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewSubnetMask: +// +// +func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) { + // Request structure. + request := &struct { + NewSubnetMask string + }{} + // BEGIN Marshal arguments into request. + + if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewSubnetMask: +func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewSubnetMask string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIPRouters: +// +// +func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) { + // Request structure. + request := &struct { + NewIPRouters string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIPRouters: +// +// +func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) { + // Request structure. + request := &struct { + NewIPRouters string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIPRouters: +func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIPRouters string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDomainName: +// +// +func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) { + // Request structure. + request := &struct { + NewDomainName string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDomainName: +func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDomainName string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewMinAddress: +// +// * NewMaxAddress: +// +// +func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) { + // Request structure. + request := &struct { + NewMinAddress string + + NewMaxAddress string + }{} + // BEGIN Marshal arguments into request. + + if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil { + return + } + if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewMinAddress: +// +// * NewMaxAddress: +func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewMinAddress string + + NewMaxAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil { + return + } + if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewReservedAddresses: +// +// +func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) { + // Request structure. + request := &struct { + NewReservedAddresses string + }{} + // BEGIN Marshal arguments into request. + + if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewReservedAddresses: +// +// +func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) { + // Request structure. + request := &struct { + NewReservedAddresses string + }{} + // BEGIN Marshal arguments into request. + + if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewReservedAddresses: +func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewReservedAddresses string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDNSServers: +// +// +func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) { + // Request structure. + request := &struct { + NewDNSServers string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDNSServers: +// +// +func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) { + // Request structure. + request := &struct { + NewDNSServers string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDNSServers: +func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDNSServers string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type Layer3Forwarding1 struct { + goupnp.ServiceClient +} + +// NewLayer3Forwarding1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil { + return + } + clients = make([]*Layer3Forwarding1, len(genericClients)) + for i := range genericClients { + clients[i] = &Layer3Forwarding1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewDefaultConnectionService: +// +// +func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) { + // Request structure. + request := &struct { + NewDefaultConnectionService string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDefaultConnectionService: +func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDefaultConnectionService string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANCableLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANCableLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil { + return + } + clients = make([]*WANCableLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANCableLinkConfig1{genericClients[i]} + } + return +} + +// +// +// Return values: +// +// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied +// +// * NewLinkType: allowed values: Ethernet +func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewCableLinkConfigState string + + NewLinkType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil { + return + } + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDownstreamFrequency: +func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDownstreamFrequency string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDownstreamModulation: allowed values: 64QAM, 256QAM +func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDownstreamModulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamFrequency: +func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamFrequency string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamModulation: allowed values: QPSK, 16QAM +func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamModulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamChannelID: +func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamChannelID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamPowerLevel: +func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamPowerLevel string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewBPIEncryptionEnabled: +func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewBPIEncryptionEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConfigFile: +func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConfigFile string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTFTPServer: +func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTFTPServer string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANCommonInterfaceConfig1 struct { + goupnp.ServiceClient +} + +// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil { + return + } + clients = make([]*WANCommonInterfaceConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANCommonInterfaceConfig1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewEnabledForInternet: +// +// +func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) { + // Request structure. + request := &struct { + NewEnabledForInternet string + }{} + // BEGIN Marshal arguments into request. + + if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewEnabledForInternet: +func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewEnabledForInternet string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet +// +// * NewLayer1UpstreamMaxBitRate: +// +// * NewLayer1DownstreamMaxBitRate: +// +// * NewPhysicalLinkStatus: allowed values: Up, Down +func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWANAccessType string + + NewLayer1UpstreamMaxBitRate string + + NewLayer1DownstreamMaxBitRate string + + NewPhysicalLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil { + return + } + if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil { + return + } + if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil { + return + } + if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWANAccessProvider: +func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWANAccessProvider string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1 +func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewMaximumActiveConnections string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalBytesSent: +func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalBytesSent string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalBytesReceived: +func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalBytesReceived string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalPacketsSent: +func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalPacketsSent string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalPacketsReceived: +func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalPacketsReceived string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewActiveConnectionIndex: +// +// Return values: +// +// * NewActiveConnDeviceContainer: +// +// * NewActiveConnectionServiceID: +func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { + // Request structure. + request := &struct { + NewActiveConnectionIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewActiveConnDeviceContainer string + + NewActiveConnectionServiceID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil { + return + } + if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANDSLLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANDSLLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil { + return + } + clients = make([]*WANDSLLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANDSLLinkConfig1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewLinkType: +// +// +func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) { + // Request structure. + request := &struct { + NewLinkType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewLinkType: +// +// * NewLinkStatus: allowed values: Up, Down +func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewLinkType string + + NewLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoConfig: +func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoConfig string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewModulationType: +func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewModulationType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDestinationAddress: +// +// +func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) { + // Request structure. + request := &struct { + NewDestinationAddress string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDestinationAddress: +func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDestinationAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewATMEncapsulation: +// +// +func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) { + // Request structure. + request := &struct { + NewATMEncapsulation string + }{} + // BEGIN Marshal arguments into request. + + if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewATMEncapsulation: +func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewATMEncapsulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewFCSPreserved: +// +// +func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) { + // Request structure. + request := &struct { + NewFCSPreserved string + }{} + // BEGIN Marshal arguments into request. + + if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewFCSPreserved: +func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewFCSPreserved string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANEthernetLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil { + return + } + clients = make([]*WANEthernetLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANEthernetLinkConfig1{genericClients[i]} + } + return +} + +// +// +// Return values: +// +// * NewEthernetLinkStatus: allowed values: Up, Down +func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewEthernetLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPConnection1 struct { + goupnp.ServiceClient +} + +// NewWANIPConnection1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil { + return + } + clients = make([]*WANIPConnection1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPConnection1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewConnectionType: +// +// +func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionType: +// +// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged +func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection1) RequestConnection() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection1) RequestTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection1) ForceTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewAutoDisconnectTime: +// +// +func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIdleDisconnectTime: +// +// +func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewWarnDisconnectDelay: +// +// +func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +// +// * NewUptime: +func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + + NewLastConnectionError string + + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoDisconnectTime: +func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIdleDisconnectTime: +func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWarnDisconnectDelay: +func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewRSIPAvailable: +// +// * NewNATEnabled: +func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewPortMappingIndex: +// +// Return values: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// Return values: +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +// +// +func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// +func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewExternalIPAddress: +func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANPOTSLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil { + return + } + clients = make([]*WANPOTSLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANPOTSLinkConfig1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewISPPhoneNumber: +// +// * NewISPInfo: +// +// * NewLinkType: allowed values: PPP_Dialup +// +// +func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) { + // Request structure. + request := &struct { + NewISPPhoneNumber string + + NewISPInfo string + + NewLinkType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil { + return + } + if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil { + return + } + if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewNumberOfRetries: +// +// * NewDelayBetweenRetries: +// +// +func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { + // Request structure. + request := &struct { + NewNumberOfRetries string + + NewDelayBetweenRetries string + }{} + // BEGIN Marshal arguments into request. + + if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil { + return + } + if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewISPPhoneNumber: +// +// * NewISPInfo: +// +// * NewLinkType: allowed values: PPP_Dialup +func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewISPPhoneNumber string + + NewISPInfo string + + NewLinkType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil { + return + } + if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil { + return + } + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewNumberOfRetries: +// +// * NewDelayBetweenRetries: +func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewNumberOfRetries string + + NewDelayBetweenRetries string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil { + return + } + if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewFclass: +func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewFclass string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDataModulationSupported: +func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataModulationSupported string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDataProtocol: +func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDataCompression: +func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataCompression string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPlusVTRCommandSupported: +func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPlusVTRCommandSupported string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANPPPConnection1 struct { + goupnp.ServiceClient +} + +// NewWANPPPConnection1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil { + return + } + clients = make([]*WANPPPConnection1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANPPPConnection1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewConnectionType: +// +// +func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionType: +// +// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay +func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewUserName: +// +// * NewPassword: +// +// +func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) { + // Request structure. + request := &struct { + NewUserName string + + NewPassword string + }{} + // BEGIN Marshal arguments into request. + + if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { + return + } + if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANPPPConnection1) RequestConnection() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANPPPConnection1) RequestTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANPPPConnection1) ForceTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewAutoDisconnectTime: +// +// +func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIdleDisconnectTime: +// +// +func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewWarnDisconnectDelay: +// +// +func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +// +// * NewUptime: +func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + + NewLastConnectionError string + + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamMaxBitRate: +// +// * NewDownstreamMaxBitRate: +func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamMaxBitRate string + + NewDownstreamMaxBitRate string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { + return + } + if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPPPEncryptionProtocol: +func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPEncryptionProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPPPCompressionProtocol: +func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPCompressionProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPPPAuthenticationProtocol: +func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPAuthenticationProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUserName: +func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUserName string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPassword: +func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPassword string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoDisconnectTime: +func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIdleDisconnectTime: +func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWarnDisconnectDelay: +func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewRSIPAvailable: +// +// * NewNATEnabled: +func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewPortMappingIndex: +// +// Return values: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// Return values: +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +// +// +func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// +func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewExternalIPAddress: +func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go b/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go new file mode 100644 index 000000000..a5892288e --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go @@ -0,0 +1,5271 @@ +// Client for UPnP Device Control Protocol Internet Gateway Device v2. +// +// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf +// +// Typically, use one of the New* functions to discover services on the local +// network. +package internetgateway2 + +// Generated file - do not edit by hand. See README.md + +import ( + "time" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/soap" +) + +// Hack to avoid Go complaining if time isn't used. +var _ time.Time + +// Device URNs: +const ( + URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" + URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" + URN_WANConnectionDevice_2 = "urn:schemas-upnp-org:device:WANConnectionDevice:2" + URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" + URN_WANDevice_2 = "urn:schemas-upnp-org:device:WANDevice:2" +) + +// Service URNs: +const ( + URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1" + URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1" + URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1" + URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" + URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1" + URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1" + URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" + URN_WANIPConnection_2 = "urn:schemas-upnp-org:service:WANIPConnection:2" + URN_WANIPv6FirewallControl_1 = "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" + URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1" + URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" +) + +// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type LANHostConfigManagement1 struct { + goupnp.ServiceClient +} + +// NewLANHostConfigManagement1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil { + return + } + clients = make([]*LANHostConfigManagement1, len(genericClients)) + for i := range genericClients { + clients[i] = &LANHostConfigManagement1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewDHCPServerConfigurable: +// +// +func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) { + // Request structure. + request := &struct { + NewDHCPServerConfigurable string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDHCPServerConfigurable: +func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDHCPServerConfigurable string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDHCPRelay: +// +// +func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) { + // Request structure. + request := &struct { + NewDHCPRelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDHCPRelay: +func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDHCPRelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewSubnetMask: +// +// +func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) { + // Request structure. + request := &struct { + NewSubnetMask string + }{} + // BEGIN Marshal arguments into request. + + if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewSubnetMask: +func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewSubnetMask string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIPRouters: +// +// +func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) { + // Request structure. + request := &struct { + NewIPRouters string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIPRouters: +// +// +func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) { + // Request structure. + request := &struct { + NewIPRouters string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIPRouters: +func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIPRouters string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDomainName: +// +// +func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) { + // Request structure. + request := &struct { + NewDomainName string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDomainName: +func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDomainName string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewMinAddress: +// +// * NewMaxAddress: +// +// +func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) { + // Request structure. + request := &struct { + NewMinAddress string + + NewMaxAddress string + }{} + // BEGIN Marshal arguments into request. + + if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil { + return + } + if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewMinAddress: +// +// * NewMaxAddress: +func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewMinAddress string + + NewMaxAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil { + return + } + if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewReservedAddresses: +// +// +func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) { + // Request structure. + request := &struct { + NewReservedAddresses string + }{} + // BEGIN Marshal arguments into request. + + if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewReservedAddresses: +// +// +func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) { + // Request structure. + request := &struct { + NewReservedAddresses string + }{} + // BEGIN Marshal arguments into request. + + if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewReservedAddresses: +func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewReservedAddresses string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDNSServers: +// +// +func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) { + // Request structure. + request := &struct { + NewDNSServers string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDNSServers: +// +// +func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) { + // Request structure. + request := &struct { + NewDNSServers string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDNSServers: +func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDNSServers string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type Layer3Forwarding1 struct { + goupnp.ServiceClient +} + +// NewLayer3Forwarding1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil { + return + } + clients = make([]*Layer3Forwarding1, len(genericClients)) + for i := range genericClients { + clients[i] = &Layer3Forwarding1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewDefaultConnectionService: +// +// +func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) { + // Request structure. + request := &struct { + NewDefaultConnectionService string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDefaultConnectionService: +func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDefaultConnectionService string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANCableLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANCableLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil { + return + } + clients = make([]*WANCableLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANCableLinkConfig1{genericClients[i]} + } + return +} + +// +// +// Return values: +// +// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied +// +// * NewLinkType: allowed values: Ethernet +func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewCableLinkConfigState string + + NewLinkType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil { + return + } + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDownstreamFrequency: +func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDownstreamFrequency string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDownstreamModulation: allowed values: 64QAM, 256QAM +func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDownstreamModulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamFrequency: +func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamFrequency string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamModulation: allowed values: QPSK, 16QAM +func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamModulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamChannelID: +func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamChannelID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamPowerLevel: +func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamPowerLevel string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewBPIEncryptionEnabled: +func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewBPIEncryptionEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConfigFile: +func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConfigFile string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTFTPServer: +func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTFTPServer string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANCommonInterfaceConfig1 struct { + goupnp.ServiceClient +} + +// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil { + return + } + clients = make([]*WANCommonInterfaceConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANCommonInterfaceConfig1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewEnabledForInternet: +// +// +func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) { + // Request structure. + request := &struct { + NewEnabledForInternet string + }{} + // BEGIN Marshal arguments into request. + + if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewEnabledForInternet: +func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewEnabledForInternet string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet +// +// * NewLayer1UpstreamMaxBitRate: +// +// * NewLayer1DownstreamMaxBitRate: +// +// * NewPhysicalLinkStatus: allowed values: Up, Down +func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWANAccessType string + + NewLayer1UpstreamMaxBitRate string + + NewLayer1DownstreamMaxBitRate string + + NewPhysicalLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil { + return + } + if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil { + return + } + if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil { + return + } + if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWANAccessProvider: +func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWANAccessProvider string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1 +func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewMaximumActiveConnections string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalBytesSent: +func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalBytesSent string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalBytesReceived: +func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalBytesReceived string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalPacketsSent: +func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalPacketsSent string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewTotalPacketsReceived: +func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalPacketsReceived string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewActiveConnectionIndex: +// +// Return values: +// +// * NewActiveConnDeviceContainer: +// +// * NewActiveConnectionServiceID: +func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { + // Request structure. + request := &struct { + NewActiveConnectionIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewActiveConnDeviceContainer string + + NewActiveConnectionServiceID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil { + return + } + if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANDSLLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANDSLLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil { + return + } + clients = make([]*WANDSLLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANDSLLinkConfig1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewLinkType: +// +// +func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) { + // Request structure. + request := &struct { + NewLinkType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewLinkType: +// +// * NewLinkStatus: allowed values: Up, Down +func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewLinkType string + + NewLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoConfig: +func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoConfig string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewModulationType: +func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewModulationType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewDestinationAddress: +// +// +func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) { + // Request structure. + request := &struct { + NewDestinationAddress string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDestinationAddress: +func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDestinationAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewATMEncapsulation: +// +// +func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) { + // Request structure. + request := &struct { + NewATMEncapsulation string + }{} + // BEGIN Marshal arguments into request. + + if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewATMEncapsulation: +func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewATMEncapsulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewFCSPreserved: +// +// +func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) { + // Request structure. + request := &struct { + NewFCSPreserved string + }{} + // BEGIN Marshal arguments into request. + + if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewFCSPreserved: +func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewFCSPreserved string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANEthernetLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil { + return + } + clients = make([]*WANEthernetLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANEthernetLinkConfig1{genericClients[i]} + } + return +} + +// +// +// Return values: +// +// * NewEthernetLinkStatus: allowed values: Up, Down +func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewEthernetLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPConnection1 struct { + goupnp.ServiceClient +} + +// NewWANIPConnection1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil { + return + } + clients = make([]*WANIPConnection1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPConnection1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewConnectionType: +// +// +func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionType: +// +// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged +func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection1) RequestConnection() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection1) RequestTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection1) ForceTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewAutoDisconnectTime: +// +// +func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIdleDisconnectTime: +// +// +func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewWarnDisconnectDelay: +// +// +func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +// +// * NewUptime: +func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + + NewLastConnectionError string + + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoDisconnectTime: +func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIdleDisconnectTime: +func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWarnDisconnectDelay: +func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewRSIPAvailable: +// +// * NewNATEnabled: +func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewPortMappingIndex: +// +// Return values: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// Return values: +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +// +// +func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// +func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewExternalIPAddress: +func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANIPConnection2 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:2". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPConnection2 struct { + goupnp.ServiceClient +} + +// NewWANIPConnection2Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_2); err != nil { + return + } + clients = make([]*WANIPConnection2, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPConnection2{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged +// +// +func (client *WANIPConnection2) SetConnectionType(NewConnectionType string) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged +// +// * NewPossibleConnectionTypes: +func (client *WANIPConnection2) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection2) RequestConnection() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection2) RequestTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANIPConnection2) ForceTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewAutoDisconnectTime: +// +// +func (client *WANIPConnection2) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIdleDisconnectTime: +// +// +func (client *WANIPConnection2) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewWarnDisconnectDelay: +// +// +func (client *WANIPConnection2) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +// +// * NewUptime: +func (client *WANIPConnection2) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + + NewLastConnectionError string + + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoDisconnectTime: +func (client *WANIPConnection2) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIdleDisconnectTime: +func (client *WANIPConnection2) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWarnDisconnectDelay: +func (client *WANIPConnection2) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewRSIPAvailable: +// +// * NewNATEnabled: +func (client *WANIPConnection2) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewPortMappingIndex: +// +// Return values: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: allowed value range: minimum=1, maximum=65535 +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 +func (client *WANIPConnection2) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// Return values: +// +// * NewInternalPort: allowed value range: minimum=1, maximum=65535 +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 +func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: allowed value range: minimum=1, maximum=65535 +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 +// +// +func (client *WANIPConnection2) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// +func (client *WANIPConnection2) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewStartPort: +// +// * NewEndPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewManage: +// +// +func (client *WANIPConnection2) DeletePortMappingRange(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool) (err error) { + // Request structure. + request := &struct { + NewStartPort string + + NewEndPort string + + NewProtocol string + + NewManage string + }{} + // BEGIN Marshal arguments into request. + + if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { + return + } + if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "DeletePortMappingRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewExternalIPAddress: +func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewStartPort: +// +// * NewEndPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewManage: +// +// * NewNumberOfPorts: +// +// Return values: +// +// * NewPortListing: +func (client *WANIPConnection2) GetListOfPortMappings(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool, NewNumberOfPorts uint16) (NewPortListing string, err error) { + // Request structure. + request := &struct { + NewStartPort string + + NewEndPort string + + NewProtocol string + + NewManage string + + NewNumberOfPorts string + }{} + // BEGIN Marshal arguments into request. + + if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { + return + } + if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { + return + } + if request.NewNumberOfPorts, err = soap.MarshalUi2(NewNumberOfPorts); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPortListing string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetListOfPortMappings", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPortListing, err = soap.UnmarshalString(response.NewPortListing); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: allowed value range: minimum=1, maximum=65535 +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800 +// +// Return values: +// +// * NewReservedPort: +func (client *WANIPConnection2) AddAnyPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (NewReservedPort uint16, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewReservedPort string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "AddAnyPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewReservedPort, err = soap.UnmarshalUi2(response.NewReservedPort); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANIPv6FirewallControl1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPv6FirewallControl1 struct { + goupnp.ServiceClient +} + +// NewWANIPv6FirewallControl1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPv6FirewallControl_1); err != nil { + return + } + clients = make([]*WANIPv6FirewallControl1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPv6FirewallControl1{genericClients[i]} + } + return +} + +// +// +// Return values: +// +// * FirewallEnabled: +// +// * InboundPinholeAllowed: +func (client *WANIPv6FirewallControl1) GetFirewallStatus() (FirewallEnabled bool, InboundPinholeAllowed bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + FirewallEnabled string + + InboundPinholeAllowed string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetFirewallStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if FirewallEnabled, err = soap.UnmarshalBoolean(response.FirewallEnabled); err != nil { + return + } + if InboundPinholeAllowed, err = soap.UnmarshalBoolean(response.InboundPinholeAllowed); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * RemoteHost: +// +// * RemotePort: +// +// * InternalClient: +// +// * InternalPort: +// +// * Protocol: +// +// Return values: +// +// * OutboundPinholeTimeout: +func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeout(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16) (OutboundPinholeTimeout uint32, err error) { + // Request structure. + request := &struct { + RemoteHost string + + RemotePort string + + InternalClient string + + InternalPort string + + Protocol string + }{} + // BEGIN Marshal arguments into request. + + if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil { + return + } + if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil { + return + } + if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil { + return + } + if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil { + return + } + if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + OutboundPinholeTimeout string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetOutboundPinholeTimeout", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if OutboundPinholeTimeout, err = soap.UnmarshalUi4(response.OutboundPinholeTimeout); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * RemoteHost: +// +// * RemotePort: +// +// * InternalClient: +// +// * InternalPort: +// +// * Protocol: +// +// * LeaseTime: allowed value range: minimum=1, maximum=86400 +// +// Return values: +// +// * UniqueID: +func (client *WANIPv6FirewallControl1) AddPinhole(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16, LeaseTime uint32) (UniqueID uint16, err error) { + // Request structure. + request := &struct { + RemoteHost string + + RemotePort string + + InternalClient string + + InternalPort string + + Protocol string + + LeaseTime string + }{} + // BEGIN Marshal arguments into request. + + if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil { + return + } + if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil { + return + } + if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil { + return + } + if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil { + return + } + if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil { + return + } + if request.LeaseTime, err = soap.MarshalUi4(LeaseTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + UniqueID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "AddPinhole", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if UniqueID, err = soap.UnmarshalUi2(response.UniqueID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * UniqueID: +// +// * NewLeaseTime: allowed value range: minimum=1, maximum=86400 +// +// +func (client *WANIPv6FirewallControl1) UpdatePinhole(UniqueID uint16, NewLeaseTime uint32) (err error) { + // Request structure. + request := &struct { + UniqueID string + + NewLeaseTime string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + if request.NewLeaseTime, err = soap.MarshalUi4(NewLeaseTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "UpdatePinhole", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * UniqueID: +// +// +func (client *WANIPv6FirewallControl1) DeletePinhole(UniqueID uint16) (err error) { + // Request structure. + request := &struct { + UniqueID string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "DeletePinhole", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * UniqueID: +// +// Return values: +// +// * PinholePackets: +func (client *WANIPv6FirewallControl1) GetPinholePackets(UniqueID uint16) (PinholePackets uint32, err error) { + // Request structure. + request := &struct { + UniqueID string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + PinholePackets string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetPinholePackets", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if PinholePackets, err = soap.UnmarshalUi4(response.PinholePackets); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * UniqueID: +// +// Return values: +// +// * IsWorking: +func (client *WANIPv6FirewallControl1) CheckPinholeWorking(UniqueID uint16) (IsWorking bool, err error) { + // Request structure. + request := &struct { + UniqueID string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + IsWorking string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "CheckPinholeWorking", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if IsWorking, err = soap.UnmarshalBoolean(response.IsWorking); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANPOTSLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil { + return + } + clients = make([]*WANPOTSLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANPOTSLinkConfig1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewISPPhoneNumber: +// +// * NewISPInfo: +// +// * NewLinkType: allowed values: PPP_Dialup +// +// +func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) { + // Request structure. + request := &struct { + NewISPPhoneNumber string + + NewISPInfo string + + NewLinkType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil { + return + } + if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil { + return + } + if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewNumberOfRetries: +// +// * NewDelayBetweenRetries: +// +// +func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { + // Request structure. + request := &struct { + NewNumberOfRetries string + + NewDelayBetweenRetries string + }{} + // BEGIN Marshal arguments into request. + + if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil { + return + } + if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewISPPhoneNumber: +// +// * NewISPInfo: +// +// * NewLinkType: allowed values: PPP_Dialup +func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewISPPhoneNumber string + + NewISPInfo string + + NewLinkType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil { + return + } + if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil { + return + } + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewNumberOfRetries: +// +// * NewDelayBetweenRetries: +func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewNumberOfRetries string + + NewDelayBetweenRetries string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil { + return + } + if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewFclass: +func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewFclass string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDataModulationSupported: +func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataModulationSupported string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDataProtocol: +func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewDataCompression: +func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataCompression string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPlusVTRCommandSupported: +func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPlusVTRCommandSupported string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANPPPConnection1 struct { + goupnp.ServiceClient +} + +// NewWANPPPConnection1Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil { + return + } + clients = make([]*WANPPPConnection1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANPPPConnection1{genericClients[i]} + } + return +} + +// Arguments: +// +// * NewConnectionType: +// +// +func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionType: +// +// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay +func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewUserName: +// +// * NewPassword: +// +// +func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) { + // Request structure. + request := &struct { + NewUserName string + + NewPassword string + }{} + // BEGIN Marshal arguments into request. + + if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { + return + } + if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANPPPConnection1) RequestConnection() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANPPPConnection1) RequestTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// +func (client *WANPPPConnection1) ForceTermination() (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewAutoDisconnectTime: +// +// +func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewIdleDisconnectTime: +// +// +func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewWarnDisconnectDelay: +// +// +func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +// +// * NewUptime: +func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + + NewLastConnectionError string + + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUpstreamMaxBitRate: +// +// * NewDownstreamMaxBitRate: +func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamMaxBitRate string + + NewDownstreamMaxBitRate string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { + return + } + if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPPPEncryptionProtocol: +func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPEncryptionProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPPPCompressionProtocol: +func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPCompressionProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPPPAuthenticationProtocol: +func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPAuthenticationProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewUserName: +func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUserName string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewPassword: +func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPassword string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewAutoDisconnectTime: +func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewIdleDisconnectTime: +func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewWarnDisconnectDelay: +func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewRSIPAvailable: +// +// * NewNATEnabled: +func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewPortMappingIndex: +// +// Return values: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// Return values: +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// * NewInternalPort: +// +// * NewInternalClient: +// +// * NewEnabled: +// +// * NewPortMappingDescription: +// +// * NewLeaseDuration: +// +// +func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + + NewInternalPort string + + NewInternalClient string + + NewEnabled string + + NewPortMappingDescription string + + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// Arguments: +// +// * NewRemoteHost: +// +// * NewExternalPort: +// +// * NewProtocol: allowed values: TCP, UDP +// +// +func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + + NewExternalPort string + + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// +// +// Return values: +// +// * NewExternalIPAddress: +func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/device.go b/Godeps/_workspace/src/github.com/huin/goupnp/device.go new file mode 100644 index 000000000..e5b658b21 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/device.go @@ -0,0 +1,184 @@ +// This file contains XML structures for communicating with UPnP devices. + +package goupnp + +import ( + "encoding/xml" + "errors" + "fmt" + "net/url" + + "github.com/huin/goupnp/scpd" + "github.com/huin/goupnp/soap" +) + +const ( + DeviceXMLNamespace = "urn:schemas-upnp-org:device-1-0" +) + +// RootDevice is the device description as described by section 2.3 "Device +// description" in +// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf +type RootDevice struct { + XMLName xml.Name `xml:"root"` + SpecVersion SpecVersion `xml:"specVersion"` + URLBase url.URL `xml:"-"` + URLBaseStr string `xml:"URLBase"` + Device Device `xml:"device"` +} + +// SetURLBase sets the URLBase for the RootDevice and its underlying components. +func (root *RootDevice) SetURLBase(urlBase *url.URL) { + root.URLBase = *urlBase + root.URLBaseStr = urlBase.String() + root.Device.SetURLBase(urlBase) +} + +// SpecVersion is part of a RootDevice, describes the version of the +// specification that the data adheres to. +type SpecVersion struct { + Major int32 `xml:"major"` + Minor int32 `xml:"minor"` +} + +// Device is a UPnP device. It can have child devices. +type Device struct { + DeviceType string `xml:"deviceType"` + FriendlyName string `xml:"friendlyName"` + Manufacturer string `xml:"manufacturer"` + ManufacturerURL URLField `xml:"manufacturerURL"` + ModelDescription string `xml:"modelDescription"` + ModelName string `xml:"modelName"` + ModelNumber string `xml:"modelNumber"` + ModelURL URLField `xml:"modelURL"` + SerialNumber string `xml:"serialNumber"` + UDN string `xml:"UDN"` + UPC string `xml:"UPC,omitempty"` + Icons []Icon `xml:"iconList>icon,omitempty"` + Services []Service `xml:"serviceList>service,omitempty"` + Devices []Device `xml:"deviceList>device,omitempty"` + + // Extra observed elements: + PresentationURL URLField `xml:"presentationURL"` +} + +// VisitDevices calls visitor for the device, and all its descendent devices. +func (device *Device) VisitDevices(visitor func(*Device)) { + visitor(device) + for i := range device.Devices { + device.Devices[i].VisitDevices(visitor) + } +} + +// VisitServices calls visitor for all Services under the device and all its +// descendent devices. +func (device *Device) VisitServices(visitor func(*Service)) { + device.VisitDevices(func(d *Device) { + for i := range d.Services { + visitor(&d.Services[i]) + } + }) +} + +// FindService finds all (if any) Services under the device and its descendents +// that have the given ServiceType. +func (device *Device) FindService(serviceType string) []*Service { + var services []*Service + device.VisitServices(func(s *Service) { + if s.ServiceType == serviceType { + services = append(services, s) + } + }) + return services +} + +// SetURLBase sets the URLBase for the Device and its underlying components. +func (device *Device) SetURLBase(urlBase *url.URL) { + device.ManufacturerURL.SetURLBase(urlBase) + device.ModelURL.SetURLBase(urlBase) + device.PresentationURL.SetURLBase(urlBase) + for i := range device.Icons { + device.Icons[i].SetURLBase(urlBase) + } + for i := range device.Services { + device.Services[i].SetURLBase(urlBase) + } + for i := range device.Devices { + device.Devices[i].SetURLBase(urlBase) + } +} + +func (device *Device) String() string { + return fmt.Sprintf("Device ID %s : %s (%s)", device.UDN, device.DeviceType, device.FriendlyName) +} + +// Icon is a representative image that a device might include in its +// description. +type Icon struct { + Mimetype string `xml:"mimetype"` + Width int32 `xml:"width"` + Height int32 `xml:"height"` + Depth int32 `xml:"depth"` + URL URLField `xml:"url"` +} + +// SetURLBase sets the URLBase for the Icon. +func (icon *Icon) SetURLBase(url *url.URL) { + icon.URL.SetURLBase(url) +} + +// Service is a service provided by a UPnP Device. +type Service struct { + ServiceType string `xml:"serviceType"` + ServiceId string `xml:"serviceId"` + SCPDURL URLField `xml:"SCPDURL"` + ControlURL URLField `xml:"controlURL"` + EventSubURL URLField `xml:"eventSubURL"` +} + +// SetURLBase sets the URLBase for the Service. +func (srv *Service) SetURLBase(urlBase *url.URL) { + srv.SCPDURL.SetURLBase(urlBase) + srv.ControlURL.SetURLBase(urlBase) + srv.EventSubURL.SetURLBase(urlBase) +} + +func (srv *Service) String() string { + return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType) +} + +// RequestSCDP requests the SCPD (soap actions and state variables description) +// for the service. +func (srv *Service) RequestSCDP() (*scpd.SCPD, error) { + if !srv.SCPDURL.Ok { + return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set") + } + s := new(scpd.SCPD) + if err := requestXml(srv.SCPDURL.URL.String(), scpd.SCPDXMLNamespace, s); err != nil { + return nil, err + } + return s, nil +} + +func (srv *Service) NewSOAPClient() *soap.SOAPClient { + return soap.NewSOAPClient(srv.ControlURL.URL) +} + +// URLField is a URL that is part of a device description. +type URLField struct { + URL url.URL `xml:"-"` + Ok bool `xml:"-"` + Str string `xml:",chardata"` +} + +func (uf *URLField) SetURLBase(urlBase *url.URL) { + refUrl, err := url.Parse(uf.Str) + if err != nil { + uf.URL = url.URL{} + uf.Ok = false + return + } + + uf.URL = *urlBase.ResolveReference(refUrl) + uf.Ok = true +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/example/example.go b/Godeps/_workspace/src/github.com/huin/goupnp/example/example.go new file mode 100644 index 000000000..df7420226 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/example/example.go @@ -0,0 +1,6 @@ +// Serves as examples of using the goupnp library. +// +// To run examples and see the output for your local network, run the following +// command (specifically including the -v flag): +// go test -v github.com/huin/goupnp/example +package example diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/example/example_test.go b/Godeps/_workspace/src/github.com/huin/goupnp/example/example_test.go new file mode 100644 index 000000000..1f3667df7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/example/example_test.go @@ -0,0 +1,62 @@ +package example_test + +import ( + "fmt" + "os" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/dcps/internetgateway1" +) + +// Use discovered WANPPPConnection1 services to find external IP addresses. +func Example_WANPPPConnection1_GetExternalIPAddress() { + clients, errors, err := internetgateway1.NewWANPPPConnection1Clients() + extIPClients := make([]GetExternalIPAddresser, len(clients)) + for i, client := range clients { + extIPClients[i] = client + } + DisplayExternalIPResults(extIPClients, errors, err) + // Output: +} + +// Use discovered WANIPConnection services to find external IP addresses. +func Example_WANIPConnection_GetExternalIPAddress() { + clients, errors, err := internetgateway1.NewWANIPConnection1Clients() + extIPClients := make([]GetExternalIPAddresser, len(clients)) + for i, client := range clients { + extIPClients[i] = client + } + DisplayExternalIPResults(extIPClients, errors, err) + // Output: +} + +type GetExternalIPAddresser interface { + GetExternalIPAddress() (NewExternalIPAddress string, err error) + GetServiceClient() *goupnp.ServiceClient +} + +func DisplayExternalIPResults(clients []GetExternalIPAddresser, errors []error, err error) { + if err != nil { + fmt.Fprintln(os.Stderr, "Error discovering service with UPnP: ", err) + return + } + + if len(errors) > 0 { + fmt.Fprintf(os.Stderr, "Error discovering %d services:\n", len(errors)) + for _, err := range errors { + fmt.Println(" ", err) + } + } + + fmt.Fprintf(os.Stderr, "Successfully discovered %d services:\n", len(clients)) + for _, client := range clients { + device := &client.GetServiceClient().RootDevice.Device + + fmt.Fprintln(os.Stderr, " Device:", device.FriendlyName) + if addr, err := client.GetExternalIPAddress(); err != nil { + fmt.Fprintf(os.Stderr, " Failed to get external IP address: %v\n", err) + } else { + fmt.Fprintf(os.Stderr, " External IP address: %v\n", addr) + } + } +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go b/Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go new file mode 100644 index 000000000..0ac1d4ff3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go @@ -0,0 +1,539 @@ +// +build gotask + +package gotasks + +import ( + "archive/zip" + "bytes" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "path" + "path/filepath" + "regexp" + "strings" + "text/template" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/scpd" + "github.com/huin/goutil/codegen" + "github.com/jingweno/gotask/tasking" +) + +var ( + deviceURNPrefix = "urn:schemas-upnp-org:device:" + serviceURNPrefix = "urn:schemas-upnp-org:service:" +) + +// NAME +// specgen - generates Go code from the UPnP specification files. +// +// DESCRIPTION +// The specification is available for download from: +// +// OPTIONS +// -s, --spec_filename= +// Path to the specification file, available from http://upnp.org/resources/upnpresources.zip +// -o, --out_dir= +// Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps +// --nogofmt +// Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt. +func TaskSpecgen(t *tasking.T) { + specFilename := t.Flags.String("spec-filename") + if specFilename == "" { + specFilename = t.Flags.String("s") + } + if specFilename == "" { + t.Fatal("--spec_filename is required") + } + outDir := t.Flags.String("out-dir") + if outDir == "" { + outDir = t.Flags.String("o") + } + if outDir == "" { + log.Fatal("--out_dir is required") + } + useGofmt := !t.Flags.Bool("nogofmt") + + specArchive, err := openZipfile(specFilename) + if err != nil { + t.Fatalf("Error opening spec file: %v", err) + } + defer specArchive.Close() + + dcpCol := newDcpsCollection() + for _, f := range globFiles("standardizeddcps/*/*.zip", specArchive.Reader) { + dirName := strings.TrimPrefix(f.Name, "standardizeddcps/") + slashIndex := strings.Index(dirName, "/") + if slashIndex == -1 { + // Should not happen. + t.Logf("Could not find / in %q", dirName) + return + } + dirName = dirName[:slashIndex] + + dcp := dcpCol.dcpForDir(dirName) + if dcp == nil { + t.Logf("No alias defined for directory %q: skipping %s\n", dirName, f.Name) + continue + } else { + t.Logf("Alias found for directory %q: processing %s\n", dirName, f.Name) + } + + dcp.processZipFile(f) + } + + for _, dcp := range dcpCol.dcpByAlias { + if err := dcp.writePackage(outDir, useGofmt); err != nil { + log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err) + } + } +} + +// DCP contains extra metadata to use when generating DCP source files. +type DCPMetadata struct { + Name string // What to name the Go DCP package. + OfficialName string // Official name for the DCP. + DocURL string // Optional - URL for futher documentation about the DCP. +} + +var dcpMetadataByDir = map[string]DCPMetadata{ + "Internet Gateway_1": { + Name: "internetgateway1", + OfficialName: "Internet Gateway Device v1", + DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf", + }, + "Internet Gateway_2": { + Name: "internetgateway2", + OfficialName: "Internet Gateway Device v2", + DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf", + }, +} + +type dcpCollection struct { + dcpByAlias map[string]*DCP +} + +func newDcpsCollection() *dcpCollection { + c := &dcpCollection{ + dcpByAlias: make(map[string]*DCP), + } + for _, metadata := range dcpMetadataByDir { + c.dcpByAlias[metadata.Name] = newDCP(metadata) + } + return c +} + +func (c *dcpCollection) dcpForDir(dirName string) *DCP { + metadata, ok := dcpMetadataByDir[dirName] + if !ok { + return nil + } + return c.dcpByAlias[metadata.Name] +} + +// DCP collects together information about a UPnP Device Control Protocol. +type DCP struct { + Metadata DCPMetadata + DeviceTypes map[string]*URNParts + ServiceTypes map[string]*URNParts + Services []SCPDWithURN +} + +func newDCP(metadata DCPMetadata) *DCP { + return &DCP{ + Metadata: metadata, + DeviceTypes: make(map[string]*URNParts), + ServiceTypes: make(map[string]*URNParts), + } +} + +func (dcp *DCP) processZipFile(file *zip.File) { + archive, err := openChildZip(file) + if err != nil { + log.Println("Error reading child zip file:", err) + return + } + for _, deviceFile := range globFiles("*/device/*.xml", archive) { + dcp.processDeviceFile(deviceFile) + } + for _, scpdFile := range globFiles("*/service/*.xml", archive) { + dcp.processSCPDFile(scpdFile) + } +} + +func (dcp *DCP) processDeviceFile(file *zip.File) { + var device goupnp.Device + if err := unmarshalXmlFile(file, &device); err != nil { + log.Printf("Error decoding device XML from file %q: %v", file.Name, err) + return + } + device.VisitDevices(func(d *goupnp.Device) { + t := strings.TrimSpace(d.DeviceType) + if t != "" { + u, err := extractURNParts(t, deviceURNPrefix) + if err != nil { + log.Println(err) + return + } + dcp.DeviceTypes[t] = u + } + }) + device.VisitServices(func(s *goupnp.Service) { + u, err := extractURNParts(s.ServiceType, serviceURNPrefix) + if err != nil { + log.Println(err) + return + } + dcp.ServiceTypes[s.ServiceType] = u + }) +} + +func (dcp *DCP) writePackage(outDir string, useGofmt bool) error { + packageDirname := filepath.Join(outDir, dcp.Metadata.Name) + err := os.MkdirAll(packageDirname, os.ModePerm) + if err != nil && !os.IsExist(err) { + return err + } + packageFilename := filepath.Join(packageDirname, dcp.Metadata.Name+".go") + packageFile, err := os.Create(packageFilename) + if err != nil { + return err + } + var output io.WriteCloser = packageFile + if useGofmt { + if output, err = codegen.NewGofmtWriteCloser(output); err != nil { + packageFile.Close() + return err + } + } + if err = packageTmpl.Execute(output, dcp); err != nil { + output.Close() + return err + } + return output.Close() +} + +func (dcp *DCP) processSCPDFile(file *zip.File) { + scpd := new(scpd.SCPD) + if err := unmarshalXmlFile(file, scpd); err != nil { + log.Printf("Error decoding SCPD XML from file %q: %v", file.Name, err) + return + } + scpd.Clean() + urnParts, err := urnPartsFromSCPDFilename(file.Name) + if err != nil { + log.Printf("Could not recognize SCPD filename %q: %v", file.Name, err) + return + } + dcp.Services = append(dcp.Services, SCPDWithURN{ + URNParts: urnParts, + SCPD: scpd, + }) +} + +type SCPDWithURN struct { + *URNParts + SCPD *scpd.SCPD +} + +func (s *SCPDWithURN) WrapArgument(arg scpd.Argument) (*argumentWrapper, error) { + relVar := s.SCPD.GetStateVariable(arg.RelatedStateVariable) + if relVar == nil { + return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name) + } + cnv, ok := typeConvs[relVar.DataType.Name] + if !ok { + return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name) + } + return &argumentWrapper{ + Argument: arg, + relVar: relVar, + conv: cnv, + }, nil +} + +type argumentWrapper struct { + scpd.Argument + relVar *scpd.StateVariable + conv conv +} + +func (arg *argumentWrapper) AsParameter() string { + return fmt.Sprintf("%s %s", arg.Name, arg.conv.ExtType) +} + +func (arg *argumentWrapper) Document() string { + relVar := arg.relVar + if rng := relVar.AllowedValueRange; rng != nil { + var parts []string + if rng.Minimum != "" { + parts = append(parts, fmt.Sprintf("minimum=%s", rng.Minimum)) + } + if rng.Maximum != "" { + parts = append(parts, fmt.Sprintf("maximum=%s", rng.Maximum)) + } + if rng.Step != "" { + parts = append(parts, fmt.Sprintf("step=%s", rng.Step)) + } + return "allowed value range: " + strings.Join(parts, ", ") + } + if len(relVar.AllowedValues) != 0 { + return "allowed values: " + strings.Join(relVar.AllowedValues, ", ") + } + return "" +} + +func (arg *argumentWrapper) Marshal() string { + return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name) +} + +func (arg *argumentWrapper) Unmarshal(objVar string) string { + return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name) +} + +type conv struct { + FuncSuffix string + ExtType string +} + +// typeConvs maps from a SOAP type (e.g "fixed.14.4") to the function name +// suffix inside the soap module (e.g "Fixed14_4") and the Go type. +var typeConvs = map[string]conv{ + "ui1": conv{"Ui1", "uint8"}, + "ui2": conv{"Ui2", "uint16"}, + "ui4": conv{"Ui4", "uint32"}, + "i1": conv{"I1", "int8"}, + "i2": conv{"I2", "int16"}, + "i4": conv{"I4", "int32"}, + "int": conv{"Int", "int64"}, + "r4": conv{"R4", "float32"}, + "r8": conv{"R8", "float64"}, + "number": conv{"R8", "float64"}, // Alias for r8. + "fixed.14.4": conv{"Fixed14_4", "float64"}, + "float": conv{"R8", "float64"}, + "char": conv{"Char", "rune"}, + "string": conv{"String", "string"}, + "date": conv{"Date", "time.Time"}, + "dateTime": conv{"DateTime", "time.Time"}, + "dateTime.tz": conv{"DateTimeTz", "time.Time"}, + "time": conv{"TimeOfDay", "soap.TimeOfDay"}, + "time.tz": conv{"TimeOfDayTz", "soap.TimeOfDay"}, + "boolean": conv{"Boolean", "bool"}, + "bin.base64": conv{"BinBase64", "[]byte"}, + "bin.hex": conv{"BinHex", "[]byte"}, +} + +type closeableZipReader struct { + io.Closer + *zip.Reader +} + +func openZipfile(filename string) (*closeableZipReader, error) { + file, err := os.Open(filename) + if err != nil { + return nil, err + } + fi, err := file.Stat() + if err != nil { + return nil, err + } + archive, err := zip.NewReader(file, fi.Size()) + if err != nil { + return nil, err + } + return &closeableZipReader{ + Closer: file, + Reader: archive, + }, nil +} + +// openChildZip opens a zip file within another zip file. +func openChildZip(file *zip.File) (*zip.Reader, error) { + zipFile, err := file.Open() + if err != nil { + return nil, err + } + defer zipFile.Close() + + zipBytes, err := ioutil.ReadAll(zipFile) + if err != nil { + return nil, err + } + + return zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes))) +} + +func globFiles(pattern string, archive *zip.Reader) []*zip.File { + var files []*zip.File + for _, f := range archive.File { + if matched, err := path.Match(pattern, f.Name); err != nil { + // This shouldn't happen - all patterns are hard-coded, errors in them + // are a programming error. + panic(err) + } else if matched { + files = append(files, f) + } + } + return files +} + +func unmarshalXmlFile(file *zip.File, data interface{}) error { + r, err := file.Open() + if err != nil { + return err + } + decoder := xml.NewDecoder(r) + r.Close() + return decoder.Decode(data) +} + +type URNParts struct { + URN string + Name string + Version string +} + +func (u *URNParts) Const() string { + return fmt.Sprintf("URN_%s_%s", u.Name, u.Version) +} + +// extractURNParts extracts the name and version from a URN string. +func extractURNParts(urn, expectedPrefix string) (*URNParts, error) { + if !strings.HasPrefix(urn, expectedPrefix) { + return nil, fmt.Errorf("%q does not have expected prefix %q", urn, expectedPrefix) + } + parts := strings.SplitN(strings.TrimPrefix(urn, expectedPrefix), ":", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("%q does not have a name and version", urn) + } + name, version := parts[0], parts[1] + return &URNParts{urn, name, version}, nil +} + +var scpdFilenameRe = regexp.MustCompile( + `.*/([a-zA-Z0-9]+)([0-9]+)\.xml`) + +func urnPartsFromSCPDFilename(filename string) (*URNParts, error) { + parts := scpdFilenameRe.FindStringSubmatch(filename) + if len(parts) != 3 { + return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename) + } + name, version := parts[1], parts[2] + return &URNParts{ + URN: serviceURNPrefix + name + ":" + version, + Name: name, + Version: version, + }, nil +} + +var packageTmpl = template.Must(template.New("package").Parse(`{{$name := .Metadata.Name}} +// Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}. +// {{if .Metadata.DocURL}} +// This DCP is documented in detail at: {{.Metadata.DocURL}}{{end}} +// +// Typically, use one of the New* functions to discover services on the local +// network. +package {{$name}} + +// Generated file - do not edit by hand. See README.md + + +import ( + "time" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/soap" +) + +// Hack to avoid Go complaining if time isn't used. +var _ time.Time + +// Device URNs: +const ({{range .DeviceTypes}} + {{.Const}} = "{{.URN}}"{{end}} +) + +// Service URNs: +const ({{range .ServiceTypes}} + {{.Const}} = "{{.URN}}"{{end}} +) + +{{range .Services}} +{{$srv := .}} +{{$srvIdent := printf "%s%s" .Name .Version}} + +// {{$srvIdent}} is a client for UPnP SOAP service with URN "{{.URN}}". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type {{$srvIdent}} struct { + goupnp.ServiceClient +} + +// New{{$srvIdent}}Clients discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClients({{$srv.Const}}); err != nil { + return + } + clients = make([]*{{$srvIdent}}, len(genericClients)) + for i := range genericClients { + clients[i] = &{{$srvIdent}}{genericClients[i]} + } + return +} + +{{range .SCPD.Actions}}{{/* loops over *SCPDWithURN values */}} + +{{$inargs := .InputArguments}}{{$outargs := .OutputArguments}} +// {{if $inargs}}Arguments:{{range $inargs}}{{$argWrap := $srv.WrapArgument .}} +// +// * {{.Name}}: {{$argWrap.Document}}{{end}}{{end}} +// +// {{if $outargs}}Return values:{{range $outargs}}{{$argWrap := $srv.WrapArgument .}} +// +// * {{.Name}}: {{$argWrap.Document}}{{end}}{{end}} +func (client *{{$srvIdent}}) {{.Name}}({{range $inargs}}{{/* +*/}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}}{{/* +*/}}) ({{range $outargs}}{{/* +*/}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}} err error) { + // Request structure. + request := {{if $inargs}}&{{template "argstruct" $inargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} + // BEGIN Marshal arguments into request. +{{range $inargs}}{{$argWrap := $srv.WrapArgument .}} + if request.{{.Name}}, err = {{$argWrap.Marshal}}; err != nil { + return + }{{end}} + // END Marshal arguments into request. + + // Response structure. + response := {{if $outargs}}&{{template "argstruct" $outargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. +{{range $outargs}}{{$argWrap := $srv.WrapArgument .}} + if {{.Name}}, err = {{$argWrap.Unmarshal "response"}}; err != nil { + return + }{{end}} + // END Unmarshal arguments from response. + return +} +{{end}}{{/* range .SCPD.Actions */}} +{{end}}{{/* range .Services */}} + +{{define "argstruct"}}struct {{"{"}}{{range .}} +{{.Name}} string +{{end}}{{"}"}}{{end}} +`)) diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go b/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go new file mode 100644 index 000000000..120b92444 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go @@ -0,0 +1,109 @@ +// goupnp is an implementation of a client for various UPnP services. +// +// For most uses, it is recommended to use the code-generated packages under +// github.com/huin/goupnp/dcps. Example use is shown at +// http://godoc.org/github.com/huin/goupnp/example +// +// A commonly used client is internetgateway1.WANPPPConnection1: +// http://godoc.org/github.com/huin/goupnp/dcps/internetgateway1#WANPPPConnection1 +// +// Currently only a couple of schemas have code generated for them from the +// UPnP example XML specifications. Not all methods will work on these clients, +// because the generated stubs contain the full set of specified methods from +// the XML specifications, and the discovered services will likely support a +// subset of those methods. +package goupnp + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + + "github.com/huin/goupnp/httpu" + "github.com/huin/goupnp/ssdp" +) + +// ContextError is an error that wraps an error with some context information. +type ContextError struct { + Context string + Err error +} + +func (err ContextError) Error() string { + return fmt.Sprintf("%s: %v", err.Context, err.Err) +} + +// MaybeRootDevice contains either a RootDevice or an error. +type MaybeRootDevice struct { + Root *RootDevice + Err error +} + +// DiscoverDevices attempts to find targets of the given type. This is +// typically the entry-point for this package. searchTarget is typically a URN +// in the form "urn:schemas-upnp-org:device:..." or +// "urn:schemas-upnp-org:service:...". A single error is returned for errors +// while attempting to send the query. An error or RootDevice is returned for +// each discovered RootDevice. +func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) { + httpu, err := httpu.NewHTTPUClient() + if err != nil { + return nil, err + } + defer httpu.Close() + responses, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 2, 3) + if err != nil { + return nil, err + } + + results := make([]MaybeRootDevice, len(responses)) + for i, response := range responses { + maybe := &results[i] + loc, err := response.Location() + if err != nil { + + maybe.Err = ContextError{"unexpected bad location from search", err} + continue + } + locStr := loc.String() + root := new(RootDevice) + if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil { + maybe.Err = ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err} + continue + } + var urlBaseStr string + if root.URLBaseStr != "" { + urlBaseStr = root.URLBaseStr + } else { + urlBaseStr = locStr + } + urlBase, err := url.Parse(urlBaseStr) + if err != nil { + maybe.Err = ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err} + continue + } + root.SetURLBase(urlBase) + maybe.Root = root + } + + return results, nil +} + +func requestXml(url string, defaultSpace string, doc interface{}) error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("goupnp: got response status %s from %q", + resp.Status, url) + } + + decoder := xml.NewDecoder(resp.Body) + decoder.DefaultSpace = defaultSpace + + return decoder.Decode(doc) +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go b/Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go new file mode 100644 index 000000000..862c3def4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go @@ -0,0 +1,117 @@ +package httpu + +import ( + "bufio" + "bytes" + "fmt" + "log" + "net" + "net/http" + "sync" + "time" +) + +// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical +// function is for HTTPMU, and particularly SSDP. +type HTTPUClient struct { + connLock sync.Mutex // Protects use of conn. + conn net.PacketConn +} + +// NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the +// purpose. +func NewHTTPUClient() (*HTTPUClient, error) { + conn, err := net.ListenPacket("udp", ":0") + if err != nil { + return nil, err + } + return &HTTPUClient{conn: conn}, nil +} + +// Close shuts down the client. The client will no longer be useful following +// this. +func (httpu *HTTPUClient) Close() error { + httpu.connLock.Lock() + defer httpu.connLock.Unlock() + return httpu.conn.Close() +} + +// Do performs a request. The timeout is how long to wait for before returning +// the responses that were received. An error is only returned for failing to +// send the request. Failures in receipt simply do not add to the resulting +// responses. +// +// Note that at present only one concurrent connection will happen per +// HTTPUClient. +func (httpu *HTTPUClient) Do(req *http.Request, timeout time.Duration, numSends int) ([]*http.Response, error) { + httpu.connLock.Lock() + defer httpu.connLock.Unlock() + + // Create the request. This is a subset of what http.Request.Write does + // deliberately to avoid creating extra fields which may confuse some + // devices. + var requestBuf bytes.Buffer + method := req.Method + if method == "" { + method = "GET" + } + if _, err := fmt.Fprintf(&requestBuf, "%s %s HTTP/1.1\r\n", method, req.URL.RequestURI()); err != nil { + return nil, err + } + if err := req.Header.Write(&requestBuf); err != nil { + return nil, err + } + if _, err := requestBuf.Write([]byte{'\r', '\n'}); err != nil { + return nil, err + } + + destAddr, err := net.ResolveUDPAddr("udp", req.Host) + if err != nil { + return nil, err + } + if err = httpu.conn.SetDeadline(time.Now().Add(timeout)); err != nil { + return nil, err + } + + // Send request. + for i := 0; i < numSends; i++ { + if n, err := httpu.conn.WriteTo(requestBuf.Bytes(), destAddr); err != nil { + return nil, err + } else if n < len(requestBuf.Bytes()) { + return nil, fmt.Errorf("httpu: wrote %d bytes rather than full %d in request", + n, len(requestBuf.Bytes())) + } + time.Sleep(5 * time.Millisecond) + } + + // Await responses until timeout. + var responses []*http.Response + responseBytes := make([]byte, 2048) + for { + // 2048 bytes should be sufficient for most networks. + n, _, err := httpu.conn.ReadFrom(responseBytes) + if err != nil { + if err, ok := err.(net.Error); ok { + if err.Timeout() { + break + } + if err.Temporary() { + // Sleep in case this is a persistent error to avoid pegging CPU until deadline. + time.Sleep(10 * time.Millisecond) + continue + } + } + return nil, err + } + + // Parse response. + response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(responseBytes[:n])), req) + if err != nil { + log.Print("httpu: error while parsing response: %v", err) + continue + } + + responses = append(responses, response) + } + return responses, err +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/httpu/serve.go b/Godeps/_workspace/src/github.com/huin/goupnp/httpu/serve.go new file mode 100644 index 000000000..9f67af85b --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/httpu/serve.go @@ -0,0 +1,108 @@ +package httpu + +import ( + "bufio" + "bytes" + "log" + "net" + "net/http" + "regexp" +) + +const ( + DefaultMaxMessageBytes = 2048 +) + +var ( + trailingWhitespaceRx = regexp.MustCompile(" +\r\n") + crlf = []byte("\r\n") +) + +// Handler is the interface by which received HTTPU messages are passed to +// handling code. +type Handler interface { + // ServeMessage is called for each HTTPU message received. peerAddr contains + // the address that the message was received from. + ServeMessage(r *http.Request) +} + +// HandlerFunc is a function-to-Handler adapter. +type HandlerFunc func(r *http.Request) + +func (f HandlerFunc) ServeMessage(r *http.Request) { + f(r) +} + +// A Server defines parameters for running an HTTPU server. +type Server struct { + Addr string // UDP address to listen on + Multicast bool // Should listen for multicast? + Interface *net.Interface // Network interface to listen on for multicast, nil for default multicast interface + Handler Handler // handler to invoke + MaxMessageBytes int // maximum number of bytes to read from a packet, DefaultMaxMessageBytes if 0 +} + +// ListenAndServe listens on the UDP network address srv.Addr. If srv.Multicast +// is true, then a multicast UDP listener will be used on srv.Interface (or +// default interface if nil). +func (srv *Server) ListenAndServe() error { + var err error + + var addr *net.UDPAddr + if addr, err = net.ResolveUDPAddr("udp", srv.Addr); err != nil { + log.Fatal(err) + } + + var conn net.PacketConn + if srv.Multicast { + if conn, err = net.ListenMulticastUDP("udp", srv.Interface, addr); err != nil { + return err + } + } else { + if conn, err = net.ListenUDP("udp", addr); err != nil { + return err + } + } + + return srv.Serve(conn) +} + +// Serve messages received on the given packet listener to the srv.Handler. +func (srv *Server) Serve(l net.PacketConn) error { + maxMessageBytes := DefaultMaxMessageBytes + if srv.MaxMessageBytes != 0 { + maxMessageBytes = srv.MaxMessageBytes + } + for { + buf := make([]byte, maxMessageBytes) + n, peerAddr, err := l.ReadFrom(buf) + if err != nil { + return err + } + buf = buf[:n] + + go func(buf []byte, peerAddr net.Addr) { + // At least one router's UPnP implementation has added a trailing space + // after "HTTP/1.1" - trim it. + buf = trailingWhitespaceRx.ReplaceAllLiteral(buf, crlf) + + req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(buf))) + if err != nil { + log.Printf("httpu: Failed to parse request: %v", err) + return + } + req.RemoteAddr = peerAddr.String() + srv.Handler.ServeMessage(req) + // No need to call req.Body.Close - underlying reader is bytes.Buffer. + }(buf, peerAddr) + } +} + +// Serve messages received on the given packet listener to the given handler. +func Serve(l net.PacketConn, handler Handler) error { + srv := Server{ + Handler: handler, + MaxMessageBytes: DefaultMaxMessageBytes, + } + return srv.Serve(l) +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/scpd/scpd.go b/Godeps/_workspace/src/github.com/huin/goupnp/scpd/scpd.go new file mode 100644 index 000000000..c9d2e69e8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/scpd/scpd.go @@ -0,0 +1,167 @@ +package scpd + +import ( + "encoding/xml" + "strings" +) + +const ( + SCPDXMLNamespace = "urn:schemas-upnp-org:service-1-0" +) + +func cleanWhitespace(s *string) { + *s = strings.TrimSpace(*s) +} + +// SCPD is the service description as described by section 2.5 "Service +// description" in +// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf +type SCPD struct { + XMLName xml.Name `xml:"scpd"` + ConfigId string `xml:"configId,attr"` + SpecVersion SpecVersion `xml:"specVersion"` + Actions []Action `xml:"actionList>action"` + StateVariables []StateVariable `xml:"serviceStateTable>stateVariable"` +} + +// Clean attempts to remove stray whitespace etc. in the structure. It seems +// unfortunately common for stray whitespace to be present in SCPD documents, +// this method attempts to make it easy to clean them out. +func (scpd *SCPD) Clean() { + cleanWhitespace(&scpd.ConfigId) + for i := range scpd.Actions { + scpd.Actions[i].clean() + } + for i := range scpd.StateVariables { + scpd.StateVariables[i].clean() + } +} + +func (scpd *SCPD) GetStateVariable(variable string) *StateVariable { + for i := range scpd.StateVariables { + v := &scpd.StateVariables[i] + if v.Name == variable { + return v + } + } + return nil +} + +func (scpd *SCPD) GetAction(action string) *Action { + for i := range scpd.Actions { + a := &scpd.Actions[i] + if a.Name == action { + return a + } + } + return nil +} + +// SpecVersion is part of a SCPD document, describes the version of the +// specification that the data adheres to. +type SpecVersion struct { + Major int32 `xml:"major"` + Minor int32 `xml:"minor"` +} + +type Action struct { + Name string `xml:"name"` + Arguments []Argument `xml:"argumentList>argument"` +} + +func (action *Action) clean() { + cleanWhitespace(&action.Name) + for i := range action.Arguments { + action.Arguments[i].clean() + } +} + +func (action *Action) InputArguments() []*Argument { + var result []*Argument + for i := range action.Arguments { + arg := &action.Arguments[i] + if arg.IsInput() { + result = append(result, arg) + } + } + return result +} + +func (action *Action) OutputArguments() []*Argument { + var result []*Argument + for i := range action.Arguments { + arg := &action.Arguments[i] + if arg.IsOutput() { + result = append(result, arg) + } + } + return result +} + +type Argument struct { + Name string `xml:"name"` + Direction string `xml:"direction"` // in|out + RelatedStateVariable string `xml:"relatedStateVariable"` // ? + Retval string `xml:"retval"` // ? +} + +func (arg *Argument) clean() { + cleanWhitespace(&arg.Name) + cleanWhitespace(&arg.Direction) + cleanWhitespace(&arg.RelatedStateVariable) + cleanWhitespace(&arg.Retval) +} + +func (arg *Argument) IsInput() bool { + return arg.Direction == "in" +} + +func (arg *Argument) IsOutput() bool { + return arg.Direction == "out" +} + +type StateVariable struct { + Name string `xml:"name"` + SendEvents string `xml:"sendEvents,attr"` // yes|no + Multicast string `xml:"multicast,attr"` // yes|no + DataType DataType `xml:"dataType"` + DefaultValue string `xml:"defaultValue"` + AllowedValueRange *AllowedValueRange `xml:"allowedValueRange"` + AllowedValues []string `xml:"allowedValueList>allowedValue"` +} + +func (v *StateVariable) clean() { + cleanWhitespace(&v.Name) + cleanWhitespace(&v.SendEvents) + cleanWhitespace(&v.Multicast) + v.DataType.clean() + cleanWhitespace(&v.DefaultValue) + if v.AllowedValueRange != nil { + v.AllowedValueRange.clean() + } + for i := range v.AllowedValues { + cleanWhitespace(&v.AllowedValues[i]) + } +} + +type AllowedValueRange struct { + Minimum string `xml:"minimum"` + Maximum string `xml:"maximum"` + Step string `xml:"step"` +} + +func (r *AllowedValueRange) clean() { + cleanWhitespace(&r.Minimum) + cleanWhitespace(&r.Maximum) + cleanWhitespace(&r.Step) +} + +type DataType struct { + Name string `xml:",chardata"` + Type string `xml:"type,attr"` +} + +func (dt *DataType) clean() { + cleanWhitespace(&dt.Name) + cleanWhitespace(&dt.Type) +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/service_client.go b/Godeps/_workspace/src/github.com/huin/goupnp/service_client.go new file mode 100644 index 000000000..c0d16ce2a --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/service_client.go @@ -0,0 +1,56 @@ +package goupnp + +import ( + "fmt" + "github.com/huin/goupnp/soap" +) + +// ServiceClient is a SOAP client, root device and the service for the SOAP +// client rolled into one value. The root device and service are intended to be +// informational. +type ServiceClient struct { + SOAPClient *soap.SOAPClient + RootDevice *RootDevice + Service *Service +} + +func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) { + var maybeRootDevices []MaybeRootDevice + if maybeRootDevices, err = DiscoverDevices(searchTarget); err != nil { + return + } + + clients = make([]ServiceClient, 0, len(maybeRootDevices)) + + for _, maybeRootDevice := range maybeRootDevices { + if maybeRootDevice.Err != nil { + errors = append(errors, maybeRootDevice.Err) + continue + } + + device := &maybeRootDevice.Root.Device + srvs := device.FindService(searchTarget) + if len(srvs) == 0 { + errors = append(errors, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)", + searchTarget, device.FriendlyName, device.UDN)) + continue + } + + for _, srv := range srvs { + clients = append(clients, ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: maybeRootDevice.Root, + Service: srv, + }) + } + } + + return +} + +// GetServiceClient returns the ServiceClient itself. This is provided so that the +// service client attributes can be accessed via an interface method on a +// wrapping type. +func (client *ServiceClient) GetServiceClient() *ServiceClient { + return client +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go b/Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go new file mode 100644 index 000000000..815610734 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go @@ -0,0 +1,157 @@ +// Definition for the SOAP structure required for UPnP's SOAP usage. + +package soap + +import ( + "bytes" + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "reflect" +) + +const ( + soapEncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" + soapPrefix = xml.Header + `` + soapSuffix = `` +) + +type SOAPClient struct { + EndpointURL url.URL + HTTPClient http.Client +} + +func NewSOAPClient(endpointURL url.URL) *SOAPClient { + return &SOAPClient{ + EndpointURL: endpointURL, + } +} + +// PerformSOAPAction makes a SOAP request, with the given action. +// inAction and outAction must both be pointers to structs with string fields +// only. +func (client *SOAPClient) PerformAction(actionNamespace, actionName string, inAction interface{}, outAction interface{}) error { + requestBytes, err := encodeRequestAction(actionNamespace, actionName, inAction) + if err != nil { + return err + } + + response, err := client.HTTPClient.Do(&http.Request{ + Method: "POST", + URL: &client.EndpointURL, + Header: http.Header{ + "SOAPACTION": []string{`"` + actionNamespace + "#" + actionName + `"`}, + "CONTENT-TYPE": []string{"text/xml; charset=\"utf-8\""}, + }, + Body: ioutil.NopCloser(bytes.NewBuffer(requestBytes)), + // Set ContentLength to avoid chunked encoding - some servers might not support it. + ContentLength: int64(len(requestBytes)), + }) + if err != nil { + return fmt.Errorf("goupnp: error performing SOAP HTTP request: %v", err) + } + defer response.Body.Close() + if response.StatusCode != 200 { + return fmt.Errorf("goupnp: SOAP request got HTTP %s", response.Status) + } + + responseEnv := newSOAPEnvelope() + decoder := xml.NewDecoder(response.Body) + if err := decoder.Decode(responseEnv); err != nil { + return fmt.Errorf("goupnp: error decoding response body: %v", err) + } + + if responseEnv.Body.Fault != nil { + return responseEnv.Body.Fault + } + + if outAction != nil { + if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { + return fmt.Errorf("goupnp: error unmarshalling out action: %v, %v", err, responseEnv.Body.RawAction) + } + } + + return nil +} + +// newSOAPAction creates a soapEnvelope with the given action and arguments. +func newSOAPEnvelope() *soapEnvelope { + return &soapEnvelope{ + EncodingStyle: soapEncodingStyle, + } +} + +// encodeRequestAction is a hacky way to create an encoded SOAP envelope +// containing the given action. Experiments with one router have shown that it +// 500s for requests where the outer default xmlns is set to the SOAP +// namespace, and then reassigning the default namespace within that to the +// service namespace. Hand-coding the outer XML to work-around this. +func encodeRequestAction(actionNamespace, actionName string, inAction interface{}) ([]byte, error) { + requestBuf := new(bytes.Buffer) + requestBuf.WriteString(soapPrefix) + requestBuf.WriteString(``) + if inAction != nil { + if err := encodeRequestArgs(requestBuf, inAction); err != nil { + return nil, err + } + } + requestBuf.WriteString(``) + requestBuf.WriteString(soapSuffix) + return requestBuf.Bytes(), nil +} + +func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error { + in := reflect.Indirect(reflect.ValueOf(inAction)) + if in.Kind() != reflect.Struct { + return fmt.Errorf("goupnp: SOAP inAction is not a struct but of type %v", in.Type()) + } + enc := xml.NewEncoder(w) + nFields := in.NumField() + inType := in.Type() + for i := 0; i < nFields; i++ { + field := inType.Field(i) + argName := field.Name + if nameOverride := field.Tag.Get("soap"); nameOverride != "" { + argName = nameOverride + } + value := in.Field(i) + if value.Kind() != reflect.String { + return fmt.Errorf("goupnp: SOAP arg %q is not of type string, but of type %v", argName, value.Type()) + } + if err := enc.EncodeElement(value.Interface(), xml.StartElement{xml.Name{"", argName}, nil}); err != nil { + return fmt.Errorf("goupnp: error encoding SOAP arg %q: %v", argName, err) + } + } + enc.Flush() + return nil +} + +type soapEnvelope struct { + XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + EncodingStyle string `xml:"http://schemas.xmlsoap.org/soap/envelope/ encodingStyle,attr"` + Body soapBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` +} + +type soapBody struct { + Fault *SOAPFaultError `xml:"Fault"` + RawAction []byte `xml:",innerxml"` +} + +// SOAPFaultError implements error, and contains SOAP fault information. +type SOAPFaultError struct { + FaultCode string `xml:"faultcode"` + FaultString string `xml:"faultstring"` + Detail string `xml:"detail"` +} + +func (err *SOAPFaultError) Error() string { + return fmt.Sprintf("SOAP fault: %s", err.FaultString) +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/soap/soap_test.go b/Godeps/_workspace/src/github.com/huin/goupnp/soap/soap_test.go new file mode 100644 index 000000000..75dbbdbf1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/soap/soap_test.go @@ -0,0 +1,85 @@ +package soap + +import ( + "bytes" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "testing" +) + +type capturingRoundTripper struct { + err error + resp *http.Response + capturedReq *http.Request +} + +func (rt *capturingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + rt.capturedReq = req + return rt.resp, rt.err +} + +func TestActionInputs(t *testing.T) { + url, err := url.Parse("http://example.com/soap") + if err != nil { + t.Fatal(err) + } + rt := &capturingRoundTripper{ + err: nil, + resp: &http.Response{ + StatusCode: 200, + Body: ioutil.NopCloser(bytes.NewBufferString(` + + + + valueA + valueB + + + + `)), + }, + } + client := SOAPClient{ + EndpointURL: *url, + HTTPClient: http.Client{ + Transport: rt, + }, + } + + type In struct { + Foo string + Bar string `soap:"bar"` + } + type Out struct { + A string + B string + } + in := In{"foo", "bar"} + gotOut := Out{} + err = client.PerformAction("mynamespace", "myaction", &in, &gotOut) + if err != nil { + t.Fatal(err) + } + + wantBody := (soapPrefix + + `` + + `foo` + + `bar` + + `` + + soapSuffix) + body, err := ioutil.ReadAll(rt.capturedReq.Body) + if err != nil { + t.Fatal(err) + } + gotBody := string(body) + if wantBody != gotBody { + t.Errorf("Bad request body\nwant: %q\n got: %q", wantBody, gotBody) + } + + wantOut := Out{"valueA", "valueB"} + if !reflect.DeepEqual(wantOut, gotOut) { + t.Errorf("Bad output\nwant: %+v\n got: %+v", wantOut, gotOut) + } +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/soap/types.go b/Godeps/_workspace/src/github.com/huin/goupnp/soap/types.go new file mode 100644 index 000000000..cd16510e3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/soap/types.go @@ -0,0 +1,508 @@ +package soap + +import ( + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" +) + +var ( + // localLoc acts like time.Local for this package, but is faked out by the + // unit tests to ensure that things stay constant (especially when running + // this test in a place where local time is UTC which might mask bugs). + localLoc = time.Local +) + +func MarshalUi1(v uint8) (string, error) { + return strconv.FormatUint(uint64(v), 10), nil +} + +func UnmarshalUi1(s string) (uint8, error) { + v, err := strconv.ParseUint(s, 10, 8) + return uint8(v), err +} + +func MarshalUi2(v uint16) (string, error) { + return strconv.FormatUint(uint64(v), 10), nil +} + +func UnmarshalUi2(s string) (uint16, error) { + v, err := strconv.ParseUint(s, 10, 16) + return uint16(v), err +} + +func MarshalUi4(v uint32) (string, error) { + return strconv.FormatUint(uint64(v), 10), nil +} + +func UnmarshalUi4(s string) (uint32, error) { + v, err := strconv.ParseUint(s, 10, 32) + return uint32(v), err +} + +func MarshalI1(v int8) (string, error) { + return strconv.FormatInt(int64(v), 10), nil +} + +func UnmarshalI1(s string) (int8, error) { + v, err := strconv.ParseInt(s, 10, 8) + return int8(v), err +} + +func MarshalI2(v int16) (string, error) { + return strconv.FormatInt(int64(v), 10), nil +} + +func UnmarshalI2(s string) (int16, error) { + v, err := strconv.ParseInt(s, 10, 16) + return int16(v), err +} + +func MarshalI4(v int32) (string, error) { + return strconv.FormatInt(int64(v), 10), nil +} + +func UnmarshalI4(s string) (int32, error) { + v, err := strconv.ParseInt(s, 10, 32) + return int32(v), err +} + +func MarshalInt(v int64) (string, error) { + return strconv.FormatInt(v, 10), nil +} + +func UnmarshalInt(s string) (int64, error) { + return strconv.ParseInt(s, 10, 64) +} + +func MarshalR4(v float32) (string, error) { + return strconv.FormatFloat(float64(v), 'G', -1, 32), nil +} + +func UnmarshalR4(s string) (float32, error) { + v, err := strconv.ParseFloat(s, 32) + return float32(v), err +} + +func MarshalR8(v float64) (string, error) { + return strconv.FormatFloat(v, 'G', -1, 64), nil +} + +func UnmarshalR8(s string) (float64, error) { + v, err := strconv.ParseFloat(s, 64) + return float64(v), err +} + +// MarshalFixed14_4 marshals float64 to SOAP "fixed.14.4" type. +func MarshalFixed14_4(v float64) (string, error) { + if v >= 1e14 || v <= -1e14 { + return "", fmt.Errorf("soap fixed14.4: value %v out of bounds", v) + } + return strconv.FormatFloat(v, 'f', 4, 64), nil +} + +// UnmarshalFixed14_4 unmarshals float64 from SOAP "fixed.14.4" type. +func UnmarshalFixed14_4(s string) (float64, error) { + v, err := strconv.ParseFloat(s, 64) + if err != nil { + return 0, err + } + if v >= 1e14 || v <= -1e14 { + return 0, fmt.Errorf("soap fixed14.4: value %q out of bounds", s) + } + return v, nil +} + +// MarshalChar marshals rune to SOAP "char" type. +func MarshalChar(v rune) (string, error) { + if v == 0 { + return "", errors.New("soap char: rune 0 is not allowed") + } + return string(v), nil +} + +// UnmarshalChar unmarshals rune from SOAP "char" type. +func UnmarshalChar(s string) (rune, error) { + if len(s) == 0 { + return 0, errors.New("soap char: got empty string") + } + r, n := utf8.DecodeRune([]byte(s)) + if n != len(s) { + return 0, fmt.Errorf("soap char: value %q is not a single rune", s) + } + return r, nil +} + +func MarshalString(v string) (string, error) { + return v, nil +} + +func UnmarshalString(v string) (string, error) { + return v, nil +} + +func parseInt(s string, err *error) int { + v, parseErr := strconv.ParseInt(s, 10, 64) + if parseErr != nil { + *err = parseErr + } + return int(v) +} + +var dateRegexps = []*regexp.Regexp{ + // yyyy[-mm[-dd]] + regexp.MustCompile(`^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$`), + // yyyy[mm[dd]] + regexp.MustCompile(`^(\d{4})(?:(\d{2})(?:(\d{2}))?)?$`), +} + +func parseDateParts(s string) (year, month, day int, err error) { + var parts []string + for _, re := range dateRegexps { + parts = re.FindStringSubmatch(s) + if parts != nil { + break + } + } + if parts == nil { + err = fmt.Errorf("soap date: value %q is not in a recognized ISO8601 date format", s) + return + } + + year = parseInt(parts[1], &err) + month = 1 + day = 1 + if len(parts[2]) != 0 { + month = parseInt(parts[2], &err) + if len(parts[3]) != 0 { + day = parseInt(parts[3], &err) + } + } + + if err != nil { + err = fmt.Errorf("soap date: %q: %v", s, err) + } + + return +} + +var timeRegexps = []*regexp.Regexp{ + // hh[:mm[:ss]] + regexp.MustCompile(`^(\d{2})(?::(\d{2})(?::(\d{2}))?)?$`), + // hh[mm[ss]] + regexp.MustCompile(`^(\d{2})(?:(\d{2})(?:(\d{2}))?)?$`), +} + +func parseTimeParts(s string) (hour, minute, second int, err error) { + var parts []string + for _, re := range timeRegexps { + parts = re.FindStringSubmatch(s) + if parts != nil { + break + } + } + if parts == nil { + err = fmt.Errorf("soap time: value %q is not in ISO8601 time format", s) + return + } + + hour = parseInt(parts[1], &err) + if len(parts[2]) != 0 { + minute = parseInt(parts[2], &err) + if len(parts[3]) != 0 { + second = parseInt(parts[3], &err) + } + } + + if err != nil { + err = fmt.Errorf("soap time: %q: %v", s, err) + } + + return +} + +// (+|-)hh[[:]mm] +var timezoneRegexp = regexp.MustCompile(`^([+-])(\d{2})(?::?(\d{2}))?$`) + +func parseTimezone(s string) (offset int, err error) { + if s == "Z" { + return 0, nil + } + parts := timezoneRegexp.FindStringSubmatch(s) + if parts == nil { + err = fmt.Errorf("soap timezone: value %q is not in ISO8601 timezone format", s) + return + } + + offset = parseInt(parts[2], &err) * 3600 + if len(parts[3]) != 0 { + offset += parseInt(parts[3], &err) * 60 + } + if parts[1] == "-" { + offset = -offset + } + + if err != nil { + err = fmt.Errorf("soap timezone: %q: %v", s, err) + } + + return +} + +var completeDateTimeZoneRegexp = regexp.MustCompile(`^([^T]+)(?:T([^-+Z]+)(.+)?)?$`) + +// splitCompleteDateTimeZone splits date, time and timezone apart from an +// ISO8601 string. It does not ensure that the contents of each part are +// correct, it merely splits on certain delimiters. +// e.g "2010-09-08T12:15:10+0700" => "2010-09-08", "12:15:10", "+0700". +// Timezone can only be present if time is also present. +func splitCompleteDateTimeZone(s string) (dateStr, timeStr, zoneStr string, err error) { + parts := completeDateTimeZoneRegexp.FindStringSubmatch(s) + if parts == nil { + err = fmt.Errorf("soap date/time/zone: value %q is not in ISO8601 datetime format", s) + return + } + dateStr = parts[1] + timeStr = parts[2] + zoneStr = parts[3] + return +} + +// MarshalDate marshals time.Time to SOAP "date" type. Note that this converts +// to local time, and discards the time-of-day components. +func MarshalDate(v time.Time) (string, error) { + return v.In(localLoc).Format("2006-01-02"), nil +} + +var dateFmts = []string{"2006-01-02", "20060102"} + +// UnmarshalDate unmarshals time.Time from SOAP "date" type. This outputs the +// date as midnight in the local time zone. +func UnmarshalDate(s string) (time.Time, error) { + year, month, day, err := parseDateParts(s) + if err != nil { + return time.Time{}, err + } + return time.Date(year, time.Month(month), day, 0, 0, 0, 0, localLoc), nil +} + +// TimeOfDay is used in cases where SOAP "time" or "time.tz" is used. +type TimeOfDay struct { + // Duration of time since midnight. + FromMidnight time.Duration + + // Set to true if Offset is specified. If false, then the timezone is + // unspecified (and by ISO8601 - implies some "local" time). + HasOffset bool + + // Offset is non-zero only if time.tz is used. It is otherwise ignored. If + // non-zero, then it is regarded as a UTC offset in seconds. Note that the + // sub-minutes is ignored by the marshal function. + Offset int +} + +// MarshalTimeOfDay marshals TimeOfDay to the "time" type. +func MarshalTimeOfDay(v TimeOfDay) (string, error) { + d := int64(v.FromMidnight / time.Second) + hour := d / 3600 + d = d % 3600 + minute := d / 60 + second := d % 60 + + return fmt.Sprintf("%02d:%02d:%02d", hour, minute, second), nil +} + +// UnmarshalTimeOfDay unmarshals TimeOfDay from the "time" type. +func UnmarshalTimeOfDay(s string) (TimeOfDay, error) { + t, err := UnmarshalTimeOfDayTz(s) + if err != nil { + return TimeOfDay{}, err + } else if t.HasOffset { + return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone") + } + return t, nil +} + +// MarshalTimeOfDayTz marshals TimeOfDay to the "time.tz" type. +func MarshalTimeOfDayTz(v TimeOfDay) (string, error) { + d := int64(v.FromMidnight / time.Second) + hour := d / 3600 + d = d % 3600 + minute := d / 60 + second := d % 60 + + tz := "" + if v.HasOffset { + if v.Offset == 0 { + tz = "Z" + } else { + offsetMins := v.Offset / 60 + sign := '+' + if offsetMins < 1 { + offsetMins = -offsetMins + sign = '-' + } + tz = fmt.Sprintf("%c%02d:%02d", sign, offsetMins/60, offsetMins%60) + } + } + + return fmt.Sprintf("%02d:%02d:%02d%s", hour, minute, second, tz), nil +} + +// UnmarshalTimeOfDayTz unmarshals TimeOfDay from the "time.tz" type. +func UnmarshalTimeOfDayTz(s string) (tod TimeOfDay, err error) { + zoneIndex := strings.IndexAny(s, "Z+-") + var timePart string + var hasOffset bool + var offset int + if zoneIndex == -1 { + hasOffset = false + timePart = s + } else { + hasOffset = true + timePart = s[:zoneIndex] + if offset, err = parseTimezone(s[zoneIndex:]); err != nil { + return + } + } + + hour, minute, second, err := parseTimeParts(timePart) + if err != nil { + return + } + + fromMidnight := time.Duration(hour*3600+minute*60+second) * time.Second + + // ISO8601 special case - values up to 24:00:00 are allowed, so using + // strictly greater-than for the maximum value. + if fromMidnight > 24*time.Hour || minute >= 60 || second >= 60 { + return TimeOfDay{}, fmt.Errorf("soap time.tz: value %q has value(s) out of range", s) + } + + return TimeOfDay{ + FromMidnight: time.Duration(hour*3600+minute*60+second) * time.Second, + HasOffset: hasOffset, + Offset: offset, + }, nil +} + +// MarshalDateTime marshals time.Time to SOAP "dateTime" type. Note that this +// converts to local time. +func MarshalDateTime(v time.Time) (string, error) { + return v.In(localLoc).Format("2006-01-02T15:04:05"), nil +} + +// UnmarshalDateTime unmarshals time.Time from the SOAP "dateTime" type. This +// returns a value in the local timezone. +func UnmarshalDateTime(s string) (result time.Time, err error) { + dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) + if err != nil { + return + } + + if len(zoneStr) != 0 { + err = fmt.Errorf("soap datetime: unexpected timezone in %q", s) + return + } + + year, month, day, err := parseDateParts(dateStr) + if err != nil { + return + } + + var hour, minute, second int + if len(timeStr) != 0 { + hour, minute, second, err = parseTimeParts(timeStr) + if err != nil { + return + } + } + + result = time.Date(year, time.Month(month), day, hour, minute, second, 0, localLoc) + return +} + +// MarshalDateTimeTz marshals time.Time to SOAP "dateTime.tz" type. +func MarshalDateTimeTz(v time.Time) (string, error) { + return v.Format("2006-01-02T15:04:05-07:00"), nil +} + +// UnmarshalDateTimeTz unmarshals time.Time from the SOAP "dateTime.tz" type. +// This returns a value in the local timezone when the timezone is unspecified. +func UnmarshalDateTimeTz(s string) (result time.Time, err error) { + dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) + if err != nil { + return + } + + year, month, day, err := parseDateParts(dateStr) + if err != nil { + return + } + + var hour, minute, second int + var location *time.Location = localLoc + if len(timeStr) != 0 { + hour, minute, second, err = parseTimeParts(timeStr) + if err != nil { + return + } + if len(zoneStr) != 0 { + var offset int + offset, err = parseTimezone(zoneStr) + if offset == 0 { + location = time.UTC + } else { + location = time.FixedZone("", offset) + } + } + } + + result = time.Date(year, time.Month(month), day, hour, minute, second, 0, location) + return +} + +// MarshalBoolean marshals bool to SOAP "boolean" type. +func MarshalBoolean(v bool) (string, error) { + if v { + return "1", nil + } + return "0", nil +} + +// UnmarshalBoolean unmarshals bool from the SOAP "boolean" type. +func UnmarshalBoolean(s string) (bool, error) { + switch s { + case "0", "false", "no": + return false, nil + case "1", "true", "yes": + return true, nil + } + return false, fmt.Errorf("soap boolean: %q is not a valid boolean value", s) +} + +// MarshalBinBase64 marshals []byte to SOAP "bin.base64" type. +func MarshalBinBase64(v []byte) (string, error) { + return base64.StdEncoding.EncodeToString(v), nil +} + +// UnmarshalBinBase64 unmarshals []byte from the SOAP "bin.base64" type. +func UnmarshalBinBase64(s string) ([]byte, error) { + return base64.StdEncoding.DecodeString(s) +} + +// MarshalBinHex marshals []byte to SOAP "bin.hex" type. +func MarshalBinHex(v []byte) (string, error) { + return hex.EncodeToString(v), nil +} + +// UnmarshalBinHex unmarshals []byte from the SOAP "bin.hex" type. +func UnmarshalBinHex(s string) ([]byte, error) { + return hex.DecodeString(s) +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/soap/types_test.go b/Godeps/_workspace/src/github.com/huin/goupnp/soap/types_test.go new file mode 100644 index 000000000..da6816190 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/soap/types_test.go @@ -0,0 +1,481 @@ +package soap + +import ( + "bytes" + "math" + "testing" + "time" +) + +type convTest interface { + Marshal() (string, error) + Unmarshal(string) (interface{}, error) + Equal(result interface{}) bool +} + +// duper is an interface that convTest values may optionally also implement to +// generate another convTest for a value in an otherwise identical testCase. +type duper interface { + Dupe(tag string) []convTest +} + +type testCase struct { + value convTest + str string + wantMarshalErr bool + wantUnmarshalErr bool + noMarshal bool + noUnMarshal bool + tag string +} + +type Ui1Test uint8 + +func (v Ui1Test) Marshal() (string, error) { + return MarshalUi1(uint8(v)) +} +func (v Ui1Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalUi1(s) +} +func (v Ui1Test) Equal(result interface{}) bool { + return uint8(v) == result.(uint8) +} +func (v Ui1Test) Dupe(tag string) []convTest { + if tag == "dupe" { + return []convTest{ + Ui2Test(v), + Ui4Test(v), + } + } + return nil +} + +type Ui2Test uint16 + +func (v Ui2Test) Marshal() (string, error) { + return MarshalUi2(uint16(v)) +} +func (v Ui2Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalUi2(s) +} +func (v Ui2Test) Equal(result interface{}) bool { + return uint16(v) == result.(uint16) +} + +type Ui4Test uint32 + +func (v Ui4Test) Marshal() (string, error) { + return MarshalUi4(uint32(v)) +} +func (v Ui4Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalUi4(s) +} +func (v Ui4Test) Equal(result interface{}) bool { + return uint32(v) == result.(uint32) +} + +type I1Test int8 + +func (v I1Test) Marshal() (string, error) { + return MarshalI1(int8(v)) +} +func (v I1Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalI1(s) +} +func (v I1Test) Equal(result interface{}) bool { + return int8(v) == result.(int8) +} +func (v I1Test) Dupe(tag string) []convTest { + if tag == "dupe" { + return []convTest{ + I2Test(v), + I4Test(v), + } + } + return nil +} + +type I2Test int16 + +func (v I2Test) Marshal() (string, error) { + return MarshalI2(int16(v)) +} +func (v I2Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalI2(s) +} +func (v I2Test) Equal(result interface{}) bool { + return int16(v) == result.(int16) +} + +type I4Test int32 + +func (v I4Test) Marshal() (string, error) { + return MarshalI4(int32(v)) +} +func (v I4Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalI4(s) +} +func (v I4Test) Equal(result interface{}) bool { + return int32(v) == result.(int32) +} + +type IntTest int64 + +func (v IntTest) Marshal() (string, error) { + return MarshalInt(int64(v)) +} +func (v IntTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalInt(s) +} +func (v IntTest) Equal(result interface{}) bool { + return int64(v) == result.(int64) +} + +type Fixed14_4Test float64 + +func (v Fixed14_4Test) Marshal() (string, error) { + return MarshalFixed14_4(float64(v)) +} +func (v Fixed14_4Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalFixed14_4(s) +} +func (v Fixed14_4Test) Equal(result interface{}) bool { + return math.Abs(float64(v)-result.(float64)) < 0.001 +} + +type CharTest rune + +func (v CharTest) Marshal() (string, error) { + return MarshalChar(rune(v)) +} +func (v CharTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalChar(s) +} +func (v CharTest) Equal(result interface{}) bool { + return rune(v) == result.(rune) +} + +type DateTest struct{ time.Time } + +func (v DateTest) Marshal() (string, error) { + return MarshalDate(time.Time(v.Time)) +} +func (v DateTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalDate(s) +} +func (v DateTest) Equal(result interface{}) bool { + return v.Time.Equal(result.(time.Time)) +} +func (v DateTest) Dupe(tag string) []convTest { + if tag != "no:dateTime" { + return []convTest{DateTimeTest{v.Time}} + } + return nil +} + +type TimeOfDayTest struct { + TimeOfDay +} + +func (v TimeOfDayTest) Marshal() (string, error) { + return MarshalTimeOfDay(v.TimeOfDay) +} +func (v TimeOfDayTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalTimeOfDay(s) +} +func (v TimeOfDayTest) Equal(result interface{}) bool { + return v.TimeOfDay == result.(TimeOfDay) +} +func (v TimeOfDayTest) Dupe(tag string) []convTest { + if tag != "no:time.tz" { + return []convTest{TimeOfDayTzTest{v.TimeOfDay}} + } + return nil +} + +type TimeOfDayTzTest struct { + TimeOfDay +} + +func (v TimeOfDayTzTest) Marshal() (string, error) { + return MarshalTimeOfDayTz(v.TimeOfDay) +} +func (v TimeOfDayTzTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalTimeOfDayTz(s) +} +func (v TimeOfDayTzTest) Equal(result interface{}) bool { + return v.TimeOfDay == result.(TimeOfDay) +} + +type DateTimeTest struct{ time.Time } + +func (v DateTimeTest) Marshal() (string, error) { + return MarshalDateTime(time.Time(v.Time)) +} +func (v DateTimeTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalDateTime(s) +} +func (v DateTimeTest) Equal(result interface{}) bool { + return v.Time.Equal(result.(time.Time)) +} +func (v DateTimeTest) Dupe(tag string) []convTest { + if tag != "no:dateTime.tz" { + return []convTest{DateTimeTzTest{v.Time}} + } + return nil +} + +type DateTimeTzTest struct{ time.Time } + +func (v DateTimeTzTest) Marshal() (string, error) { + return MarshalDateTimeTz(time.Time(v.Time)) +} +func (v DateTimeTzTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalDateTimeTz(s) +} +func (v DateTimeTzTest) Equal(result interface{}) bool { + return v.Time.Equal(result.(time.Time)) +} + +type BooleanTest bool + +func (v BooleanTest) Marshal() (string, error) { + return MarshalBoolean(bool(v)) +} +func (v BooleanTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalBoolean(s) +} +func (v BooleanTest) Equal(result interface{}) bool { + return bool(v) == result.(bool) +} + +type BinBase64Test []byte + +func (v BinBase64Test) Marshal() (string, error) { + return MarshalBinBase64([]byte(v)) +} +func (v BinBase64Test) Unmarshal(s string) (interface{}, error) { + return UnmarshalBinBase64(s) +} +func (v BinBase64Test) Equal(result interface{}) bool { + return bytes.Equal([]byte(v), result.([]byte)) +} + +type BinHexTest []byte + +func (v BinHexTest) Marshal() (string, error) { + return MarshalBinHex([]byte(v)) +} +func (v BinHexTest) Unmarshal(s string) (interface{}, error) { + return UnmarshalBinHex(s) +} +func (v BinHexTest) Equal(result interface{}) bool { + return bytes.Equal([]byte(v), result.([]byte)) +} + +func Test(t *testing.T) { + const time010203 time.Duration = (1*3600 + 2*60 + 3) * time.Second + const time0102 time.Duration = (1*3600 + 2*60) * time.Second + const time01 time.Duration = (1 * 3600) * time.Second + const time235959 time.Duration = (23*3600 + 59*60 + 59) * time.Second + + // Fake out the local time for the implementation. + localLoc = time.FixedZone("Fake/Local", 6*3600) + defer func() { + localLoc = time.Local + }() + + tests := []testCase{ + // ui1 + {str: "", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: " ", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: "abc", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: "-1", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: "0", value: Ui1Test(0), tag: "dupe"}, + {str: "1", value: Ui1Test(1), tag: "dupe"}, + {str: "255", value: Ui1Test(255), tag: "dupe"}, + {str: "256", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true}, + + // ui2 + {str: "65535", value: Ui2Test(65535)}, + {str: "65536", value: Ui2Test(0), wantUnmarshalErr: true, noMarshal: true}, + + // ui4 + {str: "4294967295", value: Ui4Test(4294967295)}, + {str: "4294967296", value: Ui4Test(0), wantUnmarshalErr: true, noMarshal: true}, + + // i1 + {str: "", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: " ", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: "abc", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"}, + {str: "0", value: I1Test(0), tag: "dupe"}, + {str: "-1", value: I1Test(-1), tag: "dupe"}, + {str: "127", value: I1Test(127), tag: "dupe"}, + {str: "-128", value: I1Test(-128), tag: "dupe"}, + {str: "128", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true}, + {str: "-129", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true}, + + // i2 + {str: "32767", value: I2Test(32767)}, + {str: "-32768", value: I2Test(-32768)}, + {str: "32768", value: I2Test(0), wantUnmarshalErr: true, noMarshal: true}, + {str: "-32769", value: I2Test(0), wantUnmarshalErr: true, noMarshal: true}, + + // i4 + {str: "2147483647", value: I4Test(2147483647)}, + {str: "-2147483648", value: I4Test(-2147483648)}, + {str: "2147483648", value: I4Test(0), wantUnmarshalErr: true, noMarshal: true}, + {str: "-2147483649", value: I4Test(0), wantUnmarshalErr: true, noMarshal: true}, + + // int + {str: "9223372036854775807", value: IntTest(9223372036854775807)}, + {str: "-9223372036854775808", value: IntTest(-9223372036854775808)}, + {str: "9223372036854775808", value: IntTest(0), wantUnmarshalErr: true, noMarshal: true}, + {str: "-9223372036854775809", value: IntTest(0), wantUnmarshalErr: true, noMarshal: true}, + + // fixed.14.4 + {str: "0.0000", value: Fixed14_4Test(0)}, + {str: "1.0000", value: Fixed14_4Test(1)}, + {str: "1.2346", value: Fixed14_4Test(1.23456)}, + {str: "-1.0000", value: Fixed14_4Test(-1)}, + {str: "-1.2346", value: Fixed14_4Test(-1.23456)}, + {str: "10000000000000.0000", value: Fixed14_4Test(1e13)}, + {str: "100000000000000.0000", value: Fixed14_4Test(1e14), wantMarshalErr: true, wantUnmarshalErr: true}, + {str: "-10000000000000.0000", value: Fixed14_4Test(-1e13)}, + {str: "-100000000000000.0000", value: Fixed14_4Test(-1e14), wantMarshalErr: true, wantUnmarshalErr: true}, + + // char + {str: "a", value: CharTest('a')}, + {str: "z", value: CharTest('z')}, + {str: "\u1234", value: CharTest(0x1234)}, + {str: "aa", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true}, + {str: "", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true}, + + // date + {str: "2013-10-08", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, tag: "no:dateTime"}, + {str: "20131008", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, noMarshal: true, tag: "no:dateTime"}, + {str: "2013-10-08T10:30:50", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime"}, + {str: "2013-10-08T10:30:50Z", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime"}, + {str: "", value: DateTest{}, wantMarshalErr: true, wantUnmarshalErr: true, noMarshal: true}, + {str: "-1", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true}, + + // time + {str: "00:00:00", value: TimeOfDayTest{TimeOfDay{FromMidnight: 0}}}, + {str: "000000", value: TimeOfDayTest{TimeOfDay{FromMidnight: 0}}, noMarshal: true}, + {str: "24:00:00", value: TimeOfDayTest{TimeOfDay{FromMidnight: 24 * time.Hour}}, noMarshal: true}, // ISO8601 special case + {str: "24:01:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "24:00:01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "25:00:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "00:60:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "00:00:60", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "01:02:03", value: TimeOfDayTest{TimeOfDay{FromMidnight: time010203}}}, + {str: "010203", value: TimeOfDayTest{TimeOfDay{FromMidnight: time010203}}, noMarshal: true}, + {str: "23:59:59", value: TimeOfDayTest{TimeOfDay{FromMidnight: time235959}}}, + {str: "235959", value: TimeOfDayTest{TimeOfDay{FromMidnight: time235959}}, noMarshal: true}, + {str: "01:02", value: TimeOfDayTest{TimeOfDay{FromMidnight: time0102}}, noMarshal: true}, + {str: "0102", value: TimeOfDayTest{TimeOfDay{FromMidnight: time0102}}, noMarshal: true}, + {str: "01", value: TimeOfDayTest{TimeOfDay{FromMidnight: time01}}, noMarshal: true}, + {str: "foo 01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "foo\n01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03 foo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03\nfoo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03Z", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03+01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03+01:23", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03+0123", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03-01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03-01:23", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + {str: "01:02:03-0123", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"}, + + // time.tz + {str: "24:00:01", value: TimeOfDayTzTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "01Z", value: TimeOfDayTzTest{TimeOfDay{time01, true, 0}}, noMarshal: true}, + {str: "01:02:03Z", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 0}}}, + {str: "01+01", value: TimeOfDayTzTest{TimeOfDay{time01, true, 3600}}, noMarshal: true}, + {str: "01:02:03+01", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600}}, noMarshal: true}, + {str: "01:02:03+01:23", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600 + 23*60}}}, + {str: "01:02:03+0123", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600 + 23*60}}, noMarshal: true}, + {str: "01:02:03-01", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -3600}}, noMarshal: true}, + {str: "01:02:03-01:23", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -(3600 + 23*60)}}}, + {str: "01:02:03-0123", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -(3600 + 23*60)}}, noMarshal: true}, + + // dateTime + {str: "2013-10-08T00:00:00", value: DateTimeTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, tag: "no:dateTime.tz"}, + {str: "20131008", value: DateTimeTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, noMarshal: true}, + {str: "2013-10-08T10:30:50", value: DateTimeTest{time.Date(2013, 10, 8, 10, 30, 50, 0, localLoc)}, tag: "no:dateTime.tz"}, + {str: "2013-10-08T10:30:50T", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true}, + {str: "2013-10-08T10:30:50+01", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, + {str: "2013-10-08T10:30:50+01:23", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, + {str: "2013-10-08T10:30:50+0123", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, + {str: "2013-10-08T10:30:50-01", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, + {str: "2013-10-08T10:30:50-01:23", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, + {str: "2013-10-08T10:30:50-0123", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"}, + + // dateTime.tz + {str: "2013-10-08T10:30:50", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, localLoc)}, noMarshal: true}, + {str: "2013-10-08T10:30:50+01", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:00", 3600))}, noMarshal: true}, + {str: "2013-10-08T10:30:50+01:23", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:23", 3600+23*60))}}, + {str: "2013-10-08T10:30:50+0123", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:23", 3600+23*60))}, noMarshal: true}, + {str: "2013-10-08T10:30:50-01", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:00", -3600))}, noMarshal: true}, + {str: "2013-10-08T10:30:50-01:23", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:23", -(3600+23*60)))}}, + {str: "2013-10-08T10:30:50-0123", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:23", -(3600+23*60)))}, noMarshal: true}, + + // boolean + {str: "0", value: BooleanTest(false)}, + {str: "1", value: BooleanTest(true)}, + {str: "false", value: BooleanTest(false), noMarshal: true}, + {str: "true", value: BooleanTest(true), noMarshal: true}, + {str: "no", value: BooleanTest(false), noMarshal: true}, + {str: "yes", value: BooleanTest(true), noMarshal: true}, + {str: "", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, + {str: "other", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, + {str: "2", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, + {str: "-1", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true}, + + // bin.base64 + {str: "", value: BinBase64Test{}}, + {str: "YQ==", value: BinBase64Test("a")}, + {str: "TG9uZ2VyIFN0cmluZy4=", value: BinBase64Test("Longer String.")}, + {str: "TG9uZ2VyIEFsaWduZWQu", value: BinBase64Test("Longer Aligned.")}, + + // bin.hex + {str: "", value: BinHexTest{}}, + {str: "61", value: BinHexTest("a")}, + {str: "4c6f6e67657220537472696e672e", value: BinHexTest("Longer String.")}, + {str: "4C6F6E67657220537472696E672E", value: BinHexTest("Longer String."), noMarshal: true}, + } + + // Generate extra test cases from convTests that implement duper. + var extras []testCase + for i := range tests { + if duper, ok := tests[i].value.(duper); ok { + dupes := duper.Dupe(tests[i].tag) + for _, duped := range dupes { + dupedCase := testCase(tests[i]) + dupedCase.value = duped + extras = append(extras, dupedCase) + } + } + } + tests = append(tests, extras...) + + for _, test := range tests { + if test.noMarshal { + } else if resultStr, err := test.value.Marshal(); err != nil && !test.wantMarshalErr { + t.Errorf("For %T marshal %v, want %q, got error: %v", test.value, test.value, test.str, err) + } else if err == nil && test.wantMarshalErr { + t.Errorf("For %T marshal %v, want error, got %q", test.value, test.value, resultStr) + } else if err == nil && resultStr != test.str { + t.Errorf("For %T marshal %v, want %q, got %q", test.value, test.value, test.str, resultStr) + } + + if test.noUnMarshal { + } else if resultValue, err := test.value.Unmarshal(test.str); err != nil && !test.wantUnmarshalErr { + t.Errorf("For %T unmarshal %q, want %v, got error: %v", test.value, test.str, test.value, err) + } else if err == nil && test.wantUnmarshalErr { + t.Errorf("For %T unmarshal %q, want error, got %v", test.value, test.str, resultValue) + } else if err == nil && !test.value.Equal(resultValue) { + t.Errorf("For %T unmarshal %q, want %v, got %v", test.value, test.str, test.value, resultValue) + } + } +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/ssdp/registry.go b/Godeps/_workspace/src/github.com/huin/goupnp/ssdp/registry.go new file mode 100644 index 000000000..38d10203f --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/ssdp/registry.go @@ -0,0 +1,202 @@ +package ssdp + +import ( + "fmt" + "log" + "net/http" + "net/url" + "regexp" + "strconv" + "sync" + "time" + + "github.com/huin/goupnp/httpu" +) + +const ( + maxExpiryTimeSeconds = 24 * 60 * 60 +) + +var ( + maxAgeRx = regexp.MustCompile("max-age=([0-9]+)") +) + +type Entry struct { + // The address that the entry data was actually received from. + RemoteAddr string + // Unique Service Name. Identifies a unique instance of a device or service. + USN string + // Notfication Type. The type of device or service being announced. + NT string + // Server's self-identifying string. + Server string + Host string + // Location of the UPnP root device description. + Location *url.URL + + // Despite BOOTID,CONFIGID being required fields, apparently they are not + // always set by devices. Set to -1 if not present. + + BootID int32 + ConfigID int32 + + SearchPort uint16 + + // When the last update was received for this entry identified by this USN. + LastUpdate time.Time + // When the last update's cached values are advised to expire. + CacheExpiry time.Time +} + +func newEntryFromRequest(r *http.Request) (*Entry, error) { + now := time.Now() + expiryDuration, err := parseCacheControlMaxAge(r.Header.Get("CACHE-CONTROL")) + if err != nil { + return nil, fmt.Errorf("ssdp: error parsing CACHE-CONTROL max age: %v", err) + } + + loc, err := url.Parse(r.Header.Get("LOCATION")) + if err != nil { + return nil, fmt.Errorf("ssdp: error parsing entry Location URL: %v", err) + } + + bootID, err := parseUpnpIntHeader(r.Header, "BOOTID.UPNP.ORG", -1) + if err != nil { + return nil, err + } + configID, err := parseUpnpIntHeader(r.Header, "CONFIGID.UPNP.ORG", -1) + if err != nil { + return nil, err + } + searchPort, err := parseUpnpIntHeader(r.Header, "SEARCHPORT.UPNP.ORG", ssdpSearchPort) + if err != nil { + return nil, err + } + + if searchPort < 1 || searchPort > 65535 { + return nil, fmt.Errorf("ssdp: search port %d is out of range", searchPort) + } + + return &Entry{ + RemoteAddr: r.RemoteAddr, + USN: r.Header.Get("USN"), + NT: r.Header.Get("NT"), + Server: r.Header.Get("SERVER"), + Host: r.Header.Get("HOST"), + Location: loc, + BootID: bootID, + ConfigID: configID, + SearchPort: uint16(searchPort), + LastUpdate: now, + CacheExpiry: now.Add(expiryDuration), + }, nil +} + +func parseCacheControlMaxAge(cc string) (time.Duration, error) { + matches := maxAgeRx.FindStringSubmatch(cc) + if len(matches) != 2 { + return 0, fmt.Errorf("did not find exactly one max-age in cache control header: %q", cc) + } + expirySeconds, err := strconv.ParseInt(matches[1], 10, 16) + if err != nil { + return 0, err + } + if expirySeconds < 1 || expirySeconds > maxExpiryTimeSeconds { + return 0, fmt.Errorf("rejecting bad expiry time of %d seconds", expirySeconds) + } + return time.Duration(expirySeconds) * time.Second, nil +} + +// parseUpnpIntHeader is intended to parse the +// {BOOT,CONFIGID,SEARCHPORT}.UPNP.ORG header fields. It returns the def if +// the head is empty or missing. +func parseUpnpIntHeader(headers http.Header, headerName string, def int32) (int32, error) { + s := headers.Get(headerName) + if s == "" { + return def, nil + } + v, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return 0, fmt.Errorf("ssdp: could not parse header %s: %v", headerName, err) + } + return int32(v), nil +} + +var _ httpu.Handler = new(Registry) + +// Registry maintains knowledge of discovered devices and services. +type Registry struct { + lock sync.Mutex + byUSN map[string]*Entry +} + +func NewRegistry() *Registry { + return &Registry{ + byUSN: make(map[string]*Entry), + } +} + +// ServeMessage implements httpu.Handler, and uses SSDP NOTIFY requests to +// maintain the registry of devices and services. +func (reg *Registry) ServeMessage(r *http.Request) { + if r.Method != methodNotify { + return + } + + nts := r.Header.Get("nts") + + var err error + switch nts { + case ntsAlive: + err = reg.handleNTSAlive(r) + case ntsUpdate: + err = reg.handleNTSUpdate(r) + case ntsByebye: + err = reg.handleNTSByebye(r) + default: + err = fmt.Errorf("unknown NTS value: %q", nts) + } + log.Printf("In %s request from %s: %v", nts, r.RemoteAddr, err) +} + +func (reg *Registry) handleNTSAlive(r *http.Request) error { + entry, err := newEntryFromRequest(r) + if err != nil { + return err + } + + reg.lock.Lock() + defer reg.lock.Unlock() + + reg.byUSN[entry.USN] = entry + + return nil +} + +func (reg *Registry) handleNTSUpdate(r *http.Request) error { + entry, err := newEntryFromRequest(r) + if err != nil { + return err + } + nextBootID, err := parseUpnpIntHeader(r.Header, "NEXTBOOTID.UPNP.ORG", -1) + if err != nil { + return err + } + entry.BootID = nextBootID + + reg.lock.Lock() + defer reg.lock.Unlock() + + reg.byUSN[entry.USN] = entry + + return nil +} + +func (reg *Registry) handleNTSByebye(r *http.Request) error { + reg.lock.Lock() + defer reg.lock.Unlock() + + delete(reg.byUSN, r.Header.Get("USN")) + + return nil +} diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/ssdp/ssdp.go b/Godeps/_workspace/src/github.com/huin/goupnp/ssdp/ssdp.go new file mode 100644 index 000000000..8178f5d94 --- /dev/null +++ b/Godeps/_workspace/src/github.com/huin/goupnp/ssdp/ssdp.go @@ -0,0 +1,83 @@ +package ssdp + +import ( + "errors" + "log" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/huin/goupnp/httpu" +) + +const ( + ssdpDiscover = `"ssdp:discover"` + ntsAlive = `ssdp:alive` + ntsByebye = `ssdp:byebye` + ntsUpdate = `ssdp:update` + ssdpUDP4Addr = "239.255.255.250:1900" + ssdpSearchPort = 1900 + methodSearch = "M-SEARCH" + methodNotify = "NOTIFY" +) + +// SSDPRawSearch performs a fairly raw SSDP search request, and returns the +// unique response(s) that it receives. Each response has the requested +// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to +// wait for responses in seconds, and must be a minimum of 1 (the +// implementation waits an additional 100ms for responses to arrive), 2 is a +// reasonable value for this. numSends is the number of requests to send - 3 is +// a reasonable value for this. +func SSDPRawSearch(httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) { + if maxWaitSeconds < 1 { + return nil, errors.New("ssdp: maxWaitSeconds must be >= 1") + } + + seenUsns := make(map[string]bool) + var responses []*http.Response + req := http.Request{ + Method: methodSearch, + // TODO: Support both IPv4 and IPv6. + Host: ssdpUDP4Addr, + URL: &url.URL{Opaque: "*"}, + Header: http.Header{ + // Putting headers in here avoids them being title-cased. + // (The UPnP discovery protocol uses case-sensitive headers) + "HOST": []string{ssdpUDP4Addr}, + "MX": []string{strconv.FormatInt(int64(maxWaitSeconds), 10)}, + "MAN": []string{ssdpDiscover}, + "ST": []string{searchTarget}, + }, + } + allResponses, err := httpu.Do(&req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends) + if err != nil { + return nil, err + } + for _, response := range allResponses { + if response.StatusCode != 200 { + log.Printf("ssdp: got response status code %q in search response", response.Status) + continue + } + if st := response.Header.Get("ST"); st != searchTarget { + log.Printf("ssdp: got unexpected search target result %q", st) + continue + } + location, err := response.Location() + if err != nil { + log.Printf("ssdp: no usable location in search response (discarding): %v", err) + continue + } + usn := response.Header.Get("USN") + if usn == "" { + log.Printf("ssdp: empty/missing USN in search response (using location instead): %v", err) + usn = location.String() + } + if _, alreadySeen := seenUsns[usn]; !alreadySeen { + seenUsns[usn] = true + responses = append(responses, response) + } + } + + return responses, nil +} diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index 25cbc0d71..ef7765e8d 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -7,9 +7,9 @@ import ( "strings" "time" - "github.com/fjl/goupnp" - "github.com/fjl/goupnp/dcps/internetgateway1" - "github.com/fjl/goupnp/dcps/internetgateway2" + "github.com/huin/goupnp" + "github.com/huin/goupnp/dcps/internetgateway1" + "github.com/huin/goupnp/dcps/internetgateway2" ) type upnp struct { -- cgit v1.2.3 From 2c454863f2f41fb232778a4cbd4cf135a58c4118 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 13:10:18 +0100 Subject: Use new rlp (TODO requires some refactoring) --- state/state_object.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/state/state_object.go b/state/state_object.go index 340939a5d..0c157403c 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -1,11 +1,13 @@ package state import ( + "bytes" "fmt" "math/big" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) @@ -71,8 +73,28 @@ func NewStateObject(addr []byte, db ethutil.Database) *StateObject { } func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateObject { + // TODO clean me up + var extobject struct { + Nonce uint64 + Balance *big.Int + Root []byte + CodeHash []byte + } + err := rlp.Decode(bytes.NewReader(data), &extobject) + if err != nil { + fmt.Println(err) + return nil + } + object := &StateObject{address: address, db: db} - object.RlpDecode(data) + //object.RlpDecode(data) + object.Nonce = extobject.Nonce + object.balance = extobject.Balance + object.codeHash = extobject.CodeHash + object.State = New(extobject.Root, db) + object.storage = make(map[string]*ethutil.Value) + object.gasPool = new(big.Int) + object.Code, _ = db.Get(extobject.CodeHash) return object } @@ -271,7 +293,6 @@ func (c *StateObject) CodeHash() ethutil.Bytes { func (c *StateObject) RlpDecode(data []byte) { decoder := ethutil.NewValueFromBytes(data) - c.Nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() c.State = New(decoder.Get(2).Bytes(), c.db) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) -- cgit v1.2.3 From 417f018498b12073cd68dce9f4b1f6770b5c9e0f Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 17 Feb 2015 13:30:25 +0100 Subject: Updated P2PConnected log fields --- logger/types.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/logger/types.go b/logger/types.go index f8dcb4e78..419382231 100644 --- a/logger/types.go +++ b/logger/types.go @@ -44,8 +44,10 @@ func (l *P2PConnecting) EventName() string { } type P2PConnected struct { - NumConnections int `json:"num_connections"` - RemoteId string `json:"remote_id"` + RemoteId string `json:"remote_id"` + RemoteAddress string `json:"remote_addr"` + RemoteVersionString string `json:"remote_version_string"` + NumConnections int `json:"num_connections"` LogEvent } -- cgit v1.2.3 From 547788b1b0c6a27c24ba3bc4362aa93143dfea2c Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 14:19:05 +0100 Subject: Added optional address slice. Closes #326 --- rpc/args.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 12e3103bc..9c2c7d7a6 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -1,6 +1,7 @@ package rpc import "encoding/json" + import "github.com/ethereum/go-ethereum/core" type GetBlockArgs struct { @@ -203,7 +204,7 @@ func (obj *Sha3Args) UnmarshalJSON(b []byte) (err error) { type FilterOptions struct { Earliest int64 Latest int64 - Address string + Address interface{} Topic []string Skip int Max int @@ -211,9 +212,22 @@ type FilterOptions struct { func toFilterOptions(options *FilterOptions) core.FilterOptions { var opts core.FilterOptions + + // Convert optional address slice/string to byte slice + if str, ok := options.Address.(string); ok { + opts.Address = [][]byte{fromHex(str)} + } else if slice, ok := options.Address.([]interface{}); ok { + bslice := make([][]byte, len(slice)) + for i, addr := range slice { + if saddr, ok := addr.(string); ok { + bslice[i] = fromHex(saddr) + } + } + opts.Address = bslice + } + opts.Earliest = options.Earliest opts.Latest = options.Latest - opts.Address = fromHex(options.Address) opts.Topics = make([][]byte, len(options.Topic)) for i, topic := range options.Topic { opts.Topics[i] = fromHex(topic) -- cgit v1.2.3 From 7ea131d4ffddaae15c697fe0d025ff431bacc01a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 17 Feb 2015 15:14:12 +0100 Subject: p2p/discover: fix pending replies iteration Range expressions capture the length of the slice once before the first iteration. A range expression cannot be used here since the loop modifies the slice variable (including length changes). --- p2p/discover/udp.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go index b2a895442..69e9f3c2e 100644 --- a/p2p/discover/udp.go +++ b/p2p/discover/udp.go @@ -253,7 +253,8 @@ func (t *udp) loop() { case reply := <-t.replies: // run matching callbacks, remove if they return false. - for i, p := range pending { + for i := 0; i < len(pending); i++ { + p := pending[i] if reply.from == p.from && reply.ptype == p.ptype && p.callback(reply.data) { p.errc <- nil copy(pending[i:], pending[i+1:]) -- cgit v1.2.3 From 567428fb3489d639cd7fdcd50e4362be52745ec4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 16:12:55 +0100 Subject: Filter and mutex locks added --- cmd/mist/assets/examples/coin.html | 5 ----- cmd/mist/gui.go | 2 -- core/chain_manager.go | 13 ++++++++++++- core/filter.go | 23 +++++++++++++++++------ eth/backend.go | 1 + pow/ezp/pow.go | 2 +- ui/filter.go | 4 ++-- 7 files changed, 33 insertions(+), 17 deletions(-) diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html index ca7a9c0dd..cb9d471de 100644 --- a/cmd/mist/assets/examples/coin.html +++ b/cmd/mist/assets/examples/coin.html @@ -80,11 +80,6 @@ refresh(); }); - var ev = contract.SingleTransact({}) - ev.watch(function(log) { - someElement.innerHTML += "tnaheousnthaoeu"; - }); - eth.watch('chain').changed(function() { refresh(); }); diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 9ce6ba650..886a5811b 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -394,7 +394,6 @@ func (gui *Gui) update() { miningLabel := gui.getObjectByName("miningLabel") events := gui.eth.EventMux().Subscribe( - //eth.PeerListEvent{}, core.NewBlockEvent{}, core.TxPreEvent{}, core.TxPostEvent{}, @@ -410,7 +409,6 @@ func (gui *Gui) update() { switch ev := ev.(type) { case core.NewBlockEvent: gui.processBlock(ev.Block, false) - //gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil) balance := ethutil.CurrencyToString(gui.eth.ChainManager().State().GetBalance(gui.address())) gui.getObjectByName("balanceLabel").Set("text", fmt.Sprintf("%v", balance)) diff --git a/core/chain_manager.go b/core/chain_manager.go index c28e901c6..025615676 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -79,6 +79,7 @@ type ChainManager struct { genesisBlock *types.Block // Last known total difficulty mu sync.RWMutex + tsmu sync.RWMutex td *big.Int currentBlock *types.Block lastBlockHash []byte @@ -131,9 +132,19 @@ func (self *ChainManager) State() *state.StateDB { } func (self *ChainManager) TransState() *state.StateDB { + self.tsmu.RLock() + defer self.tsmu.RUnlock() + //tmp := self.transState + return self.transState } +func (self *ChainManager) setTransState(statedb *state.StateDB) { + self.tsmu.Lock() + defer self.tsmu.Unlock() + self.transState = statedb +} + func (bc *ChainManager) setLastBlock() { data, _ := bc.db.Get([]byte("LastBlock")) if len(data) != 0 { @@ -376,7 +387,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.setTotalDifficulty(td) self.insert(block) - self.transState = state.New(cblock.Root(), self.db) + self.setTransState(state.New(cblock.Root(), self.db)) self.eventMux.Post(ChainEvent{block, td}) } diff --git a/core/filter.go b/core/filter.go index 234fa3316..88f12a67c 100644 --- a/core/filter.go +++ b/core/filter.go @@ -16,7 +16,7 @@ type FilterOptions struct { Earliest int64 Latest int64 - Address []byte + Address [][]byte Topics [][]byte Skip int @@ -29,7 +29,7 @@ type Filter struct { earliest int64 latest int64 skip int - address []byte + address [][]byte max int topics [][]byte @@ -65,7 +65,7 @@ func (self *Filter) SetLatestBlock(latest int64) { self.latest = latest } -func (self *Filter) SetAddress(addr []byte) { +func (self *Filter) SetAddress(addr [][]byte) { self.address = addr } @@ -145,7 +145,8 @@ func (self *Filter) FilterLogs(logs state.Logs) state.Logs { // Filter the logs for interesting stuff Logs: for _, log := range logs { - if !bytes.Equal(self.address, log.Address()) { + if !includes(self.address, log.Address()) { + //if !bytes.Equal(self.address, log.Address()) { continue } @@ -163,8 +164,18 @@ Logs: } func (self *Filter) bloomFilter(block *types.Block) bool { - if len(self.address) > 0 && !types.BloomLookup(block.Bloom(), self.address) { - return false + if len(self.address) > 0 { + var included bool + for _, addr := range self.address { + if types.BloomLookup(block.Bloom(), addr) { + included = true + break + } + } + + if !included { + return false + } } for _, topic := range self.topics { diff --git a/eth/backend.go b/eth/backend.go index 690c7136d..7685f3568 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -26,6 +26,7 @@ var ( defaultBootNodes = []*discover.Node{ discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), + discover.MustParseNode("enode://d1760a33c2f25c3b419ee4f6787fb0ea148828f5e678f0450d4be978fef908b42fc47a4c0fbf19832754f17881d381e50364fa93be42f31801d60ac64933f0a5@127.0.0.1:30303"), } ) diff --git a/pow/ezp/pow.go b/pow/ezp/pow.go index 540381243..f4a8b80e5 100644 --- a/pow/ezp/pow.go +++ b/pow/ezp/pow.go @@ -21,7 +21,7 @@ type EasyPow struct { } func New() *EasyPow { - return &EasyPow{turbo: false} + return &EasyPow{turbo: true} } func (pow *EasyPow) GetHashrate() int64 { diff --git a/ui/filter.go b/ui/filter.go index da2ea0edb..0d1746915 100644 --- a/ui/filter.go +++ b/ui/filter.go @@ -29,8 +29,8 @@ func NewFilterFromMap(object map[string]interface{}, eth core.Backend) *core.Fil } if object["address"] != nil { - val := ethutil.NewValue(object["address"]) - filter.SetAddress(fromHex(val.Str())) + //val := ethutil.NewValue(object["address"]) + //filter.SetAddress(fromHex(val.Str())) } if object["max"] != nil { -- cgit v1.2.3 From 9a2be227a6486dd514d64981fb964e86e0bb0467 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 16:18:29 +0100 Subject: commented peer count out --- cmd/mist/assets/qml/main.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 9a6bf5273..e194c9f09 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -888,7 +888,7 @@ ApplicationWindow { function addPeer(peer) { peerModel.append(peer) } function setPeerCounters(text) { - peerCounterLabel.text = text + //peerCounterLabel.text = text } function timeAgo(unixTs){ -- cgit v1.2.3 From 13c00afc68652d517f91313bb8c3eeb206d23f22 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 16:54:52 +0100 Subject: Implement register and watchTx --- cmd/mist/assets/ext/ethereum.js/dist/ethereum.js | 2 + rpc/message.go | 28 +++++++++++ rpc/packages.go | 60 +++++++++++++++++++++++- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js b/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js index d0e9d3cb7..83b598b3f 100644 --- a/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js +++ b/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js @@ -1417,6 +1417,8 @@ var ethMethods = function () { var methods = [ { name: 'balanceAt', call: 'eth_balanceAt' }, + { name: 'register', call: 'eth_register' }, + { name: 'unregister', call: 'eth_unregister' }, { name: 'stateAt', call: 'eth_stateAt' }, { name: 'storageAt', call: 'eth_storageAt' }, { name: 'countAt', call: 'eth_countAt'}, diff --git a/rpc/message.go b/rpc/message.go index 7983e003d..b5b852f54 100644 --- a/rpc/message.go +++ b/rpc/message.go @@ -342,3 +342,31 @@ func (req *RpcRequest) ToWhisperHasIdentityArgs() (string, error) { rpclogger.DebugDetailf("%T %v", args, args) return args, nil } + +func (req *RpcRequest) ToRegisterArgs() (string, error) { + if len(req.Params) < 1 { + return "", NewErrorResponse(ErrorArguments) + } + + var args string + err := json.Unmarshal(req.Params[0], &args) + if err != nil { + return "", err + } + rpclogger.DebugDetailf("%T %v", args, args) + return args, nil +} + +func (req *RpcRequest) ToWatchTxArgs() (string, error) { + if len(req.Params) < 1 { + return "", NewErrorResponse(ErrorArguments) + } + + var args string + err := json.Unmarshal(req.Params[0], &args) + if err != nil { + return "", err + } + rpclogger.DebugDetailf("%T %v", args, args) + return args, nil +} diff --git a/rpc/packages.go b/rpc/packages.go index ef31ff1e1..0b73d48a7 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -55,6 +55,9 @@ type EthereumApi struct { messagesMut sync.RWMutex messages map[int][]xeth.WhisperMessage + // Register keeps a list of accounts and transaction data + regmut sync.Mutex + register map[string][]*NewTxArgs db ethutil.Database } @@ -73,6 +76,36 @@ func NewEthereumApi(eth *xeth.XEth) *EthereumApi { return api } +func (self *EthereumApi) Register(args string, reply *interface{}) error { + self.regmut.Lock() + defer self.regmut.Unlock() + + if _, ok := self.register[args]; ok { + self.register[args] = nil // register with empty + } + return nil +} + +func (self *EthereumApi) Unregister(args string, reply *interface{}) error { + self.regmut.Lock() + defer self.regmut.Unlock() + + delete(self.register, args) + + return nil +} + +func (self *EthereumApi) WatchTx(args string, reply *interface{}) error { + self.regmut.Lock() + defer self.regmut.Unlock() + + txs := self.register[args] + self.register[args] = nil + + *reply = txs + return nil +} + func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) error { var id int filter := core.NewFilter(self.xeth.Backend()) @@ -149,8 +182,13 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { args.GasPrice = defaultGasPrice } - result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) - *reply = result + // TODO if no_private_key then + if _, exists := p.register[args.From]; exists { + p.register[args.From] = append(p.register[args.From], args) + } else { + result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) + *reply = result + } return nil } @@ -424,6 +462,24 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_gasPrice": *reply = defaultGasPrice return nil + case "eth_register": + args, err := req.ToRegisterArgs() + if err != nil { + return err + } + return p.Register(args, reply) + case "eth_unregister": + args, err := req.ToRegisterArgs() + if err != nil { + return err + } + return p.Unregister(args, reply) + case "eth_watchTx": + args, err := req.ToWatchTxArgs() + if err != nil { + return err + } + return p.WatchTx(args, reply) case "web3_sha3": args, err := req.ToSha3Args() if err != nil { -- cgit v1.2.3 From 7fc9b5b3f9ca0111cc4bc1b2a6b4bb2eccd3e048 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 22:20:47 +0100 Subject: Changed to ChainEvent and fixed a nil pointer in transact --- cmd/mist/assets/examples/info.html | 4 ++++ cmd/mist/gui.go | 6 ------ core/chain_manager.go | 2 -- eth/backend.go | 4 ++-- event/filter/eth_filter.go | 7 +++++-- rpc/args.go | 29 +++++++++++++++++++++++++++++ rpc/packages.go | 6 ++++++ xeth/xeth.go | 3 +-- 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/cmd/mist/assets/examples/info.html b/cmd/mist/assets/examples/info.html index d8816b19f..2a405c280 100644 --- a/cmd/mist/assets/examples/info.html +++ b/cmd/mist/assets/examples/info.html @@ -71,6 +71,10 @@ document.querySelector("#gas_price").innerHTML = eth.gasPrice; document.querySelector("#mining").innerHTML = eth.mining; document.querySelector("#listening").innerHTML = eth.listening; + eth.watch('chain').changed(function() { + document.querySelector("#number").innerHTML = eth.number; + }); + diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 886a5811b..c12538f4a 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -394,7 +394,6 @@ func (gui *Gui) update() { miningLabel := gui.getObjectByName("miningLabel") events := gui.eth.EventMux().Subscribe( - core.NewBlockEvent{}, core.TxPreEvent{}, core.TxPostEvent{}, ) @@ -407,11 +406,6 @@ func (gui *Gui) update() { return } switch ev := ev.(type) { - case core.NewBlockEvent: - gui.processBlock(ev.Block, false) - balance := ethutil.CurrencyToString(gui.eth.ChainManager().State().GetBalance(gui.address())) - gui.getObjectByName("balanceLabel").Set("text", fmt.Sprintf("%v", balance)) - case core.TxPreEvent: tx := ev.Tx diff --git a/core/chain_manager.go b/core/chain_manager.go index 025615676..22d54be03 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -393,8 +393,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } } self.mu.Unlock() - - self.eventMux.Post(NewBlockEvent{block}) } return nil diff --git a/eth/backend.go b/eth/backend.go index 7685f3568..9749cef9a 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -25,8 +25,8 @@ var ( jsonlogger = ethlogger.NewJsonLogger() defaultBootNodes = []*discover.Node{ - discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), - discover.MustParseNode("enode://d1760a33c2f25c3b419ee4f6787fb0ea148828f5e678f0450d4be978fef908b42fc47a4c0fbf19832754f17881d381e50364fa93be42f31801d60ac64933f0a5@127.0.0.1:30303"), + //discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), + discover.MustParseNode("enode://364d179a050fb3192ea25ee2c4836cb808f13bb1a98a058e5bf215a597080edd742a00d6fd4b5f348a08024097f0b8f567610902dddf8db573362d8b22cabef5@127.0.0.1:30303"), } ) diff --git a/event/filter/eth_filter.go b/event/filter/eth_filter.go index 295fcfbbf..d298d914d 100644 --- a/event/filter/eth_filter.go +++ b/event/filter/eth_filter.go @@ -60,7 +60,10 @@ func (self *FilterManager) GetFilter(id int) *core.Filter { func (self *FilterManager) filterLoop() { // Subscribe to events - events := self.eventMux.Subscribe(core.PendingBlockEvent{}, core.NewBlockEvent{}, state.Logs(nil)) + events := self.eventMux.Subscribe( + core.PendingBlockEvent{}, + core.ChainEvent{}, + state.Logs(nil)) out: for { @@ -69,7 +72,7 @@ out: break out case event := <-events.Chan(): switch event := event.(type) { - case core.NewBlockEvent: + case core.ChainEvent: self.filterMu.RLock() for _, filter := range self.filters { if filter.BlockCallback != nil { diff --git a/rpc/args.go b/rpc/args.go index 9c2c7d7a6..429b385d5 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -38,6 +38,35 @@ type NewTxArgs struct { Data string `json:"data"` } +func (obj *NewTxArgs) UnmarshalJSON(b []byte) (err error) { + // Data can be either specified as "data" or "code" :-/ + var ext struct { + From string + To string + Value string + Gas string + GasPrice string + Data string + Code string + } + + if err = json.Unmarshal(b, &ext); err == nil { + if len(ext.Data) == 0 { + ext.Data = ext.Code + } + obj.From = ext.From + obj.To = ext.To + obj.Value = ext.Value + obj.Gas = ext.Gas + obj.GasPrice = ext.GasPrice + obj.Data = ext.Data + + return + } + + return NewErrorResponse(ErrorDecodeArgs) +} + type PushTxArgs struct { Tx string `json:"tx"` } diff --git a/rpc/packages.go b/rpc/packages.go index 0b73d48a7..4d2194571 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -127,6 +127,9 @@ func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error filter := core.NewFilter(self.xeth.Backend()) callback := func(block *types.Block) { + self.logMut.Lock() + defer self.logMut.Unlock() + self.logs[id] = append(self.logs[id], &state.StateLog{}) } if args == "pending" { @@ -153,6 +156,9 @@ func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error { } func (self *EthereumApi) Logs(id int, reply *interface{}) error { + self.logMut.Lock() + defer self.logMut.Unlock() + filter := self.filterManager.GetFilter(id) *reply = toLogs(filter.Find()) diff --git a/xeth/xeth.go b/xeth/xeth.go index 27435b956..f005105bb 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -16,7 +16,6 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/whisper" ) @@ -220,7 +219,7 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st var ( statedb = self.chainManager.TransState() key = self.eth.KeyManager().KeyPair() - from = state.NewStateObject(key.Address(), self.eth.Db()) + from = statedb.GetOrNewStateObject(key.Address()) block = self.chainManager.CurrentBlock() to = statedb.GetOrNewStateObject(fromHex(toStr)) data = fromHex(dataStr) -- cgit v1.2.3 From 26d58e0446521f725616b5a5d1b9d1ac04837f00 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 22:46:30 +0100 Subject: Forgot to add the case for logs. Closes #336 --- rpc/packages.go | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/rpc/packages.go b/rpc/packages.go index 4d2194571..8aa604aa5 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -1,21 +1,4 @@ /* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see . -*/ -/* - For each request type, define the following: 1. RpcRequest "To" method [message.go], which does basic validation and conversion to "Args" type via json.Decoder() @@ -160,7 +143,9 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error { defer self.logMut.Unlock() filter := self.filterManager.GetFilter(id) - *reply = toLogs(filter.Find()) + if filter != nil { + *reply = toLogs(filter.Find()) + } return nil } @@ -465,6 +450,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } return p.FilterChanged(args, reply) + case "eth_filterLogs": + args, err := req.ToFilterChangedArgs() + if err != nil { + return err + } + return p.Logs(args, reply) case "eth_gasPrice": *reply = defaultGasPrice return nil -- cgit v1.2.3 From c1474e1877641cb80ed0c935a3bd5b3d5c2fe3ac Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 23:10:37 +0100 Subject: Removed mined transactions from pending view. Closes #321 --- cmd/mist/assets/qml/main.qml | 2 +- cmd/mist/assets/qml/views/pending_tx.qml | 9 +++++++++ cmd/mist/gui.go | 28 ++-------------------------- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index e194c9f09..3089fc46f 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -876,7 +876,7 @@ ApplicationWindow { } function setWalletValue(value) { - walletValueLabel.text = value + //walletValueLabel.text = value } function loadPlugin(name) { diff --git a/cmd/mist/assets/qml/views/pending_tx.qml b/cmd/mist/assets/qml/views/pending_tx.qml index 4442a69db..3dcedeff2 100644 --- a/cmd/mist/assets/qml/views/pending_tx.qml +++ b/cmd/mist/assets/qml/views/pending_tx.qml @@ -41,4 +41,13 @@ Rectangle { pendingTxModel.insert(0, {hash: tx.hash, to: tx.address, from: tx.sender, value: tx.value, contract: isContract}) } + + function removeTx(tx) { + for (var i = 0; i < pendingTxModel.count; i++) { + if (tx.hash === pendingTxModel.get(i).hash) { + pendingTxModel.remove(i); + break; + } + } + } } diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index c12538f4a..c9419473c 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -407,34 +407,10 @@ func (gui *Gui) update() { } switch ev := ev.(type) { case core.TxPreEvent: - tx := ev.Tx - - tstate := gui.eth.ChainManager().TransState() - cstate := gui.eth.ChainManager().State() - - taccount := tstate.GetAccount(gui.address()) - caccount := cstate.GetAccount(gui.address()) - unconfirmedFunds := new(big.Int).Sub(taccount.Balance(), caccount.Balance()) - - gui.setWalletValue(taccount.Balance(), unconfirmedFunds) - gui.insertTransaction("pre", tx) + gui.insertTransaction("pre", ev.Tx) case core.TxPostEvent: - tx := ev.Tx - object := state.GetAccount(gui.address()) - - if bytes.Compare(tx.From(), gui.address()) == 0 { - object.SubAmount(tx.Value()) - - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - } else if bytes.Compare(tx.To(), gui.address()) == 0 { - object.AddAmount(tx.Value()) - - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - } - - gui.setWalletValue(object.Balance(), nil) - state.UpdateStateObject(object) + gui.getObjectByName("pendingTxView").Call("removeTx", xeth.NewTx(ev.Tx)) } case <-peerUpdateTicker.C: -- cgit v1.2.3 From 5ec8c5f71b2db976ffe51180f20bfd6b4fd94188 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 23:14:10 +0100 Subject: added bootnode back in --- eth/backend.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index 9749cef9a..690c7136d 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -25,8 +25,7 @@ var ( jsonlogger = ethlogger.NewJsonLogger() defaultBootNodes = []*discover.Node{ - //discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), - discover.MustParseNode("enode://364d179a050fb3192ea25ee2c4836cb808f13bb1a98a058e5bf215a597080edd742a00d6fd4b5f348a08024097f0b8f567610902dddf8db573362d8b22cabef5@127.0.0.1:30303"), + discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), } ) -- cgit v1.2.3 From 60318c96d03bcaaf731802b1080a3d87cb482124 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 23:22:42 +0100 Subject: removed old wallet --- cmd/mist/assets/qml/main.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 3089fc46f..f9bfd9b8d 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -46,7 +46,6 @@ ApplicationWindow { walletWeb.view.url = "http://ethereum-dapp-wallet.meteor.com/"; walletWeb.menuItem.title = "Wallet"; - addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: false}); addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); -- cgit v1.2.3 From f499f343baefece18764135eb99af0c7e038ff5e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 18 Feb 2015 10:52:23 +0100 Subject: Update JSON Log types --- eth/backend.go | 2 - logger/types.go | 593 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 295 insertions(+), 300 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index 690c7136d..06c64e811 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -205,9 +205,7 @@ func (s *Ethereum) Coinbase() []byte { return nil } // TODO func (s *Ethereum) Start() error { jsonlogger.LogJson(ðlogger.LogStarting{ ClientString: s.net.Name, - Coinbase: ethutil.Bytes2Hex(s.KeyManager().Address()), ProtocolVersion: ProtocolVersion, - LogEvent: ethlogger.LogEvent{Guid: ethutil.Bytes2Hex(crypto.FromECDSAPub(&s.net.PrivateKey.PublicKey))}, }) err := s.net.Start() diff --git a/logger/types.go b/logger/types.go index 419382231..d14a26643 100644 --- a/logger/types.go +++ b/logger/types.go @@ -7,7 +7,6 @@ import ( type utctime8601 struct{} func (utctime8601) MarshalJSON() ([]byte, error) { - // FIX This should be re-formated for proper ISO 8601 return []byte(`"` + time.Now().UTC().Format(time.RFC3339Nano)[:26] + `Z"`), nil } @@ -16,14 +15,13 @@ type JsonLog interface { } type LogEvent struct { - Guid string `json:"guid"` - Ts utctime8601 `json:"ts"` + // Guid string `json:"guid"` + Ts utctime8601 `json:"ts"` // Level string `json:"level"` } type LogStarting struct { - ClientString string `json:"version_string"` - Coinbase string `json:"coinbase"` + ClientString string `json:"client_impl"` ProtocolVersion int `json:"eth_version"` LogEvent } @@ -32,17 +30,6 @@ func (l *LogStarting) EventName() string { return "starting" } -type P2PConnecting struct { - RemoteId string `json:"remote_id"` - RemoteEndpoint string `json:"remote_endpoint"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PConnecting) EventName() string { - return "p2p.connecting" -} - type P2PConnected struct { RemoteId string `json:"remote_id"` RemoteAddress string `json:"remote_addr"` @@ -55,268 +42,46 @@ func (l *P2PConnected) EventName() string { return "p2p.connected" } -type P2PHandshaked struct { - RemoteCapabilities []string `json:"remote_capabilities"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PHandshaked) EventName() string { - return "p2p.handshaked" -} - -type P2PDisconnected struct { - NumConnections int `json:"num_connections"` - RemoteId string `json:"remote_id"` - LogEvent -} - -func (l *P2PDisconnected) EventName() string { - return "p2p.disconnected" -} - -type P2PDisconnecting struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PDisconnecting) EventName() string { - return "p2p.disconnecting" -} - -type P2PDisconnectingBadHandshake struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PDisconnectingBadHandshake) EventName() string { - return "p2p.disconnecting.bad_handshake" -} - -type P2PDisconnectingBadProtocol struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PDisconnectingBadProtocol) EventName() string { - return "p2p.disconnecting.bad_protocol" -} - -type P2PDisconnectingReputation struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PDisconnectingReputation) EventName() string { - return "p2p.disconnecting.reputation" -} - -type P2PDisconnectingDHT struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PDisconnectingDHT) EventName() string { - return "p2p.disconnecting.dht" -} - -type P2PEthDisconnectingBadBlock struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PEthDisconnectingBadBlock) EventName() string { - return "p2p.eth.disconnecting.bad_block" -} - -type P2PEthDisconnectingBadTx struct { - Reason string `json:"reason"` - RemoteId string `json:"remote_id"` - NumConnections int `json:"num_connections"` - LogEvent -} - -func (l *P2PEthDisconnectingBadTx) EventName() string { - return "p2p.eth.disconnecting.bad_tx" -} - -type EthNewBlockMined struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockHexRlp string `json:"block_hexrlp"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockMined) EventName() string { - return "eth.newblock.mined" -} - -type EthNewBlockBroadcasted struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` +type EthMinerNewBlock struct { + BlockHash string `json:"block_hash"` + BlockNumber int `json:"block_number"` + ChainHeadHash string `json:"chain_head_hash"` + BlockPrevHash string `json:"block_prev_hash"` LogEvent } -func (l *EthNewBlockBroadcasted) EventName() string { - return "eth.newblock.broadcasted" +func (l *EthMinerNewBlock) EventName() string { + return "eth.miner.new_block" } -type EthNewBlockReceived struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` +type EthChainReceivedNewBlock struct { + BlockHash string `json:"block_hash"` + BlockNumber int `json:"block_number"` + ChainHeadHash string `json:"chain_head_hash"` + BlockPrevHash string `json:"block_prev_hash"` + RemoteId int `json:"remote_id"` LogEvent } -func (l *EthNewBlockReceived) EventName() string { - return "eth.newblock.received" +func (l *EthChainReceivedNewBlock) EventName() string { + return "eth.chain.received.new_block" } -type EthNewBlockIsKnown struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` +type EthChainNewHead struct { + BlockHash string `json:"block_hash"` + BlockNumber int `json:"block_number"` + ChainHeadHash string `json:"chain_head_hash"` + BlockPrevHash string `json:"block_prev_hash"` LogEvent } -func (l *EthNewBlockIsKnown) EventName() string { - return "eth.newblock.is_known" -} - -type EthNewBlockIsNew struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockIsNew) EventName() string { - return "eth.newblock.is_new" -} - -type EthNewBlockMissingParent struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockMissingParent) EventName() string { - return "eth.newblock.missing_parent" -} - -type EthNewBlockIsInvalid struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockIsInvalid) EventName() string { - return "eth.newblock.is_invalid" -} - -type EthNewBlockChainIsOlder struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockChainIsOlder) EventName() string { - return "eth.newblock.chain.is_older" -} - -type EthNewBlockChainIsCanonical struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockChainIsCanonical) EventName() string { - return "eth.newblock.chain.is_cannonical" -} - -type EthNewBlockChainNotCanonical struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockChainNotCanonical) EventName() string { - return "eth.newblock.chain.not_cannonical" -} - -type EthNewBlockChainSwitched struct { - BlockNumber int `json:"block_number"` - HeadHash string `json:"head_hash"` - OldHeadHash string `json:"old_head_hash"` - BlockHash string `json:"block_hash"` - BlockDifficulty int `json:"block_difficulty"` - BlockPrevHash string `json:"block_prev_hash"` - LogEvent -} - -func (l *EthNewBlockChainSwitched) EventName() string { - return "eth.newblock.chain.switched" -} - -type EthTxCreated struct { - TxHash string `json:"tx_hash"` - TxSender string `json:"tx_sender"` - TxAddress string `json:"tx_address"` - TxHexRLP string `json:"tx_hexrlp"` - TxNonce int `json:"tx_nonce"` - LogEvent -} - -func (l *EthTxCreated) EventName() string { - return "eth.tx.created" +func (l *EthChainNewHead) EventName() string { + return "eth.chain.new_head" } type EthTxReceived struct { - TxHash string `json:"tx_hash"` - TxAddress string `json:"tx_address"` - TxHexRLP string `json:"tx_hexrlp"` - RemoteId string `json:"remote_id"` - TxNonce int `json:"tx_nonce"` + TxHash string `json:"tx_hash"` + RemoteId string `json:"remote_id"` LogEvent } @@ -324,39 +89,271 @@ func (l *EthTxReceived) EventName() string { return "eth.tx.received" } -type EthTxBroadcasted struct { - TxHash string `json:"tx_hash"` - TxSender string `json:"tx_sender"` - TxAddress string `json:"tx_address"` - TxNonce int `json:"tx_nonce"` - LogEvent -} - -func (l *EthTxBroadcasted) EventName() string { - return "eth.tx.broadcasted" -} - -type EthTxValidated struct { - TxHash string `json:"tx_hash"` - TxSender string `json:"tx_sender"` - TxAddress string `json:"tx_address"` - TxNonce int `json:"tx_nonce"` - LogEvent -} - -func (l *EthTxValidated) EventName() string { - return "eth.tx.validated" -} - -type EthTxIsInvalid struct { - TxHash string `json:"tx_hash"` - TxSender string `json:"tx_sender"` - TxAddress string `json:"tx_address"` - Reason string `json:"reason"` - TxNonce int `json:"tx_nonce"` - LogEvent -} - -func (l *EthTxIsInvalid) EventName() string { - return "eth.tx.is_invalid" -} +// +// +// The types below are legacy and need to be converted to new format or deleted +// +// + +// type P2PConnecting struct { +// RemoteId string `json:"remote_id"` +// RemoteEndpoint string `json:"remote_endpoint"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PConnecting) EventName() string { +// return "p2p.connecting" +// } + +// type P2PHandshaked struct { +// RemoteCapabilities []string `json:"remote_capabilities"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PHandshaked) EventName() string { +// return "p2p.handshaked" +// } + +// type P2PDisconnected struct { +// NumConnections int `json:"num_connections"` +// RemoteId string `json:"remote_id"` +// LogEvent +// } + +// func (l *P2PDisconnected) EventName() string { +// return "p2p.disconnected" +// } + +// type P2PDisconnecting struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PDisconnecting) EventName() string { +// return "p2p.disconnecting" +// } + +// type P2PDisconnectingBadHandshake struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PDisconnectingBadHandshake) EventName() string { +// return "p2p.disconnecting.bad_handshake" +// } + +// type P2PDisconnectingBadProtocol struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PDisconnectingBadProtocol) EventName() string { +// return "p2p.disconnecting.bad_protocol" +// } + +// type P2PDisconnectingReputation struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PDisconnectingReputation) EventName() string { +// return "p2p.disconnecting.reputation" +// } + +// type P2PDisconnectingDHT struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PDisconnectingDHT) EventName() string { +// return "p2p.disconnecting.dht" +// } + +// type P2PEthDisconnectingBadBlock struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PEthDisconnectingBadBlock) EventName() string { +// return "p2p.eth.disconnecting.bad_block" +// } + +// type P2PEthDisconnectingBadTx struct { +// Reason string `json:"reason"` +// RemoteId string `json:"remote_id"` +// NumConnections int `json:"num_connections"` +// LogEvent +// } + +// func (l *P2PEthDisconnectingBadTx) EventName() string { +// return "p2p.eth.disconnecting.bad_tx" +// } + +// type EthNewBlockBroadcasted struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockBroadcasted) EventName() string { +// return "eth.newblock.broadcasted" +// } + +// type EthNewBlockIsKnown struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockIsKnown) EventName() string { +// return "eth.newblock.is_known" +// } + +// type EthNewBlockIsNew struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockIsNew) EventName() string { +// return "eth.newblock.is_new" +// } + +// type EthNewBlockMissingParent struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockMissingParent) EventName() string { +// return "eth.newblock.missing_parent" +// } + +// type EthNewBlockIsInvalid struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockIsInvalid) EventName() string { +// return "eth.newblock.is_invalid" +// } + +// type EthNewBlockChainIsOlder struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockChainIsOlder) EventName() string { +// return "eth.newblock.chain.is_older" +// } + +// type EthNewBlockChainIsCanonical struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockChainIsCanonical) EventName() string { +// return "eth.newblock.chain.is_cannonical" +// } + +// type EthNewBlockChainNotCanonical struct { +// BlockNumber int `json:"block_number"` +// HeadHash string `json:"head_hash"` +// BlockHash string `json:"block_hash"` +// BlockDifficulty int `json:"block_difficulty"` +// BlockPrevHash string `json:"block_prev_hash"` +// LogEvent +// } + +// func (l *EthNewBlockChainNotCanonical) EventName() string { +// return "eth.newblock.chain.not_cannonical" +// } + +// type EthTxCreated struct { +// TxHash string `json:"tx_hash"` +// TxSender string `json:"tx_sender"` +// TxAddress string `json:"tx_address"` +// TxHexRLP string `json:"tx_hexrlp"` +// TxNonce int `json:"tx_nonce"` +// LogEvent +// } + +// func (l *EthTxCreated) EventName() string { +// return "eth.tx.created" +// } + +// type EthTxBroadcasted struct { +// TxHash string `json:"tx_hash"` +// TxSender string `json:"tx_sender"` +// TxAddress string `json:"tx_address"` +// TxNonce int `json:"tx_nonce"` +// LogEvent +// } + +// func (l *EthTxBroadcasted) EventName() string { +// return "eth.tx.broadcasted" +// } + +// type EthTxValidated struct { +// TxHash string `json:"tx_hash"` +// TxSender string `json:"tx_sender"` +// TxAddress string `json:"tx_address"` +// TxNonce int `json:"tx_nonce"` +// LogEvent +// } + +// func (l *EthTxValidated) EventName() string { +// return "eth.tx.validated" +// } + +// type EthTxIsInvalid struct { +// TxHash string `json:"tx_hash"` +// TxSender string `json:"tx_sender"` +// TxAddress string `json:"tx_address"` +// Reason string `json:"reason"` +// TxNonce int `json:"tx_nonce"` +// LogEvent +// } + +// func (l *EthTxIsInvalid) EventName() string { +// return "eth.tx.is_invalid" +// } -- cgit v1.2.3 From 07bdba687f4971641c4dadc526c634dfbe4177d8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 18 Feb 2015 10:52:36 +0100 Subject: Re-add LogFormat to Config --- cmd/ethereum/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 0dba462be..d4a57ee48 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -67,6 +67,7 @@ func main() { DataDir: Datadir, LogFile: LogFile, LogLevel: LogLevel, + LogFormat: LogFormat, MaxPeers: MaxPeer, Port: OutboundPort, NAT: NAT, -- cgit v1.2.3 From 05b1ec008b771d9856e83a6269a5267eb18e1f51 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 11:42:01 +0100 Subject: Disabled ability to disable whisper. Closes #334 --- cmd/ethereum/flags.go | 2 +- cmd/ethereum/main.go | 2 +- cmd/mist/main.go | 1 + eth/backend.go | 6 +++++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index 1e6869a69..577bee442 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -132,7 +132,7 @@ func Init() { natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:)") ) flag.BoolVar(&Dial, "dial", true, "dial out connections (default on)") - flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)") + //flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)") flag.StringVar(&OutboundPort, "port", "30303", "listening port") flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap") diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 0dba462be..1ffd4b6e9 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -71,7 +71,7 @@ func main() { Port: OutboundPort, NAT: NAT, KeyRing: KeyRing, - Shh: SHH, + Shh: true, Dial: Dial, BootNodes: BootNodes, NodeKey: NodeKey, diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 32222fbef..14f561e99 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -60,6 +60,7 @@ func run() error { MaxPeers: MaxPeer, Port: OutboundPort, NAT: NAT, + Shh: true, BootNodes: BootNodes, NodeKey: NodeKey, KeyRing: KeyRing, diff --git a/eth/backend.go b/eth/backend.go index 690c7136d..d109ab98e 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -160,7 +160,11 @@ func New(config *Config) (*Ethereum, error) { eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify) ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool) - protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()} + protocols := []p2p.Protocol{ethProto} + if config.Shh { + protocols = append(protocols, eth.whisper.Protocol()) + } + netprv := config.NodeKey if netprv == nil { if netprv, err = crypto.GenerateKey(); err != nil { -- cgit v1.2.3 From be90ad89a89502ef3d2c0375d267b667618f5e7c Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 12:01:20 +0100 Subject: Disable turbo --- pow/ezp/pow.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pow/ezp/pow.go b/pow/ezp/pow.go index f4a8b80e5..540381243 100644 --- a/pow/ezp/pow.go +++ b/pow/ezp/pow.go @@ -21,7 +21,7 @@ type EasyPow struct { } func New() *EasyPow { - return &EasyPow{turbo: true} + return &EasyPow{turbo: false} } func (pow *EasyPow) GetHashrate() int64 { -- cgit v1.2.3 From 655e94259765b02454df93205a30a271103de5a0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 13:14:21 +0100 Subject: Added GetBlock GetUncle with OOB guard --- core/block_processor.go | 6 +++++- core/block_processor_test.go | 34 ++++++++++++++++++++++++++++++++++ core/chain_manager.go | 16 ++++++++-------- core/types/block.go | 12 ++++++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 core/block_processor_test.go diff --git a/core/block_processor.go b/core/block_processor.go index 893c586dd..b4449100f 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -250,7 +250,11 @@ func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error { } if block.Time() > time.Now().Unix() { - return fmt.Errorf("block time is in the future") + return BlockFutureErr + } + + if new(big.Int).Sub(block.Number(), parent.Number()).Cmp(big.NewInt(1)) != 0 { + return BlockNumberErr } // Verify the nonce of the block. Return an error if it's not valid diff --git a/core/block_processor_test.go b/core/block_processor_test.go new file mode 100644 index 000000000..35aeaa714 --- /dev/null +++ b/core/block_processor_test.go @@ -0,0 +1,34 @@ +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" +) + +func proc() (*BlockProcessor, *ChainManager) { + db, _ := ethdb.NewMemDatabase() + var mux event.TypeMux + + chainMan := NewChainManager(db, &mux) + return NewBlockProcessor(db, nil, chainMan, &mux), chainMan +} + +func TestNumber(t *testing.T) { + bp, chain := proc() + block1 := chain.NewBlock(nil) + block1.Header().Number = big.NewInt(3) + + err := bp.ValidateBlock(block1, chain.Genesis()) + if err != BlockNumberErr { + t.Errorf("expected block number error") + } + + block1 = chain.NewBlock(nil) + err = bp.ValidateBlock(block1, chain.Genesis()) + if err == BlockNumberErr { + t.Errorf("didn't expect block number error") + } +} diff --git a/core/chain_manager.go b/core/chain_manager.go index 22d54be03..286282064 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -87,6 +87,14 @@ type ChainManager struct { transState *state.StateDB } +func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { + bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux} + bc.setLastBlock() + bc.transState = bc.State().Copy() + + return bc +} + func (self *ChainManager) Td() *big.Int { self.mu.RLock() defer self.mu.RUnlock() @@ -108,14 +116,6 @@ func (self *ChainManager) CurrentBlock() *types.Block { return self.currentBlock } -func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { - bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux} - bc.setLastBlock() - bc.transState = bc.State().Copy() - - return bc -} - func (self *ChainManager) Status() (td *big.Int, currentBlock []byte, genesisBlock []byte) { self.mu.RLock() defer self.mu.RUnlock() diff --git a/core/types/block.go b/core/types/block.go index fa28f5cc7..d57de1311 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -185,6 +185,18 @@ func (self *Block) GasUsed() *big.Int { return self.header.GasUsed } func (self *Block) Root() []byte { return self.header.Root } func (self *Block) SetRoot(root []byte) { self.header.Root = root } func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) } +func (self *Block) GetTransaction(i int) *Transaction { + if len(self.transactions) > i { + return self.transactions[i] + } + return nil +} +func (self *Block) GetUncle(i int) *Header { + if len(self.uncles) > i { + return self.uncles[i] + } + return nil +} // Implement pow.Block func (self *Block) Difficulty() *big.Int { return self.header.Difficulty } -- cgit v1.2.3 From ee9df32dba5091069cbdad8d00dc15738d676d5b Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 16:08:51 +0100 Subject: Added errors --- core/error.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/error.go b/core/error.go index 11d8c1653..6af48ac2d 100644 --- a/core/error.go +++ b/core/error.go @@ -1,10 +1,16 @@ package core import ( + "errors" "fmt" "math/big" ) +var ( + BlockNumberErr = errors.New("block number invalid") + BlockFutureErr = errors.New("block time is in the future") +) + // Parent error. In case a parent is unknown this error will be thrown // by the block manager type ParentErr struct { -- cgit v1.2.3 From 487c5cc294d4c0506e50a026737be7f4cc94436f Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 17:18:07 +0100 Subject: Added WIP number package --- ethutil/number/int.go | 181 ++++++++++++++++++++++++++++++++++++++++++++ ethutil/number/uint_test.go | 92 ++++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 ethutil/number/int.go create mode 100644 ethutil/number/uint_test.go diff --git a/ethutil/number/int.go b/ethutil/number/int.go new file mode 100644 index 000000000..9a41fe3e5 --- /dev/null +++ b/ethutil/number/int.go @@ -0,0 +1,181 @@ +package number + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/ethutil" +) + +var tt256 = new(big.Int).Lsh(big.NewInt(1), 256) +var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1)) +var tt255 = new(big.Int).Lsh(big.NewInt(1), 255) + +func limitUnsigned256(x *Number) *Number { + x.num.And(x.num, tt256m1) + return x +} + +func limitSigned256(x *Number) *Number { + if x.num.Cmp(tt255) < 0 { + return x + } else { + x.num.Sub(x.num, tt256) + return x + } +} + +// Number function +type Initialiser func(n int64) *Number + +// A Number represents a generic integer with a bounding function limiter. Limit is called after each operations +// to give "fake" bounded integers. New types of Number can be created through NewInitialiser returning a lambda +// with the new Initialiser. +type Number struct { + num *big.Int + limit func(n *Number) *Number +} + +// Returns a new initialiser for a new *Number without having to expose certain fields +func NewInitialiser(limiter func(*Number) *Number) Initialiser { + return func(n int64) *Number { + return &Number{big.NewInt(n), limiter} + } +} + +// Return a Number with a UNSIGNED limiter up to 256 bits +func Uint256(n int64) *Number { + return &Number{big.NewInt(n), limitUnsigned256} +} + +// Return a Number with a SIGNED limiter up to 256 bits +func Int256(n int64) *Number { + return &Number{big.NewInt(n), limitSigned256} +} + +// Returns a Number with a SIGNED unlimited size +func Big(n int64) *Number { + return &Number{big.NewInt(n), func(x *Number) *Number { return x }} +} + +// Sets i to sum of x+y +func (i *Number) Add(x, y *Number) *Number { + i.num.Add(x.num, y.num) + return i.limit(i) +} + +// Sets i to difference of x-y +func (i *Number) Sub(x, y *Number) *Number { + i.num.Sub(x.num, y.num) + return i.limit(i) +} + +// Sets i to product of x*y +func (i *Number) Mul(x, y *Number) *Number { + i.num.Mul(x.num, y.num) + return i.limit(i) +} + +// Sets i to the quotient prodject of x/y +func (i *Number) Div(x, y *Number) *Number { + i.num.Div(x.num, y.num) + return i.limit(i) +} + +// Sets i to x % y +func (i *Number) Mod(x, y *Number) *Number { + i.num.Mod(x.num, y.num) + return i.limit(i) +} + +// Sets i to x << s +func (i *Number) Lsh(x *Number, s uint) *Number { + i.num.Lsh(x.num, s) + return i.limit(i) +} + +// Sets i to x^y +func (i *Number) Pow(x, y *Number) *Number { + i.num.Exp(x.num, y.num, big.NewInt(0)) + return i.limit(i) +} + +// Setters + +// Set x to i +func (i *Number) Set(x *Number) *Number { + i.num.Set(x.num) + return i.limit(i) +} + +// Set x bytes to i +func (i *Number) SetBytes(x []byte) *Number { + i.num.SetBytes(x) + return i.limit(i) +} + +// Cmp compares x and y and returns: +// +// -1 if x < y +// 0 if x == y +// +1 if x > y +func (i *Number) Cmp(x *Number) int { + return i.num.Cmp(x.num) +} + +// Getters + +// Returns the string representation of i +func (i *Number) String() string { + return i.num.String() +} + +// Returns the byte representation of i +func (i *Number) Bytes() []byte { + return i.num.Bytes() +} + +// Uint64 returns the Uint64 representation of x. If x cannot be represented in an int64, the result is undefined. +func (i *Number) Uint64() uint64 { + return i.num.Uint64() +} + +// Int64 returns the int64 representation of x. If x cannot be represented in an int64, the result is undefined. +func (i *Number) Int64() int64 { + return i.num.Int64() +} + +// Returns the signed version of i +func (i *Number) Int256() *Number { + return Int(0).Set(i) +} + +// Returns the unsigned version of i +func (i *Number) Uint256() *Number { + return Uint(0).Set(i) +} + +// Returns the index of the first bit that's set to 1 +func (i *Number) FirstBitSet() int { + for j := 0; j < i.num.BitLen(); j++ { + if i.num.Bit(j) > 0 { + return j + } + } + + return i.num.BitLen() +} + +// Variables + +var ( + Zero = Uint(0) + One = Uint(1) + Two = Uint(2) + MaxUint256 = Uint(0).SetBytes(ethutil.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) + + MinOne = Int(-1) + + // "typedefs" + Uint = Uint256 + Int = Int256 +) diff --git a/ethutil/number/uint_test.go b/ethutil/number/uint_test.go new file mode 100644 index 000000000..c42989465 --- /dev/null +++ b/ethutil/number/uint_test.go @@ -0,0 +1,92 @@ +package number + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/ethutil" +) + +func TestSet(t *testing.T) { + a := Uint(0) + b := Uint(10) + a.Set(b) + if a.num.Cmp(b.num) != 0 { + t.Error("didn't compare", a, b) + } + + c := Uint(0).SetBytes(ethutil.Hex2Bytes("0a")) + if c.num.Cmp(big.NewInt(10)) != 0 { + t.Error("c set bytes failed.") + } +} + +func TestInitialiser(t *testing.T) { + check := false + init := NewInitialiser(func(x *Number) *Number { + check = true + return x + }) + a := init(0).Add(init(1), init(2)) + if a.Cmp(init(3)) != 0 { + t.Error("expected 3. got", a) + } + if !check { + t.Error("expected limiter to be called") + } +} + +func TestGet(t *testing.T) { + a := Uint(10) + if a.Uint64() != 10 { + t.Error("expected to get 10. got", a.Uint64()) + } + + a = Uint(10) + if a.Int64() != 10 { + t.Error("expected to get 10. got", a.Int64()) + } +} + +func TestCmp(t *testing.T) { + a := Uint(10) + b := Uint(10) + c := Uint(11) + + if a.Cmp(b) != 0 { + t.Error("a b == 0 failed", a, b) + } + + if a.Cmp(c) >= 0 { + t.Error("a c < 0 failed", a, c) + } + + if c.Cmp(b) <= 0 { + t.Error("c b > 0 failed", c, b) + } +} + +func TestMaxArith(t *testing.T) { + a := Uint(0).Add(MaxUint256, One) + if a.Cmp(Zero) != 0 { + t.Error("expected max256 + 1 = 0 got", a) + } + + a = Uint(0).Sub(Uint(0), One) + if a.Cmp(MaxUint256) != 0 { + t.Error("expected 0 - 1 = max256 got", a) + } + + a = Int(0).Sub(Int(0), One) + if a.Cmp(MinOne) != 0 { + t.Error("expected 0 - 1 = -1 got", a) + } +} + +func TestConversion(t *testing.T) { + a := Int(-1) + b := a.Uint256() + if b.Cmp(MaxUint256) != 0 { + t.Error("expected -1 => unsigned to return max. got", b) + } +} -- cgit v1.2.3 From 5aff8bfb5918e53ba2590b25e6c17e1875870f6a Mon Sep 17 00:00:00 2001 From: Maran Date: Thu, 19 Feb 2015 10:38:36 +0100 Subject: Implement command line argument to set the amount of agents created by the miner Defaults to the amount of cores available on the CPU --- cmd/mist/flags.go | 3 +++ cmd/mist/main.go | 27 ++++++++++++++------------- cmd/utils/cmd.go | 2 +- eth/backend.go | 4 +++- miner/miner.go | 4 ++-- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go index eb280f71b..d9487de9e 100644 --- a/cmd/mist/flags.go +++ b/cmd/mist/flags.go @@ -63,6 +63,7 @@ var ( DebugFile string LogLevel int VmType int + MinerThreads int ) // flags specific to gui client @@ -137,6 +138,8 @@ func Init() { flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap") flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") + flag.IntVar(&MinerThreads, "minerthreads", runtime.NumCPU(), "number of miner threads") + flag.Parse() var err error diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 14f561e99..d41aa34bf 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -52,19 +52,20 @@ func run() error { config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") ethereum, err := eth.New(ð.Config{ - Name: p2p.MakeName(ClientIdentifier, Version), - KeyStore: KeyStore, - DataDir: Datadir, - LogFile: LogFile, - LogLevel: LogLevel, - MaxPeers: MaxPeer, - Port: OutboundPort, - NAT: NAT, - Shh: true, - BootNodes: BootNodes, - NodeKey: NodeKey, - KeyRing: KeyRing, - Dial: true, + Name: p2p.MakeName(ClientIdentifier, Version), + KeyStore: KeyStore, + DataDir: Datadir, + LogFile: LogFile, + LogLevel: LogLevel, + MaxPeers: MaxPeer, + Port: OutboundPort, + NAT: NAT, + Shh: true, + BootNodes: BootNodes, + NodeKey: NodeKey, + KeyRing: KeyRing, + Dial: true, + MinerThreads: MinerThreads, }) if err != nil { mainlogger.Fatalln(err) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index ecb847fc3..d252f3ab2 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -225,7 +225,7 @@ func StartMining(ethereum *eth.Ethereum) bool { go func() { clilogger.Infoln("Start mining") if gminer == nil { - gminer = miner.New(addr, ethereum) + gminer = miner.New(addr, ethereum, 4) } gminer.Start() }() diff --git a/eth/backend.go b/eth/backend.go index d109ab98e..05d84cae8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -53,6 +53,8 @@ type Config struct { Shh bool Dial bool + MinerThreads int + KeyManager *crypto.KeyManager } @@ -153,7 +155,7 @@ func New(config *Config) (*Ethereum, error) { eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux()) eth.chainManager.SetProcessor(eth.blockProcessor) eth.whisper = whisper.New() - eth.miner = miner.New(keyManager.Address(), eth) + eth.miner = miner.New(keyManager.Address(), eth, config.MinerThreads) hasBlock := eth.chainManager.HasBlock insertChain := eth.chainManager.InsertChain diff --git a/miner/miner.go b/miner/miner.go index 27afcf684..0cc2361c8 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -20,13 +20,13 @@ type Miner struct { mining bool } -func New(coinbase []byte, eth core.Backend) *Miner { +func New(coinbase []byte, eth core.Backend, minerThreads int) *Miner { miner := &Miner{ Coinbase: coinbase, worker: newWorker(coinbase, eth), } - for i := 0; i < 4; i++ { + for i := 0; i < minerThreads; i++ { miner.worker.register(NewCpuMiner(i, ezp.New())) } -- cgit v1.2.3 From fdecc11128596eadc00e7a7d81b856d844396c37 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Feb 2015 11:09:46 +0100 Subject: Temp fix for #342 --- vm/vm.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vm/vm.go b/vm/vm.go index 29e1ade54..5ec507ddc 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -266,7 +266,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1) // Not needed - //base = U256(base) + base = U256(base) stack.Push(base) case LT: @@ -532,7 +532,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I case NUMBER: number := self.env.BlockNumber() - stack.Push(number) + stack.Push(U256(number)) self.Printf(" => 0x%x", number.Bytes()) case DIFFICULTY: @@ -676,6 +676,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I gas := stack.Pop() // Pop gas and value of the stack. value, addr := stack.Popn() + value = U256(value) // Pop input size and offset inSize, inOffset := stack.Popn() // Pop return size and offset -- cgit v1.2.3 From 03b8c6841be08f19db0f98cea6d0a6f4fd64736f Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Feb 2015 11:49:58 +0100 Subject: Topics => Topic. Closes #343 --- rpc/args.go | 2 +- rpc/message.go | 17 +---------------- rpc/packages.go | 10 +++++----- 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 429b385d5..f730819fd 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -289,7 +289,7 @@ type WhisperMessageArgs struct { Payload string To string From string - Topics []string + Topic []string Priority uint32 Ttl uint32 } diff --git a/rpc/message.go b/rpc/message.go index b5b852f54..d96c35d7e 100644 --- a/rpc/message.go +++ b/rpc/message.go @@ -231,21 +231,6 @@ func (req *RpcRequest) ToFilterStringArgs() (string, error) { return args, nil } -func (req *RpcRequest) ToFilterChangedArgs() (int, error) { - if len(req.Params) < 1 { - return 0, NewErrorResponse(ErrorArguments) - } - - var id int - r := bytes.NewReader(req.Params[0]) - err := json.NewDecoder(r).Decode(&id) - if err != nil { - return 0, NewErrorResponse(ErrorDecodeArgs) - } - rpclogger.DebugDetailf("%T %v", id, id) - return id, nil -} - func (req *RpcRequest) ToDbPutArgs() (*DbArgs, error) { if len(req.Params) < 3 { return nil, NewErrorResponse(ErrorArguments) @@ -301,7 +286,7 @@ func (req *RpcRequest) ToWhisperFilterArgs() (*xeth.Options, error) { return &args, nil } -func (req *RpcRequest) ToWhisperIdArgs() (int, error) { +func (req *RpcRequest) ToIdArgs() (int, error) { if len(req.Params) < 1 { return 0, NewErrorResponse(ErrorArguments) } diff --git a/rpc/packages.go b/rpc/packages.go index 8aa604aa5..7044d9d12 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -349,7 +349,7 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { } func (p *EthereumApi) WhisperPost(args *WhisperMessageArgs, reply *interface{}) error { - err := p.xeth.Whisper().Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl) + err := p.xeth.Whisper().Post(args.Payload, args.To, args.From, args.Topic, args.Priority, args.Ttl) if err != nil { return err } @@ -445,13 +445,13 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } return p.NewFilterString(args, reply) case "eth_changed": - args, err := req.ToFilterChangedArgs() + args, err := req.ToIdArgs() if err != nil { return err } return p.FilterChanged(args, reply) case "eth_filterLogs": - args, err := req.ToFilterChangedArgs() + args, err := req.ToIdArgs() if err != nil { return err } @@ -504,7 +504,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } return p.NewWhisperFilter(args, reply) case "shh_changed": - args, err := req.ToWhisperIdArgs() + args, err := req.ToIdArgs() if err != nil { return err } @@ -522,7 +522,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } return p.HasWhisperIdentity(args, reply) case "shh_getMessages": - args, err := req.ToWhisperIdArgs() + args, err := req.ToIdArgs() if err != nil { return err } -- cgit v1.2.3 From 0057bb4ef6d55b5d580a4e0421526a477ef93de9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Feb 2015 11:51:38 +0100 Subject: WIP QT Clipboard --- cmd/mist/assets/qml/main.qml | 1 + cmd/mist/gui.go | 1 + rpc/util.go | 6 +++--- ui/qt/clipboard/capi.hpp | 11 +++++++++++ ui/qt/clipboard/clipboard.cpp | 20 ++++++++++++++++++++ ui/qt/clipboard/clipboard.go | 15 +++++++++++++++ ui/qt/clipboard/clipboard.hpp | 23 +++++++++++++++++++++++ xeth/types.go | 2 +- 8 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 ui/qt/clipboard/capi.hpp create mode 100644 ui/qt/clipboard/clipboard.cpp create mode 100644 ui/qt/clipboard/clipboard.go create mode 100644 ui/qt/clipboard/clipboard.hpp diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index f9bfd9b8d..5f7f05d83 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -246,6 +246,7 @@ ApplicationWindow { } } } + } property var blockModel: ListModel { diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index c9419473c..1e3efd269 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -131,6 +131,7 @@ func (gui *Gui) Start(assetPath string) { context.SetVar("gui", gui) context.SetVar("eth", gui.uiLib) context.SetVar("shh", gui.whisper) + //clipboard.SetQMLClipboard(context) win, err := gui.showWallet(context) if err != nil { diff --git a/rpc/util.go b/rpc/util.go index 679d83754..366e315ac 100644 --- a/rpc/util.go +++ b/rpc/util.go @@ -80,7 +80,7 @@ type RpcServer interface { type Log struct { Address string `json:"address"` - Topics []string `json:"topics"` + Topic []string `json:"topics"` Data string `json:"data"` } @@ -89,11 +89,11 @@ func toLogs(logs state.Logs) (ls []Log) { for i, log := range logs { var l Log - l.Topics = make([]string, len(log.Topics())) + l.Topic = make([]string, len(log.Topics())) l.Address = toHex(log.Address()) l.Data = toHex(log.Data()) for j, topic := range log.Topics() { - l.Topics[j] = toHex(topic) + l.Topic[j] = toHex(topic) } ls[i] = l } diff --git a/ui/qt/clipboard/capi.hpp b/ui/qt/clipboard/capi.hpp new file mode 100644 index 000000000..202613469 --- /dev/null +++ b/ui/qt/clipboard/capi.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "clipboard.hpp" + +typedef void Clipboard_; + +Clipboard_ *initClipboard() +{ + Clipboard *clipboard = new(Clipboard); + return static_cast(clipboard); +} diff --git a/ui/qt/clipboard/clipboard.cpp b/ui/qt/clipboard/clipboard.cpp new file mode 100644 index 000000000..192aa7a2b --- /dev/null +++ b/ui/qt/clipboard/clipboard.cpp @@ -0,0 +1,20 @@ +#include "clipboard.h" + +#include + +Clipboard::Clipboard() +{ + connect(QApplication::clipboard(), &QClipboard::dataChanged, [this] { emit clipboardChanged();}); +} + +QString Clipboard::get() const +{ + QClipboard *clipboard = QApplication::clipboard(); + return clipboard->text(); +} + +void Clipboard::toClipboard(QString _text) +{ + QClipboard *clipboard = QApplicationion::clipboard(); + clipboard->setText(_text); +} diff --git a/ui/qt/clipboard/clipboard.go b/ui/qt/clipboard/clipboard.go new file mode 100644 index 000000000..064ee954d --- /dev/null +++ b/ui/qt/clipboard/clipboard.go @@ -0,0 +1,15 @@ +package clipboard + +// #cgo CPPFLAGS: -I./ +// #cgo CXXFLAGS: -std=c++0x -pedantic-errors -Wall -fno-strict-aliasing +// #cgo LDFLAGS: -lstdc++ +// #cgo pkg-config: Qt5Quick +// +// #include "capi.hpp" +import "C" + +import "github.com/obscuren/qml" + +func SetQMLClipboard(context *qml.Context) { + context.SetVar("clipboard", (unsafe.Pointer)(C.initClipboard())) +} diff --git a/ui/qt/clipboard/clipboard.hpp b/ui/qt/clipboard/clipboard.hpp new file mode 100644 index 000000000..1aa213ceb --- /dev/null +++ b/ui/qt/clipboard/clipboard.hpp @@ -0,0 +1,23 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +class Clipboard : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString get READ get WRITE toClipboard NOTIFY clipboardChanged) +public: + Clipboard(); + virtual ~Clipboard(){} + + Q_INVOKABLE void toClipboard(QString _text); + +signals: + void clipboardChanged(); +}; + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/xeth/types.go b/xeth/types.go index a903fccbb..5b2d16018 100644 --- a/xeth/types.go +++ b/xeth/types.go @@ -150,7 +150,7 @@ type Transaction struct { func NewTx(tx *types.Transaction) *Transaction { hash := toHex(tx.Hash()) receiver := toHex(tx.To()) - if receiver == "0000000000000000000000000000000000000000" { + if len(receiver) == 0 { receiver = toHex(core.AddressFromMessage(tx)) } sender := toHex(tx.From()) -- cgit v1.2.3 From dba4f3122e83a66edc1fa089c5d69f789b07a6b3 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Feb 2015 13:21:37 +0100 Subject: Added uninstall filter methods --- rpc/message.go | 15 +++++++++++++++ rpc/packages.go | 13 +++++++++++++ 2 files changed, 28 insertions(+) diff --git a/rpc/message.go b/rpc/message.go index b5b852f54..524d7fc84 100644 --- a/rpc/message.go +++ b/rpc/message.go @@ -231,6 +231,21 @@ func (req *RpcRequest) ToFilterStringArgs() (string, error) { return args, nil } +func (req *RpcRequest) ToUninstallFilterArgs() (int, error) { + if len(req.Params) < 1 { + return 0, NewErrorResponse(ErrorArguments) + } + + var args int + err := json.Unmarshal(req.Params[0], &args) + if err != nil { + return 0, NewErrorResponse(ErrorDecodeArgs) + } + + rpclogger.DebugDetailf("%T %v", args, args) + return args, nil +} + func (req *RpcRequest) ToFilterChangedArgs() (int, error) { if len(req.Params) < 1 { return 0, NewErrorResponse(ErrorArguments) diff --git a/rpc/packages.go b/rpc/packages.go index 8aa604aa5..216321dba 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -105,6 +105,13 @@ func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) erro return nil } +func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { + delete(self.logs, id) + self.filterManager.UninstallFilter(id) + *reply = true + return nil +} + func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error { var id int filter := core.NewFilter(self.xeth.Backend()) @@ -444,6 +451,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } return p.NewFilterString(args, reply) + case "eth_uninstallFilter": + args, err := req.ToUninstallFilterArgs() + if err != nil { + return err + } + return p.UninstallFilter(args, reply) case "eth_changed": args, err := req.ToFilterChangedArgs() if err != nil { -- cgit v1.2.3 From c14071df9da4ab3f5b372293e87184af9b91c09e Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Feb 2015 13:34:27 +0100 Subject: Reset storage cache after sync --- state/state_object.go | 1 + 1 file changed, 1 insertion(+) diff --git a/state/state_object.go b/state/state_object.go index 0c157403c..eaa91c713 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -152,6 +152,7 @@ func (self *StateObject) Sync() { self.setAddr([]byte(key), value) } + self.storage = make(Storage) } func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value { -- cgit v1.2.3 From 73f94f37559ca0c8739c7dddeaf46d36827fdf30 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Feb 2015 01:52:03 +0100 Subject: p2p: disable encryption handshake The diff is a bit bigger than expected because the protocol handshake logic has moved out of Peer. This is necessary because the protocol handshake will have custom framing in the final protocol. --- p2p/crypto.go | 363 ----------------------------------------- p2p/crypto_test.go | 167 ------------------- p2p/handshake.go | 434 ++++++++++++++++++++++++++++++++++++++++++++++++++ p2p/handshake_test.go | 224 ++++++++++++++++++++++++++ p2p/message.go | 2 +- p2p/peer.go | 229 +++++++------------------- p2p/peer_test.go | 105 +++--------- p2p/server.go | 38 +++-- p2p/server_test.go | 12 +- 9 files changed, 767 insertions(+), 807 deletions(-) delete mode 100644 p2p/crypto.go delete mode 100644 p2p/crypto_test.go create mode 100644 p2p/handshake.go create mode 100644 p2p/handshake_test.go diff --git a/p2p/crypto.go b/p2p/crypto.go deleted file mode 100644 index 7e4b43712..000000000 --- a/p2p/crypto.go +++ /dev/null @@ -1,363 +0,0 @@ -package p2p - -import ( - // "binary" - "crypto/ecdsa" - "crypto/rand" - "fmt" - "io" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/ecies" - "github.com/ethereum/go-ethereum/crypto/secp256k1" - ethlogger "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/p2p/discover" -) - -var clogger = ethlogger.NewLogger("CRYPTOID") - -const ( - sskLen = 16 // ecies.MaxSharedKeyLength(pubKey) / 2 - sigLen = 65 // elliptic S256 - pubLen = 64 // 512 bit pubkey in uncompressed representation without format byte - shaLen = 32 // hash length (for nonce etc) - - authMsgLen = sigLen + shaLen + pubLen + shaLen + 1 - authRespLen = pubLen + shaLen + 1 - - eciesBytes = 65 + 16 + 32 - iHSLen = authMsgLen + eciesBytes // size of the final ECIES payload sent as initiator's handshake - rHSLen = authRespLen + eciesBytes // size of the final ECIES payload sent as receiver's handshake -) - -type hexkey []byte - -func (self hexkey) String() string { - return fmt.Sprintf("(%d) %x", len(self), []byte(self)) -} - -func encHandshake(conn io.ReadWriter, prv *ecdsa.PrivateKey, dial *discover.Node) ( - remoteID discover.NodeID, - sessionToken []byte, - err error, -) { - if dial == nil { - var remotePubkey []byte - sessionToken, remotePubkey, err = inboundEncHandshake(conn, prv, nil) - copy(remoteID[:], remotePubkey) - } else { - remoteID = dial.ID - sessionToken, err = outboundEncHandshake(conn, prv, remoteID[:], nil) - } - return remoteID, sessionToken, err -} - -// outboundEncHandshake negotiates a session token on conn. -// it should be called on the dialing side of the connection. -// -// privateKey is the local client's private key -// remotePublicKey is the remote peer's node ID -// sessionToken is the token from a previous session with this node. -func outboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, remotePublicKey []byte, sessionToken []byte) ( - newSessionToken []byte, - err error, -) { - auth, initNonce, randomPrivKey, err := authMsg(prvKey, remotePublicKey, sessionToken) - if err != nil { - return nil, err - } - if sessionToken != nil { - clogger.Debugf("session-token: %v", hexkey(sessionToken)) - } - - clogger.Debugf("initiator-nonce: %v", hexkey(initNonce)) - clogger.Debugf("initiator-random-private-key: %v", hexkey(crypto.FromECDSA(randomPrivKey))) - randomPublicKeyS, _ := exportPublicKey(&randomPrivKey.PublicKey) - clogger.Debugf("initiator-random-public-key: %v", hexkey(randomPublicKeyS)) - if _, err = conn.Write(auth); err != nil { - return nil, err - } - clogger.Debugf("initiator handshake: %v", hexkey(auth)) - - response := make([]byte, rHSLen) - if _, err = io.ReadFull(conn, response); err != nil { - return nil, err - } - recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prvKey) - if err != nil { - return nil, err - } - - clogger.Debugf("receiver-nonce: %v", hexkey(recNonce)) - remoteRandomPubKeyS, _ := exportPublicKey(remoteRandomPubKey) - clogger.Debugf("receiver-random-public-key: %v", hexkey(remoteRandomPubKeyS)) - return newSession(initNonce, recNonce, randomPrivKey, remoteRandomPubKey) -} - -// authMsg creates the initiator handshake. -func authMsg(prvKey *ecdsa.PrivateKey, remotePubKeyS, sessionToken []byte) ( - auth, initNonce []byte, - randomPrvKey *ecdsa.PrivateKey, - err error, -) { - // session init, common to both parties - remotePubKey, err := importPublicKey(remotePubKeyS) - if err != nil { - return - } - - var tokenFlag byte // = 0x00 - if sessionToken == nil { - // no session token found means we need to generate shared secret. - // ecies shared secret is used as initial session token for new peers - // generate shared key from prv and remote pubkey - if sessionToken, err = ecies.ImportECDSA(prvKey).GenerateShared(ecies.ImportECDSAPublic(remotePubKey), sskLen, sskLen); err != nil { - return - } - // tokenFlag = 0x00 // redundant - } else { - // for known peers, we use stored token from the previous session - tokenFlag = 0x01 - } - - //E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0) - // E(remote-pubk, S(ecdhe-random, token^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x1) - // allocate msgLen long message, - var msg []byte = make([]byte, authMsgLen) - initNonce = msg[authMsgLen-shaLen-1 : authMsgLen-1] - if _, err = rand.Read(initNonce); err != nil { - return - } - // create known message - // ecdh-shared-secret^nonce for new peers - // token^nonce for old peers - var sharedSecret = xor(sessionToken, initNonce) - - // generate random keypair to use for signing - if randomPrvKey, err = crypto.GenerateKey(); err != nil { - return - } - // sign shared secret (message known to both parties): shared-secret - var signature []byte - // signature = sign(ecdhe-random, shared-secret) - // uses secp256k1.Sign - if signature, err = crypto.Sign(sharedSecret, randomPrvKey); err != nil { - return - } - - // message - // signed-shared-secret || H(ecdhe-random-pubk) || pubk || nonce || 0x0 - copy(msg, signature) // copy signed-shared-secret - // H(ecdhe-random-pubk) - var randomPubKey64 []byte - if randomPubKey64, err = exportPublicKey(&randomPrvKey.PublicKey); err != nil { - return - } - var pubKey64 []byte - if pubKey64, err = exportPublicKey(&prvKey.PublicKey); err != nil { - return - } - copy(msg[sigLen:sigLen+shaLen], crypto.Sha3(randomPubKey64)) - // pubkey copied to the correct segment. - copy(msg[sigLen+shaLen:sigLen+shaLen+pubLen], pubKey64) - // nonce is already in the slice - // stick tokenFlag byte to the end - msg[authMsgLen-1] = tokenFlag - - // encrypt using remote-pubk - // auth = eciesEncrypt(remote-pubk, msg) - if auth, err = crypto.Encrypt(remotePubKey, msg); err != nil { - return - } - return -} - -// completeHandshake is called when the initiator receives an -// authentication response (aka receiver handshake). It completes the -// handshake by reading off parameters the remote peer provides needed -// to set up the secure session. -func completeHandshake(auth []byte, prvKey *ecdsa.PrivateKey) ( - respNonce []byte, - remoteRandomPubKey *ecdsa.PublicKey, - tokenFlag bool, - err error, -) { - var msg []byte - // they prove that msg is meant for me, - // I prove I possess private key if i can read it - if msg, err = crypto.Decrypt(prvKey, auth); err != nil { - return - } - - respNonce = msg[pubLen : pubLen+shaLen] - var remoteRandomPubKeyS = msg[:pubLen] - if remoteRandomPubKey, err = importPublicKey(remoteRandomPubKeyS); err != nil { - return - } - if msg[authRespLen-1] == 0x01 { - tokenFlag = true - } - return -} - -// inboundEncHandshake negotiates a session token on conn. -// it should be called on the listening side of the connection. -// -// privateKey is the local client's private key -// sessionToken is the token from a previous session with this node. -func inboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, sessionToken []byte) ( - token, remotePubKey []byte, - err error, -) { - // we are listening connection. we are responders in the - // handshake. Extract info from the authentication. The initiator - // starts by sending us a handshake that we need to respond to. so - // we read auth message first, then respond. - auth := make([]byte, iHSLen) - if _, err := io.ReadFull(conn, auth); err != nil { - return nil, nil, err - } - response, recNonce, initNonce, remotePubKey, randomPrivKey, remoteRandomPubKey, err := authResp(auth, sessionToken, prvKey) - if err != nil { - return nil, nil, err - } - clogger.Debugf("receiver-nonce: %v", hexkey(recNonce)) - clogger.Debugf("receiver-random-priv-key: %v", hexkey(crypto.FromECDSA(randomPrivKey))) - if _, err = conn.Write(response); err != nil { - return nil, nil, err - } - clogger.Debugf("receiver handshake:\n%v", hexkey(response)) - token, err = newSession(initNonce, recNonce, randomPrivKey, remoteRandomPubKey) - return token, remotePubKey, err -} - -// authResp is called by peer if it accepted (but not -// initiated) the connection from the remote. It is passed the initiator -// handshake received and the session token belonging to the -// remote initiator. -// -// The first return value is the authentication response (aka receiver -// handshake) that is to be sent to the remote initiator. -func authResp(auth, sessionToken []byte, prvKey *ecdsa.PrivateKey) ( - authResp, respNonce, initNonce, remotePubKeyS []byte, - randomPrivKey *ecdsa.PrivateKey, - remoteRandomPubKey *ecdsa.PublicKey, - err error, -) { - // they prove that msg is meant for me, - // I prove I possess private key if i can read it - msg, err := crypto.Decrypt(prvKey, auth) - if err != nil { - return - } - - remotePubKeyS = msg[sigLen+shaLen : sigLen+shaLen+pubLen] - remotePubKey, _ := importPublicKey(remotePubKeyS) - - var tokenFlag byte - if sessionToken == nil { - // no session token found means we need to generate shared secret. - // ecies shared secret is used as initial session token for new peers - // generate shared key from prv and remote pubkey - if sessionToken, err = ecies.ImportECDSA(prvKey).GenerateShared(ecies.ImportECDSAPublic(remotePubKey), sskLen, sskLen); err != nil { - return - } - // tokenFlag = 0x00 // redundant - } else { - // for known peers, we use stored token from the previous session - tokenFlag = 0x01 - } - - // the initiator nonce is read off the end of the message - initNonce = msg[authMsgLen-shaLen-1 : authMsgLen-1] - // I prove that i own prv key (to derive shared secret, and read - // nonce off encrypted msg) and that I own shared secret they - // prove they own the private key belonging to ecdhe-random-pubk - // we can now reconstruct the signed message and recover the peers - // pubkey - var signedMsg = xor(sessionToken, initNonce) - var remoteRandomPubKeyS []byte - if remoteRandomPubKeyS, err = secp256k1.RecoverPubkey(signedMsg, msg[:sigLen]); err != nil { - return - } - // convert to ECDSA standard - if remoteRandomPubKey, err = importPublicKey(remoteRandomPubKeyS); err != nil { - return - } - - // now we find ourselves a long task too, fill it random - var resp = make([]byte, authRespLen) - // generate shaLen long nonce - respNonce = resp[pubLen : pubLen+shaLen] - if _, err = rand.Read(respNonce); err != nil { - return - } - // generate random keypair for session - if randomPrivKey, err = crypto.GenerateKey(); err != nil { - return - } - // responder auth message - // E(remote-pubk, ecdhe-random-pubk || nonce || 0x0) - var randomPubKeyS []byte - if randomPubKeyS, err = exportPublicKey(&randomPrivKey.PublicKey); err != nil { - return - } - copy(resp[:pubLen], randomPubKeyS) - // nonce is already in the slice - resp[authRespLen-1] = tokenFlag - - // encrypt using remote-pubk - // auth = eciesEncrypt(remote-pubk, msg) - // why not encrypt with ecdhe-random-remote - if authResp, err = crypto.Encrypt(remotePubKey, resp); err != nil { - return - } - return -} - -// newSession is called after the handshake is completed. The -// arguments are values negotiated in the handshake. The return value -// is a new session Token to be remembered for the next time we -// connect with this peer. -func newSession(initNonce, respNonce []byte, privKey *ecdsa.PrivateKey, remoteRandomPubKey *ecdsa.PublicKey) ([]byte, error) { - // 3) Now we can trust ecdhe-random-pubk to derive new keys - //ecdhe-shared-secret = ecdh.agree(ecdhe-random, remote-ecdhe-random-pubk) - pubKey := ecies.ImportECDSAPublic(remoteRandomPubKey) - dhSharedSecret, err := ecies.ImportECDSA(privKey).GenerateShared(pubKey, sskLen, sskLen) - if err != nil { - return nil, err - } - sharedSecret := crypto.Sha3(dhSharedSecret, crypto.Sha3(respNonce, initNonce)) - sessionToken := crypto.Sha3(sharedSecret) - return sessionToken, nil -} - -// importPublicKey unmarshals 512 bit public keys. -func importPublicKey(pubKey []byte) (pubKeyEC *ecdsa.PublicKey, err error) { - var pubKey65 []byte - switch len(pubKey) { - case 64: - // add 'uncompressed key' flag - pubKey65 = append([]byte{0x04}, pubKey...) - case 65: - pubKey65 = pubKey - default: - return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey)) - } - return crypto.ToECDSAPub(pubKey65), nil -} - -func exportPublicKey(pubKeyEC *ecdsa.PublicKey) (pubKey []byte, err error) { - if pubKeyEC == nil { - return nil, fmt.Errorf("no ECDSA public key given") - } - return crypto.FromECDSAPub(pubKeyEC)[1:], nil -} - -func xor(one, other []byte) (xor []byte) { - xor = make([]byte, len(one)) - for i := 0; i < len(one); i++ { - xor[i] = one[i] ^ other[i] - } - return xor -} diff --git a/p2p/crypto_test.go b/p2p/crypto_test.go deleted file mode 100644 index 6cf0f4818..000000000 --- a/p2p/crypto_test.go +++ /dev/null @@ -1,167 +0,0 @@ -package p2p - -import ( - "bytes" - "crypto/ecdsa" - "crypto/rand" - "net" - "testing" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/ecies" -) - -func TestPublicKeyEncoding(t *testing.T) { - prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader) - pub0 := &prv0.PublicKey - pub0s := crypto.FromECDSAPub(pub0) - pub1, err := importPublicKey(pub0s) - if err != nil { - t.Errorf("%v", err) - } - eciesPub1 := ecies.ImportECDSAPublic(pub1) - if eciesPub1 == nil { - t.Errorf("invalid ecdsa public key") - } - pub1s, err := exportPublicKey(pub1) - if err != nil { - t.Errorf("%v", err) - } - if len(pub1s) != 64 { - t.Errorf("wrong length expect 64, got", len(pub1s)) - } - pub2, err := importPublicKey(pub1s) - if err != nil { - t.Errorf("%v", err) - } - pub2s, err := exportPublicKey(pub2) - if err != nil { - t.Errorf("%v", err) - } - if !bytes.Equal(pub1s, pub2s) { - t.Errorf("exports dont match") - } - pub2sEC := crypto.FromECDSAPub(pub2) - if !bytes.Equal(pub0s, pub2sEC) { - t.Errorf("exports dont match") - } -} - -func TestSharedSecret(t *testing.T) { - prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader) - pub0 := &prv0.PublicKey - prv1, _ := crypto.GenerateKey() - pub1 := &prv1.PublicKey - - ss0, err := ecies.ImportECDSA(prv0).GenerateShared(ecies.ImportECDSAPublic(pub1), sskLen, sskLen) - if err != nil { - return - } - ss1, err := ecies.ImportECDSA(prv1).GenerateShared(ecies.ImportECDSAPublic(pub0), sskLen, sskLen) - if err != nil { - return - } - t.Logf("Secret:\n%v %x\n%v %x", len(ss0), ss0, len(ss0), ss1) - if !bytes.Equal(ss0, ss1) { - t.Errorf("dont match :(") - } -} - -func TestCryptoHandshake(t *testing.T) { - testCryptoHandshake(newkey(), newkey(), nil, t) -} - -func TestCryptoHandshakeWithToken(t *testing.T) { - sessionToken := make([]byte, shaLen) - rand.Read(sessionToken) - testCryptoHandshake(newkey(), newkey(), sessionToken, t) -} - -func testCryptoHandshake(prv0, prv1 *ecdsa.PrivateKey, sessionToken []byte, t *testing.T) { - var err error - // pub0 := &prv0.PublicKey - pub1 := &prv1.PublicKey - - // pub0s := crypto.FromECDSAPub(pub0) - pub1s := crypto.FromECDSAPub(pub1) - - // simulate handshake by feeding output to input - // initiator sends handshake 'auth' - auth, initNonce, randomPrivKey, err := authMsg(prv0, pub1s, sessionToken) - if err != nil { - t.Errorf("%v", err) - } - t.Logf("-> %v", hexkey(auth)) - - // receiver reads auth and responds with response - response, remoteRecNonce, remoteInitNonce, _, remoteRandomPrivKey, remoteInitRandomPubKey, err := authResp(auth, sessionToken, prv1) - if err != nil { - t.Errorf("%v", err) - } - t.Logf("<- %v\n", hexkey(response)) - - // initiator reads receiver's response and the key exchange completes - recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prv0) - if err != nil { - t.Errorf("completeHandshake error: %v", err) - } - - // now both parties should have the same session parameters - initSessionToken, err := newSession(initNonce, recNonce, randomPrivKey, remoteRandomPubKey) - if err != nil { - t.Errorf("newSession error: %v", err) - } - - recSessionToken, err := newSession(remoteInitNonce, remoteRecNonce, remoteRandomPrivKey, remoteInitRandomPubKey) - if err != nil { - t.Errorf("newSession error: %v", err) - } - - // fmt.Printf("\nauth (%v) %x\n\nresp (%v) %x\n\n", len(auth), auth, len(response), response) - - // fmt.Printf("\nauth %x\ninitNonce %x\nresponse%x\nremoteRecNonce %x\nremoteInitNonce %x\nremoteRandomPubKey %x\nrecNonce %x\nremoteInitRandomPubKey %x\ninitSessionToken %x\n\n", auth, initNonce, response, remoteRecNonce, remoteInitNonce, remoteRandomPubKey, recNonce, remoteInitRandomPubKey, initSessionToken) - - if !bytes.Equal(initNonce, remoteInitNonce) { - t.Errorf("nonces do not match") - } - if !bytes.Equal(recNonce, remoteRecNonce) { - t.Errorf("receiver nonces do not match") - } - if !bytes.Equal(initSessionToken, recSessionToken) { - t.Errorf("session tokens do not match") - } -} - -func TestHandshake(t *testing.T) { - defer testlog(t).detach() - - prv0, _ := crypto.GenerateKey() - prv1, _ := crypto.GenerateKey() - pub0s, _ := exportPublicKey(&prv0.PublicKey) - pub1s, _ := exportPublicKey(&prv1.PublicKey) - rw0, rw1 := net.Pipe() - tokens := make(chan []byte) - - go func() { - token, err := outboundEncHandshake(rw0, prv0, pub1s, nil) - if err != nil { - t.Errorf("outbound side error: %v", err) - } - tokens <- token - }() - go func() { - token, remotePubkey, err := inboundEncHandshake(rw1, prv1, nil) - if err != nil { - t.Errorf("inbound side error: %v", err) - } - if !bytes.Equal(remotePubkey, pub0s) { - t.Errorf("inbound side returned wrong remote pubkey\n got: %x\n want: %x", remotePubkey, pub0s) - } - tokens <- token - }() - - t1, t2 := <-tokens, <-tokens - if !bytes.Equal(t1, t2) { - t.Error("session token mismatch") - } -} diff --git a/p2p/handshake.go b/p2p/handshake.go new file mode 100644 index 000000000..614711eaf --- /dev/null +++ b/p2p/handshake.go @@ -0,0 +1,434 @@ +package p2p + +import ( + "crypto/ecdsa" + "crypto/rand" + "errors" + "fmt" + "io" + "net" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/ecies" + "github.com/ethereum/go-ethereum/crypto/secp256k1" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + sskLen = 16 // ecies.MaxSharedKeyLength(pubKey) / 2 + sigLen = 65 // elliptic S256 + pubLen = 64 // 512 bit pubkey in uncompressed representation without format byte + shaLen = 32 // hash length (for nonce etc) + + authMsgLen = sigLen + shaLen + pubLen + shaLen + 1 + authRespLen = pubLen + shaLen + 1 + + eciesBytes = 65 + 16 + 32 + iHSLen = authMsgLen + eciesBytes // size of the final ECIES payload sent as initiator's handshake + rHSLen = authRespLen + eciesBytes // size of the final ECIES payload sent as receiver's handshake +) + +type conn struct { + *frameRW + *protoHandshake +} + +func newConn(fd net.Conn, hs *protoHandshake) *conn { + return &conn{newFrameRW(fd, msgWriteTimeout), hs} +} + +// encHandshake represents information about the remote end +// of a connection that is negotiated during the encryption handshake. +type encHandshake struct { + ID discover.NodeID + IngressMAC []byte + EgressMAC []byte + Token []byte +} + +// protoHandshake is the RLP structure of the protocol handshake. +type protoHandshake struct { + Version uint64 + Name string + Caps []Cap + ListenPort uint64 + ID discover.NodeID +} + +// setupConn starts a protocol session on the given connection. +// It runs the encryption handshake and the protocol handshake. +// If dial is non-nil, the connection the local node is the initiator. +func setupConn(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake, dial *discover.Node) (*conn, error) { + if dial == nil { + return setupInboundConn(fd, prv, our) + } else { + return setupOutboundConn(fd, prv, our, dial) + } +} + +func setupInboundConn(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake) (*conn, error) { + // var remotePubkey []byte + // sessionToken, remotePubkey, err = inboundEncHandshake(fd, prv, nil) + // copy(remoteID[:], remotePubkey) + + rw := newFrameRW(fd, msgWriteTimeout) + rhs, err := readProtocolHandshake(rw, our) + if err != nil { + return nil, err + } + if err := writeProtocolHandshake(rw, our); err != nil { + return nil, fmt.Errorf("protocol write error: %v", err) + } + return &conn{rw, rhs}, nil +} + +func setupOutboundConn(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake, dial *discover.Node) (*conn, error) { + // remoteID = dial.ID + // sessionToken, err = outboundEncHandshake(fd, prv, remoteID[:], nil) + + rw := newFrameRW(fd, msgWriteTimeout) + if err := writeProtocolHandshake(rw, our); err != nil { + return nil, fmt.Errorf("protocol write error: %v", err) + } + rhs, err := readProtocolHandshake(rw, our) + if err != nil { + return nil, fmt.Errorf("protocol handshake read error: %v", err) + } + if rhs.ID != dial.ID { + return nil, errors.New("dialed node id mismatch") + } + return &conn{rw, rhs}, nil +} + +// outboundEncHandshake negotiates a session token on conn. +// it should be called on the dialing side of the connection. +// +// privateKey is the local client's private key +// remotePublicKey is the remote peer's node ID +// sessionToken is the token from a previous session with this node. +func outboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, remotePublicKey []byte, sessionToken []byte) ( + newSessionToken []byte, + err error, +) { + auth, initNonce, randomPrivKey, err := authMsg(prvKey, remotePublicKey, sessionToken) + if err != nil { + return nil, err + } + if _, err = conn.Write(auth); err != nil { + return nil, err + } + + response := make([]byte, rHSLen) + if _, err = io.ReadFull(conn, response); err != nil { + return nil, err + } + recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prvKey) + if err != nil { + return nil, err + } + + return newSession(initNonce, recNonce, randomPrivKey, remoteRandomPubKey) +} + +// authMsg creates the initiator handshake. +func authMsg(prvKey *ecdsa.PrivateKey, remotePubKeyS, sessionToken []byte) ( + auth, initNonce []byte, + randomPrvKey *ecdsa.PrivateKey, + err error, +) { + // session init, common to both parties + remotePubKey, err := importPublicKey(remotePubKeyS) + if err != nil { + return + } + + var tokenFlag byte // = 0x00 + if sessionToken == nil { + // no session token found means we need to generate shared secret. + // ecies shared secret is used as initial session token for new peers + // generate shared key from prv and remote pubkey + if sessionToken, err = ecies.ImportECDSA(prvKey).GenerateShared(ecies.ImportECDSAPublic(remotePubKey), sskLen, sskLen); err != nil { + return + } + // tokenFlag = 0x00 // redundant + } else { + // for known peers, we use stored token from the previous session + tokenFlag = 0x01 + } + + //E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0) + // E(remote-pubk, S(ecdhe-random, token^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x1) + // allocate msgLen long message, + var msg []byte = make([]byte, authMsgLen) + initNonce = msg[authMsgLen-shaLen-1 : authMsgLen-1] + if _, err = rand.Read(initNonce); err != nil { + return + } + // create known message + // ecdh-shared-secret^nonce for new peers + // token^nonce for old peers + var sharedSecret = xor(sessionToken, initNonce) + + // generate random keypair to use for signing + if randomPrvKey, err = crypto.GenerateKey(); err != nil { + return + } + // sign shared secret (message known to both parties): shared-secret + var signature []byte + // signature = sign(ecdhe-random, shared-secret) + // uses secp256k1.Sign + if signature, err = crypto.Sign(sharedSecret, randomPrvKey); err != nil { + return + } + + // message + // signed-shared-secret || H(ecdhe-random-pubk) || pubk || nonce || 0x0 + copy(msg, signature) // copy signed-shared-secret + // H(ecdhe-random-pubk) + var randomPubKey64 []byte + if randomPubKey64, err = exportPublicKey(&randomPrvKey.PublicKey); err != nil { + return + } + var pubKey64 []byte + if pubKey64, err = exportPublicKey(&prvKey.PublicKey); err != nil { + return + } + copy(msg[sigLen:sigLen+shaLen], crypto.Sha3(randomPubKey64)) + // pubkey copied to the correct segment. + copy(msg[sigLen+shaLen:sigLen+shaLen+pubLen], pubKey64) + // nonce is already in the slice + // stick tokenFlag byte to the end + msg[authMsgLen-1] = tokenFlag + + // encrypt using remote-pubk + // auth = eciesEncrypt(remote-pubk, msg) + if auth, err = crypto.Encrypt(remotePubKey, msg); err != nil { + return + } + return +} + +// completeHandshake is called when the initiator receives an +// authentication response (aka receiver handshake). It completes the +// handshake by reading off parameters the remote peer provides needed +// to set up the secure session. +func completeHandshake(auth []byte, prvKey *ecdsa.PrivateKey) ( + respNonce []byte, + remoteRandomPubKey *ecdsa.PublicKey, + tokenFlag bool, + err error, +) { + var msg []byte + // they prove that msg is meant for me, + // I prove I possess private key if i can read it + if msg, err = crypto.Decrypt(prvKey, auth); err != nil { + return + } + + respNonce = msg[pubLen : pubLen+shaLen] + var remoteRandomPubKeyS = msg[:pubLen] + if remoteRandomPubKey, err = importPublicKey(remoteRandomPubKeyS); err != nil { + return + } + if msg[authRespLen-1] == 0x01 { + tokenFlag = true + } + return +} + +// inboundEncHandshake negotiates a session token on conn. +// it should be called on the listening side of the connection. +// +// privateKey is the local client's private key +// sessionToken is the token from a previous session with this node. +func inboundEncHandshake(conn io.ReadWriter, prvKey *ecdsa.PrivateKey, sessionToken []byte) ( + token, remotePubKey []byte, + err error, +) { + // we are listening connection. we are responders in the + // handshake. Extract info from the authentication. The initiator + // starts by sending us a handshake that we need to respond to. so + // we read auth message first, then respond. + auth := make([]byte, iHSLen) + if _, err := io.ReadFull(conn, auth); err != nil { + return nil, nil, err + } + response, recNonce, initNonce, remotePubKey, randomPrivKey, remoteRandomPubKey, err := authResp(auth, sessionToken, prvKey) + if err != nil { + return nil, nil, err + } + if _, err = conn.Write(response); err != nil { + return nil, nil, err + } + token, err = newSession(initNonce, recNonce, randomPrivKey, remoteRandomPubKey) + return token, remotePubKey, err +} + +// authResp is called by peer if it accepted (but not +// initiated) the connection from the remote. It is passed the initiator +// handshake received and the session token belonging to the +// remote initiator. +// +// The first return value is the authentication response (aka receiver +// handshake) that is to be sent to the remote initiator. +func authResp(auth, sessionToken []byte, prvKey *ecdsa.PrivateKey) ( + authResp, respNonce, initNonce, remotePubKeyS []byte, + randomPrivKey *ecdsa.PrivateKey, + remoteRandomPubKey *ecdsa.PublicKey, + err error, +) { + // they prove that msg is meant for me, + // I prove I possess private key if i can read it + msg, err := crypto.Decrypt(prvKey, auth) + if err != nil { + return + } + + remotePubKeyS = msg[sigLen+shaLen : sigLen+shaLen+pubLen] + remotePubKey, _ := importPublicKey(remotePubKeyS) + + var tokenFlag byte + if sessionToken == nil { + // no session token found means we need to generate shared secret. + // ecies shared secret is used as initial session token for new peers + // generate shared key from prv and remote pubkey + if sessionToken, err = ecies.ImportECDSA(prvKey).GenerateShared(ecies.ImportECDSAPublic(remotePubKey), sskLen, sskLen); err != nil { + return + } + // tokenFlag = 0x00 // redundant + } else { + // for known peers, we use stored token from the previous session + tokenFlag = 0x01 + } + + // the initiator nonce is read off the end of the message + initNonce = msg[authMsgLen-shaLen-1 : authMsgLen-1] + // I prove that i own prv key (to derive shared secret, and read + // nonce off encrypted msg) and that I own shared secret they + // prove they own the private key belonging to ecdhe-random-pubk + // we can now reconstruct the signed message and recover the peers + // pubkey + var signedMsg = xor(sessionToken, initNonce) + var remoteRandomPubKeyS []byte + if remoteRandomPubKeyS, err = secp256k1.RecoverPubkey(signedMsg, msg[:sigLen]); err != nil { + return + } + // convert to ECDSA standard + if remoteRandomPubKey, err = importPublicKey(remoteRandomPubKeyS); err != nil { + return + } + + // now we find ourselves a long task too, fill it random + var resp = make([]byte, authRespLen) + // generate shaLen long nonce + respNonce = resp[pubLen : pubLen+shaLen] + if _, err = rand.Read(respNonce); err != nil { + return + } + // generate random keypair for session + if randomPrivKey, err = crypto.GenerateKey(); err != nil { + return + } + // responder auth message + // E(remote-pubk, ecdhe-random-pubk || nonce || 0x0) + var randomPubKeyS []byte + if randomPubKeyS, err = exportPublicKey(&randomPrivKey.PublicKey); err != nil { + return + } + copy(resp[:pubLen], randomPubKeyS) + // nonce is already in the slice + resp[authRespLen-1] = tokenFlag + + // encrypt using remote-pubk + // auth = eciesEncrypt(remote-pubk, msg) + // why not encrypt with ecdhe-random-remote + if authResp, err = crypto.Encrypt(remotePubKey, resp); err != nil { + return + } + return +} + +// newSession is called after the handshake is completed. The +// arguments are values negotiated in the handshake. The return value +// is a new session Token to be remembered for the next time we +// connect with this peer. +func newSession(initNonce, respNonce []byte, privKey *ecdsa.PrivateKey, remoteRandomPubKey *ecdsa.PublicKey) ([]byte, error) { + // 3) Now we can trust ecdhe-random-pubk to derive new keys + //ecdhe-shared-secret = ecdh.agree(ecdhe-random, remote-ecdhe-random-pubk) + pubKey := ecies.ImportECDSAPublic(remoteRandomPubKey) + dhSharedSecret, err := ecies.ImportECDSA(privKey).GenerateShared(pubKey, sskLen, sskLen) + if err != nil { + return nil, err + } + sharedSecret := crypto.Sha3(dhSharedSecret, crypto.Sha3(respNonce, initNonce)) + sessionToken := crypto.Sha3(sharedSecret) + return sessionToken, nil +} + +// importPublicKey unmarshals 512 bit public keys. +func importPublicKey(pubKey []byte) (pubKeyEC *ecdsa.PublicKey, err error) { + var pubKey65 []byte + switch len(pubKey) { + case 64: + // add 'uncompressed key' flag + pubKey65 = append([]byte{0x04}, pubKey...) + case 65: + pubKey65 = pubKey + default: + return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey)) + } + return crypto.ToECDSAPub(pubKey65), nil +} + +func exportPublicKey(pubKeyEC *ecdsa.PublicKey) (pubKey []byte, err error) { + if pubKeyEC == nil { + return nil, fmt.Errorf("no ECDSA public key given") + } + return crypto.FromECDSAPub(pubKeyEC)[1:], nil +} + +func xor(one, other []byte) (xor []byte) { + xor = make([]byte, len(one)) + for i := 0; i < len(one); i++ { + xor[i] = one[i] ^ other[i] + } + return xor +} + +func writeProtocolHandshake(w MsgWriter, our *protoHandshake) error { + return EncodeMsg(w, handshakeMsg, our.Version, our.Name, our.Caps, our.ListenPort, our.ID[:]) +} + +func readProtocolHandshake(r MsgReader, our *protoHandshake) (*protoHandshake, error) { + // read and handle remote handshake + msg, err := r.ReadMsg() + if err != nil { + return nil, err + } + if msg.Code == discMsg { + // disconnect before protocol handshake is valid according to the + // spec and we send it ourself if Server.addPeer fails. + var reason DiscReason + rlp.Decode(msg.Payload, &reason) + return nil, discRequestedError(reason) + } + if msg.Code != handshakeMsg { + return nil, fmt.Errorf("expected handshake, got %x", msg.Code) + } + if msg.Size > baseProtocolMaxMsgSize { + return nil, fmt.Errorf("message too big (%d > %d)", msg.Size, baseProtocolMaxMsgSize) + } + var hs protoHandshake + if err := msg.Decode(&hs); err != nil { + return nil, err + } + // validate handshake info + if hs.Version != our.Version { + return nil, newPeerError(errP2PVersionMismatch, "required version %d, received %d\n", baseProtocolVersion, hs.Version) + } + if (hs.ID == discover.NodeID{}) { + return nil, newPeerError(errPubkeyInvalid, "missing") + } + return &hs, nil +} diff --git a/p2p/handshake_test.go b/p2p/handshake_test.go new file mode 100644 index 000000000..06c6a6932 --- /dev/null +++ b/p2p/handshake_test.go @@ -0,0 +1,224 @@ +package p2p + +import ( + "bytes" + "crypto/ecdsa" + "crypto/rand" + "net" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/ecies" + "github.com/ethereum/go-ethereum/p2p/discover" +) + +func TestPublicKeyEncoding(t *testing.T) { + prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader) + pub0 := &prv0.PublicKey + pub0s := crypto.FromECDSAPub(pub0) + pub1, err := importPublicKey(pub0s) + if err != nil { + t.Errorf("%v", err) + } + eciesPub1 := ecies.ImportECDSAPublic(pub1) + if eciesPub1 == nil { + t.Errorf("invalid ecdsa public key") + } + pub1s, err := exportPublicKey(pub1) + if err != nil { + t.Errorf("%v", err) + } + if len(pub1s) != 64 { + t.Errorf("wrong length expect 64, got", len(pub1s)) + } + pub2, err := importPublicKey(pub1s) + if err != nil { + t.Errorf("%v", err) + } + pub2s, err := exportPublicKey(pub2) + if err != nil { + t.Errorf("%v", err) + } + if !bytes.Equal(pub1s, pub2s) { + t.Errorf("exports dont match") + } + pub2sEC := crypto.FromECDSAPub(pub2) + if !bytes.Equal(pub0s, pub2sEC) { + t.Errorf("exports dont match") + } +} + +func TestSharedSecret(t *testing.T) { + prv0, _ := crypto.GenerateKey() // = ecdsa.GenerateKey(crypto.S256(), rand.Reader) + pub0 := &prv0.PublicKey + prv1, _ := crypto.GenerateKey() + pub1 := &prv1.PublicKey + + ss0, err := ecies.ImportECDSA(prv0).GenerateShared(ecies.ImportECDSAPublic(pub1), sskLen, sskLen) + if err != nil { + return + } + ss1, err := ecies.ImportECDSA(prv1).GenerateShared(ecies.ImportECDSAPublic(pub0), sskLen, sskLen) + if err != nil { + return + } + t.Logf("Secret:\n%v %x\n%v %x", len(ss0), ss0, len(ss0), ss1) + if !bytes.Equal(ss0, ss1) { + t.Errorf("dont match :(") + } +} + +func TestCryptoHandshake(t *testing.T) { + testCryptoHandshake(newkey(), newkey(), nil, t) +} + +func TestCryptoHandshakeWithToken(t *testing.T) { + sessionToken := make([]byte, shaLen) + rand.Read(sessionToken) + testCryptoHandshake(newkey(), newkey(), sessionToken, t) +} + +func testCryptoHandshake(prv0, prv1 *ecdsa.PrivateKey, sessionToken []byte, t *testing.T) { + var err error + // pub0 := &prv0.PublicKey + pub1 := &prv1.PublicKey + + // pub0s := crypto.FromECDSAPub(pub0) + pub1s := crypto.FromECDSAPub(pub1) + + // simulate handshake by feeding output to input + // initiator sends handshake 'auth' + auth, initNonce, randomPrivKey, err := authMsg(prv0, pub1s, sessionToken) + if err != nil { + t.Errorf("%v", err) + } + // t.Logf("-> %v", hexkey(auth)) + + // receiver reads auth and responds with response + response, remoteRecNonce, remoteInitNonce, _, remoteRandomPrivKey, remoteInitRandomPubKey, err := authResp(auth, sessionToken, prv1) + if err != nil { + t.Errorf("%v", err) + } + // t.Logf("<- %v\n", hexkey(response)) + + // initiator reads receiver's response and the key exchange completes + recNonce, remoteRandomPubKey, _, err := completeHandshake(response, prv0) + if err != nil { + t.Errorf("completeHandshake error: %v", err) + } + + // now both parties should have the same session parameters + initSessionToken, err := newSession(initNonce, recNonce, randomPrivKey, remoteRandomPubKey) + if err != nil { + t.Errorf("newSession error: %v", err) + } + + recSessionToken, err := newSession(remoteInitNonce, remoteRecNonce, remoteRandomPrivKey, remoteInitRandomPubKey) + if err != nil { + t.Errorf("newSession error: %v", err) + } + + // fmt.Printf("\nauth (%v) %x\n\nresp (%v) %x\n\n", len(auth), auth, len(response), response) + + // fmt.Printf("\nauth %x\ninitNonce %x\nresponse%x\nremoteRecNonce %x\nremoteInitNonce %x\nremoteRandomPubKey %x\nrecNonce %x\nremoteInitRandomPubKey %x\ninitSessionToken %x\n\n", auth, initNonce, response, remoteRecNonce, remoteInitNonce, remoteRandomPubKey, recNonce, remoteInitRandomPubKey, initSessionToken) + + if !bytes.Equal(initNonce, remoteInitNonce) { + t.Errorf("nonces do not match") + } + if !bytes.Equal(recNonce, remoteRecNonce) { + t.Errorf("receiver nonces do not match") + } + if !bytes.Equal(initSessionToken, recSessionToken) { + t.Errorf("session tokens do not match") + } +} + +func TestEncHandshake(t *testing.T) { + defer testlog(t).detach() + + prv0, _ := crypto.GenerateKey() + prv1, _ := crypto.GenerateKey() + pub0s, _ := exportPublicKey(&prv0.PublicKey) + pub1s, _ := exportPublicKey(&prv1.PublicKey) + rw0, rw1 := net.Pipe() + tokens := make(chan []byte) + + go func() { + token, err := outboundEncHandshake(rw0, prv0, pub1s, nil) + if err != nil { + t.Errorf("outbound side error: %v", err) + } + tokens <- token + }() + go func() { + token, remotePubkey, err := inboundEncHandshake(rw1, prv1, nil) + if err != nil { + t.Errorf("inbound side error: %v", err) + } + if !bytes.Equal(remotePubkey, pub0s) { + t.Errorf("inbound side returned wrong remote pubkey\n got: %x\n want: %x", remotePubkey, pub0s) + } + tokens <- token + }() + + t1, t2 := <-tokens, <-tokens + if !bytes.Equal(t1, t2) { + t.Error("session token mismatch") + } +} + +func TestSetupConn(t *testing.T) { + prv0, _ := crypto.GenerateKey() + prv1, _ := crypto.GenerateKey() + node0 := &discover.Node{ + ID: discover.PubkeyID(&prv0.PublicKey), + IP: net.IP{1, 2, 3, 4}, + TCPPort: 33, + } + node1 := &discover.Node{ + ID: discover.PubkeyID(&prv1.PublicKey), + IP: net.IP{5, 6, 7, 8}, + TCPPort: 44, + } + hs0 := &protoHandshake{ + Version: baseProtocolVersion, + ID: node0.ID, + Caps: []Cap{{"a", 0}, {"b", 2}}, + } + hs1 := &protoHandshake{ + Version: baseProtocolVersion, + ID: node1.ID, + Caps: []Cap{{"c", 1}, {"d", 3}}, + } + fd0, fd1 := net.Pipe() + + done := make(chan struct{}) + go func() { + defer close(done) + conn0, err := setupConn(fd0, prv0, hs0, node1) + if err != nil { + t.Errorf("outbound side error: %v", err) + return + } + if conn0.ID != node1.ID { + t.Errorf("outbound conn id mismatch: got %v, want %v", conn0.ID, node1.ID) + } + if !reflect.DeepEqual(conn0.Caps, hs1.Caps) { + t.Errorf("outbound caps mismatch: got %v, want %v", conn0.Caps, hs1.Caps) + } + }() + + conn1, err := setupConn(fd1, prv1, hs1, nil) + if err != nil { + t.Fatalf("inbound side error: %v", err) + } + if conn1.ID != node0.ID { + t.Errorf("inbound conn id mismatch: got %v, want %v", conn1.ID, node0.ID) + } + if !reflect.DeepEqual(conn1.Caps, hs0.Caps) { + t.Errorf("inbound caps mismatch: got %v, want %v", conn1.Caps, hs0.Caps) + } + + <-done +} diff --git a/p2p/message.go b/p2p/message.go index 07916f7b3..7adad4b09 100644 --- a/p2p/message.go +++ b/p2p/message.go @@ -197,7 +197,7 @@ func (rw *frameRW) ReadMsg() (msg Msg, err error) { return msg, err } if !bytes.HasPrefix(start, magicToken) { - return msg, fmt.Errorf("bad magic token %x", start[:4], magicToken) + return msg, fmt.Errorf("bad magic token %x", start[:4]) } size := binary.BigEndian.Uint32(start[4:]) diff --git a/p2p/peer.go b/p2p/peer.go index fd5bec7d5..b9bf0fd73 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -33,37 +33,14 @@ const ( peersMsg = 0x05 ) -// handshake is the RLP structure of the protocol handshake. -type handshake struct { - Version uint64 - Name string - Caps []Cap - ListenPort uint64 - NodeID discover.NodeID -} - // Peer represents a connected remote node. type Peer struct { // Peers have all the log methods. // Use them to display messages related to the peer. *logger.Logger - infoMu sync.Mutex - name string - caps []Cap - - ourID, remoteID *discover.NodeID - ourName string - - rw *frameRW - - // These fields maintain the running protocols. - protocols []Protocol - runlock sync.RWMutex // protects running - running map[string]*proto - - // disables protocol handshake, for testing - noHandshake bool + rw *conn + running map[string]*protoRW protoWG sync.WaitGroup protoErr chan error @@ -73,36 +50,27 @@ type Peer struct { // NewPeer returns a peer for testing purposes. func NewPeer(id discover.NodeID, name string, caps []Cap) *Peer { - conn, _ := net.Pipe() - peer := newPeer(conn, nil, "", nil, &id) - peer.setHandshakeInfo(name, caps) + pipe, _ := net.Pipe() + conn := newConn(pipe, &protoHandshake{ID: id, Name: name, Caps: caps}) + peer := newPeer(conn, nil) close(peer.closed) // ensures Disconnect doesn't block return peer } // ID returns the node's public key. func (p *Peer) ID() discover.NodeID { - return *p.remoteID + return p.rw.ID } // Name returns the node name that the remote node advertised. func (p *Peer) Name() string { - // this needs a lock because the information is part of the - // protocol handshake. - p.infoMu.Lock() - name := p.name - p.infoMu.Unlock() - return name + return p.rw.Name } // Caps returns the capabilities (supported subprotocols) of the remote peer. func (p *Peer) Caps() []Cap { - // this needs a lock because the information is part of the - // protocol handshake. - p.infoMu.Lock() - caps := p.caps - p.infoMu.Unlock() - return caps + // TODO: maybe return copy + return p.rw.Caps } // RemoteAddr returns the remote address of the network connection. @@ -126,30 +94,20 @@ func (p *Peer) Disconnect(reason DiscReason) { // String implements fmt.Stringer. func (p *Peer) String() string { - return fmt.Sprintf("Peer %.8x %v", p.remoteID[:], p.RemoteAddr()) + return fmt.Sprintf("Peer %.8x %v", p.rw.ID[:], p.RemoteAddr()) } -func newPeer(conn net.Conn, protocols []Protocol, ourName string, ourID, remoteID *discover.NodeID) *Peer { - logtag := fmt.Sprintf("Peer %.8x %v", remoteID[:], conn.RemoteAddr()) - return &Peer{ - Logger: logger.NewLogger(logtag), - rw: newFrameRW(conn, msgWriteTimeout), - ourID: ourID, - ourName: ourName, - remoteID: remoteID, - protocols: protocols, - running: make(map[string]*proto), - disc: make(chan DiscReason), - protoErr: make(chan error), - closed: make(chan struct{}), +func newPeer(conn *conn, protocols []Protocol) *Peer { + logtag := fmt.Sprintf("Peer %.8x %v", conn.ID[:], conn.RemoteAddr()) + p := &Peer{ + Logger: logger.NewLogger(logtag), + rw: conn, + running: matchProtocols(protocols, conn.Caps, conn), + disc: make(chan DiscReason), + protoErr: make(chan error), + closed: make(chan struct{}), } -} - -func (p *Peer) setHandshakeInfo(name string, caps []Cap) { - p.infoMu.Lock() - p.name = name - p.caps = caps - p.infoMu.Unlock() + return p } func (p *Peer) run() DiscReason { @@ -157,16 +115,9 @@ func (p *Peer) run() DiscReason { defer p.closeProtocols() defer close(p.closed) + p.startProtocols() go func() { readErr <- p.readLoop() }() - if !p.noHandshake { - if err := writeProtocolHandshake(p.rw, p.ourName, *p.ourID, p.protocols); err != nil { - p.DebugDetailf("Protocol handshake error: %v\n", err) - p.rw.Close() - return DiscProtocolError - } - } - // Wait for an error or disconnect. var reason DiscReason select { @@ -206,11 +157,6 @@ func (p *Peer) politeDisconnect(reason DiscReason) { } func (p *Peer) readLoop() error { - if !p.noHandshake { - if err := readProtocolHandshake(p, p.rw); err != nil { - return err - } - } for { msg, err := p.rw.ReadMsg() if err != nil { @@ -249,105 +195,51 @@ func (p *Peer) handle(msg Msg) error { return nil } -func readProtocolHandshake(p *Peer, rw MsgReadWriter) error { - // read and handle remote handshake - msg, err := rw.ReadMsg() - if err != nil { - return err - } - if msg.Code == discMsg { - // disconnect before protocol handshake is valid according to the - // spec and we send it ourself if Server.addPeer fails. - var reason DiscReason - rlp.Decode(msg.Payload, &reason) - return discRequestedError(reason) - } - if msg.Code != handshakeMsg { - return newPeerError(errProtocolBreach, "expected handshake, got %x", msg.Code) - } - if msg.Size > baseProtocolMaxMsgSize { - return newPeerError(errInvalidMsg, "message too big") - } - var hs handshake - if err := msg.Decode(&hs); err != nil { - return err - } - // validate handshake info - if hs.Version != baseProtocolVersion { - return newPeerError(errP2PVersionMismatch, "required version %d, received %d\n", - baseProtocolVersion, hs.Version) - } - if hs.NodeID == *p.remoteID { - return newPeerError(errPubkeyForbidden, "node ID mismatch") - } - // TODO: remove Caps with empty name - p.setHandshakeInfo(hs.Name, hs.Caps) - p.startSubprotocols(hs.Caps) - return nil -} - -func writeProtocolHandshake(w MsgWriter, name string, id discover.NodeID, ps []Protocol) error { - var caps []interface{} - for _, proto := range ps { - caps = append(caps, proto.cap()) - } - return EncodeMsg(w, handshakeMsg, baseProtocolVersion, name, caps, 0, id) -} - -// startProtocols starts matching named subprotocols. -func (p *Peer) startSubprotocols(caps []Cap) { +// matchProtocols creates structures for matching named subprotocols. +func matchProtocols(protocols []Protocol, caps []Cap, rw MsgReadWriter) map[string]*protoRW { sort.Sort(capsByName(caps)) - p.runlock.Lock() - defer p.runlock.Unlock() offset := baseProtocolLength + result := make(map[string]*protoRW) outer: for _, cap := range caps { - for _, proto := range p.protocols { - if proto.Name == cap.Name && - proto.Version == cap.Version && - p.running[cap.Name] == nil { - p.running[cap.Name] = p.startProto(offset, proto) + for _, proto := range protocols { + if proto.Name == cap.Name && proto.Version == cap.Version && result[cap.Name] == nil { + result[cap.Name] = &protoRW{Protocol: proto, offset: offset, in: make(chan Msg), w: rw} offset += proto.Length continue outer } } } + return result } -func (p *Peer) startProto(offset uint64, impl Protocol) *proto { - p.DebugDetailf("Starting protocol %s/%d\n", impl.Name, impl.Version) - rw := &proto{ - name: impl.Name, - in: make(chan Msg), - offset: offset, - maxcode: impl.Length, - w: p.rw, +func (p *Peer) startProtocols() { + for _, proto := range p.running { + proto := proto + p.DebugDetailf("Starting protocol %s/%d\n", proto.Name, proto.Version) + p.protoWG.Add(1) + go func() { + err := proto.Run(p, proto) + if err == nil { + p.DebugDetailf("Protocol %s/%d returned\n", proto.Name, proto.Version) + err = errors.New("protocol returned") + } else { + p.DebugDetailf("Protocol %s/%d error: %v\n", proto.Name, proto.Version, err) + } + select { + case p.protoErr <- err: + case <-p.closed: + } + p.protoWG.Done() + }() } - p.protoWG.Add(1) - go func() { - err := impl.Run(p, rw) - if err == nil { - p.DebugDetailf("Protocol %s/%d returned\n", impl.Name, impl.Version) - err = errors.New("protocol returned") - } else { - p.DebugDetailf("Protocol %s/%d error: %v\n", impl.Name, impl.Version, err) - } - select { - case p.protoErr <- err: - case <-p.closed: - } - p.protoWG.Done() - }() - return rw } // getProto finds the protocol responsible for handling // the given message code. -func (p *Peer) getProto(code uint64) (*proto, error) { - p.runlock.RLock() - defer p.runlock.RUnlock() +func (p *Peer) getProto(code uint64) (*protoRW, error) { for _, proto := range p.running { - if code >= proto.offset && code < proto.offset+proto.maxcode { + if code >= proto.offset && code < proto.offset+proto.Length { return proto, nil } } @@ -355,46 +247,43 @@ func (p *Peer) getProto(code uint64) (*proto, error) { } func (p *Peer) closeProtocols() { - p.runlock.RLock() for _, p := range p.running { close(p.in) } - p.runlock.RUnlock() p.protoWG.Wait() } // writeProtoMsg sends the given message on behalf of the given named protocol. // this exists because of Server.Broadcast. func (p *Peer) writeProtoMsg(protoName string, msg Msg) error { - p.runlock.RLock() proto, ok := p.running[protoName] - p.runlock.RUnlock() if !ok { return fmt.Errorf("protocol %s not handled by peer", protoName) } - if msg.Code >= proto.maxcode { + if msg.Code >= proto.Length { return newPeerError(errInvalidMsgCode, "code %x is out of range for protocol %q", msg.Code, protoName) } msg.Code += proto.offset return p.rw.WriteMsg(msg) } -type proto struct { - name string - in chan Msg - maxcode, offset uint64 - w MsgWriter +type protoRW struct { + Protocol + + in chan Msg + offset uint64 + w MsgWriter } -func (rw *proto) WriteMsg(msg Msg) error { - if msg.Code >= rw.maxcode { +func (rw *protoRW) WriteMsg(msg Msg) error { + if msg.Code >= rw.Length { return newPeerError(errInvalidMsgCode, "not handled") } msg.Code += rw.offset return rw.w.WriteMsg(msg) } -func (rw *proto) ReadMsg() (Msg, error) { +func (rw *protoRW) ReadMsg() (Msg, error) { msg, ok := <-rw.in if !ok { return msg, io.EOF diff --git a/p2p/peer_test.go b/p2p/peer_test.go index 68c9910a2..a1260adbd 100644 --- a/p2p/peer_test.go +++ b/p2p/peer_test.go @@ -6,11 +6,9 @@ import ( "io/ioutil" "net" "reflect" - "sort" "testing" "time" - "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/rlp" ) @@ -23,6 +21,7 @@ var discard = Protocol{ if err != nil { return err } + fmt.Printf("discarding %d\n", msg.Code) if err = msg.Discard(); err != nil { return err } @@ -30,13 +29,20 @@ var discard = Protocol{ }, } -func testPeer(noHandshake bool, protos []Protocol) (*frameRW, *Peer, <-chan DiscReason) { - conn1, conn2 := net.Pipe() - peer := newPeer(conn1, protos, "name", &discover.NodeID{}, &discover.NodeID{}) - peer.noHandshake = noHandshake +func testPeer(protos []Protocol) (*conn, *Peer, <-chan DiscReason) { + fd1, fd2 := net.Pipe() + hs1 := &protoHandshake{ID: randomID(), Version: baseProtocolVersion} + hs2 := &protoHandshake{ID: randomID(), Version: baseProtocolVersion} + for _, p := range protos { + hs1.Caps = append(hs1.Caps, p.cap()) + hs2.Caps = append(hs2.Caps, p.cap()) + } + + peer := newPeer(newConn(fd1, hs1), protos) errc := make(chan DiscReason, 1) go func() { errc <- peer.run() }() - return newFrameRW(conn2, msgWriteTimeout), peer, errc + + return newConn(fd2, hs2), peer, errc } func TestPeerProtoReadMsg(t *testing.T) { @@ -61,9 +67,8 @@ func TestPeerProtoReadMsg(t *testing.T) { }, } - rw, peer, errc := testPeer(true, []Protocol{proto}) + rw, _, errc := testPeer([]Protocol{proto}) defer rw.Close() - peer.startSubprotocols([]Cap{proto.cap()}) EncodeMsg(rw, baseProtocolLength+2, 1) EncodeMsg(rw, baseProtocolLength+3, 2) @@ -100,9 +105,8 @@ func TestPeerProtoReadLargeMsg(t *testing.T) { }, } - rw, peer, errc := testPeer(true, []Protocol{proto}) + rw, _, errc := testPeer([]Protocol{proto}) defer rw.Close() - peer.startSubprotocols([]Cap{proto.cap()}) EncodeMsg(rw, 18, make([]byte, msgsize)) select { @@ -130,9 +134,8 @@ func TestPeerProtoEncodeMsg(t *testing.T) { return nil }, } - rw, peer, _ := testPeer(true, []Protocol{proto}) + rw, _, _ := testPeer([]Protocol{proto}) defer rw.Close() - peer.startSubprotocols([]Cap{proto.cap()}) if err := expectMsg(rw, 17, []string{"foo", "bar"}); err != nil { t.Error(err) @@ -142,9 +145,8 @@ func TestPeerProtoEncodeMsg(t *testing.T) { func TestPeerWriteForBroadcast(t *testing.T) { defer testlog(t).detach() - rw, peer, peerErr := testPeer(true, []Protocol{discard}) + rw, peer, peerErr := testPeer([]Protocol{discard}) defer rw.Close() - peer.startSubprotocols([]Cap{discard.cap()}) // test write errors if err := peer.writeProtoMsg("b", NewMsg(3)); err == nil { @@ -160,7 +162,7 @@ func TestPeerWriteForBroadcast(t *testing.T) { read := make(chan struct{}) go func() { if err := expectMsg(rw, 16, nil); err != nil { - t.Error() + t.Error(err) } close(read) }() @@ -179,7 +181,7 @@ func TestPeerWriteForBroadcast(t *testing.T) { func TestPeerPing(t *testing.T) { defer testlog(t).detach() - rw, _, _ := testPeer(true, nil) + rw, _, _ := testPeer(nil) defer rw.Close() if err := EncodeMsg(rw, pingMsg); err != nil { t.Fatal(err) @@ -192,7 +194,7 @@ func TestPeerPing(t *testing.T) { func TestPeerDisconnect(t *testing.T) { defer testlog(t).detach() - rw, _, disc := testPeer(true, nil) + rw, _, disc := testPeer(nil) defer rw.Close() if err := EncodeMsg(rw, discMsg, DiscQuitting); err != nil { t.Fatal(err) @@ -206,73 +208,6 @@ func TestPeerDisconnect(t *testing.T) { } } -func TestPeerHandshake(t *testing.T) { - defer testlog(t).detach() - - // remote has two matching protocols: a and c - remote := NewPeer(randomID(), "", []Cap{{"a", 1}, {"b", 999}, {"c", 3}}) - remoteID := randomID() - remote.ourID = &remoteID - remote.ourName = "remote peer" - - start := make(chan string) - stop := make(chan struct{}) - run := func(p *Peer, rw MsgReadWriter) error { - name := rw.(*proto).name - if name != "a" && name != "c" { - t.Errorf("protocol %q should not be started", name) - } else { - start <- name - } - <-stop - return nil - } - protocols := []Protocol{ - {Name: "a", Version: 1, Length: 1, Run: run}, - {Name: "b", Version: 2, Length: 1, Run: run}, - {Name: "c", Version: 3, Length: 1, Run: run}, - {Name: "d", Version: 4, Length: 1, Run: run}, - } - rw, p, disc := testPeer(false, protocols) - p.remoteID = remote.ourID - defer rw.Close() - - // run the handshake - remoteProtocols := []Protocol{protocols[0], protocols[2]} - if err := writeProtocolHandshake(rw, "remote peer", remoteID, remoteProtocols); err != nil { - t.Fatalf("handshake write error: %v", err) - } - if err := readProtocolHandshake(remote, rw); err != nil { - t.Fatalf("handshake read error: %v", err) - } - - // check that all protocols have been started - var started []string - for i := 0; i < 2; i++ { - select { - case name := <-start: - started = append(started, name) - case <-time.After(100 * time.Millisecond): - } - } - sort.Strings(started) - if !reflect.DeepEqual(started, []string{"a", "c"}) { - t.Errorf("wrong protocols started: %v", started) - } - - // check that metadata has been set - if p.ID() != remoteID { - t.Errorf("peer has wrong node ID: got %v, want %v", p.ID(), remoteID) - } - if p.Name() != remote.ourName { - t.Errorf("peer has wrong node name: got %q, want %q", p.Name(), remote.ourName) - } - - close(stop) - expectMsg(rw, discMsg, nil) - t.Logf("disc reason: %v", <-disc) -} - func TestNewPeer(t *testing.T) { name := "nodename" caps := []Cap{{"foo", 2}, {"bar", 3}} diff --git a/p2p/server.go b/p2p/server.go index 35b584a27..194dc3f1c 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -5,7 +5,6 @@ import ( "crypto/ecdsa" "errors" "fmt" - "io" "net" "runtime" "sync" @@ -83,9 +82,11 @@ type Server struct { // Hooks for testing. These are useful because we can inhibit // the whole protocol stack. - handshakeFunc + setupFunc newPeerHook + ourHandshake *protoHandshake + lock sync.RWMutex running bool listener net.Listener @@ -99,7 +100,7 @@ type Server struct { peerConnect chan *discover.Node } -type handshakeFunc func(io.ReadWriter, *ecdsa.PrivateKey, *discover.Node) (discover.NodeID, []byte, error) +type setupFunc func(net.Conn, *ecdsa.PrivateKey, *protoHandshake, *discover.Node) (*conn, error) type newPeerHook func(*Peer) // Peers returns all connected peers. @@ -170,8 +171,8 @@ func (srv *Server) Start() (err error) { srv.peers = make(map[discover.NodeID]*Peer) srv.peerConnect = make(chan *discover.Node) - if srv.handshakeFunc == nil { - srv.handshakeFunc = encHandshake + if srv.setupFunc == nil { + srv.setupFunc = setupConn } if srv.Blacklist == nil { srv.Blacklist = NewBlacklist() @@ -183,11 +184,17 @@ func (srv *Server) Start() (err error) { } // dial stuff - dt, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT) + ntab, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT) if err != nil { return err } - srv.ntab = dt + srv.ntab = ntab + + srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: ntab.Self()} + for _, p := range srv.Protocols { + srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) + } + if srv.Dialer == nil { srv.Dialer = &net.Dialer{Timeout: defaultDialTimeout} } @@ -347,18 +354,17 @@ func (srv *Server) findPeers() { } } -func (srv *Server) startPeer(conn net.Conn, dest *discover.Node) { +func (srv *Server) startPeer(fd net.Conn, dest *discover.Node) { // TODO: handle/store session token - conn.SetDeadline(time.Now().Add(handshakeTimeout)) - remoteID, _, err := srv.handshakeFunc(conn, srv.PrivateKey, dest) + fd.SetDeadline(time.Now().Add(handshakeTimeout)) + conn, err := srv.setupFunc(fd, srv.PrivateKey, srv.ourHandshake, dest) if err != nil { - conn.Close() - srvlog.Debugf("Encryption Handshake with %v failed: %v", conn.RemoteAddr(), err) + fd.Close() + srvlog.Debugf("Handshake with %v failed: %v", fd.RemoteAddr(), err) return } - ourID := srv.ntab.Self() - p := newPeer(conn, srv.Protocols, srv.Name, &ourID, &remoteID) - if ok, reason := srv.addPeer(remoteID, p); !ok { + p := newPeer(conn, srv.Protocols) + if ok, reason := srv.addPeer(conn.ID, p); !ok { srvlog.DebugDetailf("Not adding %v (%v)\n", p, reason) p.politeDisconnect(reason) return @@ -394,7 +400,7 @@ func (srv *Server) addPeer(id discover.NodeID, p *Peer) (bool, DiscReason) { func (srv *Server) removePeer(p *Peer) { srv.lock.Lock() - delete(srv.peers, *p.remoteID) + delete(srv.peers, p.ID()) srv.lock.Unlock() srv.peerWG.Done() } diff --git a/p2p/server_test.go b/p2p/server_test.go index aa2b3d243..c109fffb9 100644 --- a/p2p/server_test.go +++ b/p2p/server_test.go @@ -21,8 +21,12 @@ func startTestServer(t *testing.T, pf newPeerHook) *Server { ListenAddr: "127.0.0.1:0", PrivateKey: newkey(), newPeerHook: pf, - handshakeFunc: func(io.ReadWriter, *ecdsa.PrivateKey, *discover.Node) (id discover.NodeID, st []byte, err error) { - return randomID(), nil, err + setupFunc: func(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake, dial *discover.Node) (*conn, error) { + id := randomID() + return &conn{ + frameRW: newFrameRW(fd, msgWriteTimeout), + protoHandshake: &protoHandshake{ID: id, Version: baseProtocolVersion}, + }, nil }, } if err := server.Start(); err != nil { @@ -116,9 +120,7 @@ func TestServerBroadcast(t *testing.T) { var connected sync.WaitGroup srv := startTestServer(t, func(p *Peer) { - p.protocols = []Protocol{discard} - p.startSubprotocols([]Cap{discard.cap()}) - p.noHandshake = true + p.running = matchProtocols([]Protocol{discard}, []Cap{discard.cap()}, p.rw) connected.Done() }) defer srv.Stop() -- cgit v1.2.3 From 1ec6190e866eeefd91ea82b31da9f94753685a4a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Feb 2015 16:39:20 +0100 Subject: cmd/mist: show peer names in peers window --- cmd/mist/assets/qml/main.qml | 3 ++- cmd/mist/gui.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index f9bfd9b8d..31d240b5f 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -927,7 +927,8 @@ ApplicationWindow { model: peerModel TableViewColumn{width: 180; role: "addr" ; title: "Remote Address" } TableViewColumn{width: 280; role: "nodeID" ; title: "Node ID" } - TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" } + TableViewColumn{width: 100; role: "name" ; title: "Name" } + TableViewColumn{width: 40; role: "caps" ; title: "Capabilities" } } } } diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index c9419473c..efab18064 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -466,7 +466,7 @@ NumGC: %d )) } -type qmlpeer struct{ Addr, NodeID, Caps string } +type qmlpeer struct{ Addr, NodeID, Name, Caps string } type peersByID []*qmlpeer @@ -481,6 +481,7 @@ func (gui *Gui) setPeerInfo() { qpeers[i] = &qmlpeer{ NodeID: p.ID().String(), Addr: p.RemoteAddr().String(), + Name: p.Name(), Caps: fmt.Sprint(p.Caps()), } } -- cgit v1.2.3 From 3dbd32093cd1060c339b3351fbb676b8c7cc31f0 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Feb 2015 16:53:52 +0100 Subject: p2p: enable devp2p ping This should prevent connection drops. --- p2p/peer.go | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/p2p/peer.go b/p2p/peer.go index b9bf0fd73..fb027c834 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -21,6 +21,7 @@ const ( baseProtocolMaxMsgSize = 10 * 1024 * 1024 disconnectGracePeriod = 2 * time.Second + pingInterval = 15 * time.Second ) const ( @@ -118,19 +119,33 @@ func (p *Peer) run() DiscReason { p.startProtocols() go func() { readErr <- p.readLoop() }() + ping := time.NewTicker(pingInterval) + defer ping.Stop() + // Wait for an error or disconnect. var reason DiscReason - select { - case err := <-readErr: - // We rely on protocols to abort if there is a write error. It - // might be more robust to handle them here as well. - p.DebugDetailf("Read error: %v\n", err) - p.rw.Close() - return DiscNetworkError - - case err := <-p.protoErr: - reason = discReasonForError(err) - case reason = <-p.disc: +loop: + for { + select { + case <-ping.C: + go func() { + if err := EncodeMsg(p.rw, pingMsg, nil); err != nil { + p.protoErr <- err + return + } + }() + case err := <-readErr: + // We rely on protocols to abort if there is a write error. It + // might be more robust to handle them here as well. + p.DebugDetailf("Read error: %v\n", err) + p.rw.Close() + return DiscNetworkError + case err := <-p.protoErr: + reason = discReasonForError(err) + break loop + case reason = <-p.disc: + break loop + } } p.politeDisconnect(reason) -- cgit v1.2.3 From dd871e791cdd2aefd001f6c3a11ac9378dde0bf5 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Feb 2015 17:08:18 +0100 Subject: p2p: initialize Server.ourHandshake before accepting connections --- p2p/server.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/p2p/server.go b/p2p/server.go index 194dc3f1c..923716011 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -160,7 +160,7 @@ func (srv *Server) Start() (err error) { } srvlog.Infoln("Starting Server") - // initialize all the fields + // static fields if srv.PrivateKey == nil { return fmt.Errorf("Server.PrivateKey must be set to a non-nil key") } @@ -170,31 +170,32 @@ func (srv *Server) Start() (err error) { srv.quit = make(chan struct{}) srv.peers = make(map[discover.NodeID]*Peer) srv.peerConnect = make(chan *discover.Node) - if srv.setupFunc == nil { srv.setupFunc = setupConn } if srv.Blacklist == nil { srv.Blacklist = NewBlacklist() } - if srv.ListenAddr != "" { - if err := srv.startListening(); err != nil { - return err - } - } - // dial stuff + // node table ntab, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT) if err != nil { return err } srv.ntab = ntab + // handshake srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: ntab.Self()} for _, p := range srv.Protocols { srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) } + // listen/dial + if srv.ListenAddr != "" { + if err := srv.startListening(); err != nil { + return err + } + } if srv.Dialer == nil { srv.Dialer = &net.Dialer{Timeout: defaultDialTimeout} } -- cgit v1.2.3 From fa15854a54d1d4505619aa3b3deabb50cd8ca881 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Feb 2015 17:09:13 +0100 Subject: logger: add P2P disconnected event --- logger/types.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/logger/types.go b/logger/types.go index d14a26643..7ab4a2b8c 100644 --- a/logger/types.go +++ b/logger/types.go @@ -42,6 +42,16 @@ func (l *P2PConnected) EventName() string { return "p2p.connected" } +type P2PDisconnected struct { + NumConnections int `json:"num_connections"` + RemoteId string `json:"remote_id"` + LogEvent +} + +func (l *P2PDisconnected) EventName() string { + return "p2p.disconnected" +} + type EthMinerNewBlock struct { BlockHash string `json:"block_hash"` BlockNumber int `json:"block_number"` @@ -117,16 +127,6 @@ func (l *EthTxReceived) EventName() string { // return "p2p.handshaked" // } -// type P2PDisconnected struct { -// NumConnections int `json:"num_connections"` -// RemoteId string `json:"remote_id"` -// LogEvent -// } - -// func (l *P2PDisconnected) EventName() string { -// return "p2p.disconnected" -// } - // type P2PDisconnecting struct { // Reason string `json:"reason"` // RemoteId string `json:"remote_id"` -- cgit v1.2.3 From 3719db352a3de1c7daece71895abdd871616a2aa Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 19 Feb 2015 17:09:33 +0100 Subject: p2p: emit JSON connect/disconnect events --- p2p/server.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/p2p/server.go b/p2p/server.go index 923716011..3ea2538d1 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -22,6 +22,7 @@ const ( ) var srvlog = logger.NewLogger("P2P Server") +var srvjslog = logger.NewJsonLogger() // MakeName creates a node name that follows the ethereum convention // for such names. It adds the operation system name and Go runtime version @@ -370,14 +371,26 @@ func (srv *Server) startPeer(fd net.Conn, dest *discover.Node) { p.politeDisconnect(reason) return } + srvlog.Debugf("Added %v\n", p) + srvjslog.LogJson(&logger.P2PConnected{ + RemoteId: fmt.Sprintf("%x", conn.ID[:]), + RemoteAddress: conn.RemoteAddr().String(), + RemoteVersionString: conn.Name, + NumConnections: srv.PeerCount(), + }) if srv.newPeerHook != nil { srv.newPeerHook(p) } discreason := p.run() srv.removePeer(p) + srvlog.Debugf("Removed %v (%v)\n", p, discreason) + srvjslog.LogJson(&logger.P2PDisconnected{ + RemoteId: fmt.Sprintf("%x", conn.ID[:]), + NumConnections: srv.PeerCount(), + }) } func (srv *Server) addPeer(id discover.NodeID, p *Peer) (bool, DiscReason) { -- cgit v1.2.3 From 605dd3a9820bb74be883afe3cb0e462aca40b32d Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Feb 2015 18:41:50 +0100 Subject: Add serpent compilation to RPC --- rpc/message.go | 15 +++++++++++++++ rpc/packages.go | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/rpc/message.go b/rpc/message.go index 524d7fc84..1935bf1e2 100644 --- a/rpc/message.go +++ b/rpc/message.go @@ -201,6 +201,21 @@ func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { return args, nil } +func (req *RpcRequest) ToCompileArgs() (string, error) { + if len(req.Params) < 1 { + return "", NewErrorResponse(ErrorArguments) + } + + var args string + err := json.Unmarshal(req.Params[0], &args) + if err != nil { + return "", NewErrorResponse(ErrorDecodeArgs) + } + + rpclogger.DebugDetailf("%T %v", args, args) + return args, nil +} + func (req *RpcRequest) ToFilterArgs() (*FilterOptions, error) { if len(req.Params) < 1 { return nil, NewErrorResponse(ErrorArguments) diff --git a/rpc/packages.go b/rpc/packages.go index 216321dba..c969f58cc 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -300,6 +300,21 @@ func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error { return nil } +func (p *EthereumApi) GetCompilers(reply *interface{}) error { + c := []string{"serpent"} + *reply = c + return nil +} + +func (p *EthereumApi) CompileSerpent(script string, reply *interface{}) error { + res, err := ethutil.Compile(script, false) + if err != nil { + return err + } + *reply = res + return nil +} + func (p *EthereumApi) Sha3(args *Sha3Args, reply *interface{}) error { *reply = toHex(crypto.Sha3(fromHex(args.Data))) return nil @@ -490,6 +505,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } return p.WatchTx(args, reply) + case "eth_compilers": + return p.GetCompilers(reply) + case "eth_serpent": + args, err := req.ToCompileArgs() + if err != nil { + return err + } + return p.CompileSerpent(args, reply) case "web3_sha3": args, err := req.ToSha3Args() if err != nil { -- cgit v1.2.3 From a59cd94625f589bb167be7a9c4588ff959dcfc00 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 19 Feb 2015 18:58:15 +0100 Subject: Add setMining RPC method --- rpc/message.go | 15 +++++++++++++++ rpc/packages.go | 11 +++++++++++ xeth/xeth.go | 11 +++++++++++ 3 files changed, 37 insertions(+) diff --git a/rpc/message.go b/rpc/message.go index 1935bf1e2..d02acef0e 100644 --- a/rpc/message.go +++ b/rpc/message.go @@ -201,6 +201,21 @@ func (req *RpcRequest) ToGetCodeAtArgs() (*GetCodeAtArgs, error) { return args, nil } +func (req *RpcRequest) ToBoolArgs() (bool, error) { + if len(req.Params) < 1 { + return false, NewErrorResponse(ErrorArguments) + } + + var args bool + err := json.Unmarshal(req.Params[0], &args) + if err != nil { + return false, NewErrorResponse(ErrorDecodeArgs) + } + + rpclogger.DebugDetailf("%T %v", args, args) + return args, nil +} + func (req *RpcRequest) ToCompileArgs() (string, error) { if len(req.Params) < 1 { return "", NewErrorResponse(ErrorArguments) diff --git a/rpc/packages.go b/rpc/packages.go index c969f58cc..d82538c92 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -267,6 +267,11 @@ func (p *EthereumApi) GetIsMining(reply *interface{}) error { return nil } +func (p *EthereumApi) SetMining(shouldmine bool, reply *interface{}) error { + *reply = p.xeth.SetMining(shouldmine) + return nil +} + func (p *EthereumApi) BlockNumber(reply *interface{}) error { *reply = p.xeth.Backend().ChainManager().CurrentBlock().Number() return nil @@ -400,6 +405,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return p.GetIsListening(reply) case "eth_mining": return p.GetIsMining(reply) + case "eth_setMining": + args, err := req.ToBoolArgs() + if err != nil { + return err + } + return p.SetMining(args, reply) case "eth_peerCount": return p.GetPeerCount(reply) case "eth_number": diff --git a/xeth/xeth.go b/xeth/xeth.go index f005105bb..06915c5e0 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -102,6 +102,17 @@ func (self *XEth) IsMining() bool { return self.miner.Mining() } +func (self *XEth) SetMining(shouldmine bool) bool { + ismining := self.miner.Mining() + if shouldmine && !ismining { + self.miner.Start() + } + if ismining && !shouldmine { + self.miner.Stop() + } + return self.miner.Mining() +} + func (self *XEth) IsListening() bool { return self.eth.IsListening() } -- cgit v1.2.3 From fa4cbad315609e41d88c59ecbce7c6c6169fc57a Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Feb 2015 22:33:22 +0100 Subject: Optimisations and fixed a couple of DDOS issues in the miner --- cmd/mist/assets/examples/bomb.html | 22 +++++++++++++++++++ cmd/mist/gui.go | 20 +++-------------- core/block_processor.go | 25 +++++++++++---------- core/chain_manager.go | 25 ++++++++++++++++----- core/error.go | 17 -------------- core/events.go | 3 +++ core/state_transition.go | 3 ++- core/transaction_pool.go | 33 ++++++++++++++++++++-------- ethutil/common.go | 7 ++++++ miner/worker.go | 22 +++++++++++-------- pow/ezp/pow.go | 2 +- rpc/packages.go | 1 + state/state_object.go | 4 ++++ state/statedb.go | 45 +++++++++++++++++++++----------------- xeth/xeth.go | 29 +++++++++++++----------- 15 files changed, 155 insertions(+), 103 deletions(-) create mode 100644 cmd/mist/assets/examples/bomb.html diff --git a/cmd/mist/assets/examples/bomb.html b/cmd/mist/assets/examples/bomb.html new file mode 100644 index 000000000..62540f9bb --- /dev/null +++ b/cmd/mist/assets/examples/bomb.html @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 1e3efd269..afddeb8f6 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -387,14 +387,11 @@ func (gui *Gui) update() { generalUpdateTicker := time.NewTicker(500 * time.Millisecond) statsUpdateTicker := time.NewTicker(5 * time.Second) - state := gui.eth.ChainManager().TransState() - - gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance()))) - lastBlockLabel := gui.getObjectByName("lastBlockLabel") miningLabel := gui.getObjectByName("miningLabel") events := gui.eth.EventMux().Subscribe( + core.ChainEvent{}, core.TxPreEvent{}, core.TxPostEvent{}, ) @@ -407,6 +404,8 @@ func (gui *Gui) update() { return } switch ev := ev.(type) { + case core.ChainEvent: + gui.processBlock(ev.Block, false) case core.TxPreEvent: gui.insertTransaction("pre", ev.Tx) @@ -422,19 +421,6 @@ func (gui *Gui) update() { lastBlockLabel.Set("text", statusText) miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.Miner().HashRate(), 10)+"/Khash") - /* - blockLength := gui.eth.BlockPool().BlocksProcessed - chainLength := gui.eth.BlockPool().ChainLength - - var ( - pct float64 = 1.0 / float64(chainLength) * float64(blockLength) - dlWidget = gui.win.Root().ObjectByName("downloadIndicator") - dlLabel = gui.win.Root().ObjectByName("downloadLabel") - ) - dlWidget.Set("value", pct) - dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength)) - */ - case <-statsUpdateTicker.C: gui.setStatsPane() } diff --git a/core/block_processor.go b/core/block_processor.go index b4449100f..a9795385f 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -73,24 +73,27 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block return receipts, nil } -func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, state *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) { +func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) { // If we are mining this block and validating we want to set the logs back to 0 - state.EmptyLogs() + statedb.EmptyLogs() txGas := new(big.Int).Set(tx.Gas()) - cb := state.GetStateObject(coinbase.Address()) - st := NewStateTransition(NewEnv(state, self.bc, tx, block), tx, cb) + cb := statedb.GetStateObject(coinbase.Address()) + st := NewStateTransition(NewEnv(statedb, self.bc, tx, block), tx, cb) _, err := st.TransitionState() + if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err)) { + return nil, nil, err + } txGas.Sub(txGas, st.gas) // Update the state with pending changes - state.Update(txGas) + statedb.Update(txGas) cumulative := new(big.Int).Set(usedGas.Add(usedGas, txGas)) - receipt := types.NewReceipt(state.Root(), cumulative) - receipt.SetLogs(state.Logs()) + receipt := types.NewReceipt(statedb.Root(), cumulative) + receipt.SetLogs(statedb.Logs()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) chainlogger.Debugln(receipt) @@ -99,12 +102,12 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, state go self.eventMux.Post(TxPostEvent{tx}) } - go self.eventMux.Post(state.Logs()) + go self.eventMux.Post(statedb.Logs()) return receipt, txGas, err } -func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) { +func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) { var ( receipts types.Receipts handled, unhandled types.Transactions @@ -115,12 +118,12 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state ) for _, tx := range txs { - receipt, txGas, err := self.ApplyTransaction(coinbase, state, block, tx, totalUsedGas, transientProcess) + receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, block, tx, totalUsedGas, transientProcess) if err != nil { switch { case IsNonceErr(err): return nil, nil, nil, nil, err - case IsGasLimitErr(err): + case state.IsGasLimitErr(err): return nil, nil, nil, nil, err default: statelogger.Infoln(err) diff --git a/core/chain_manager.go b/core/chain_manager.go index 286282064..003781791 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -134,14 +134,11 @@ func (self *ChainManager) State() *state.StateDB { func (self *ChainManager) TransState() *state.StateDB { self.tsmu.RLock() defer self.tsmu.RUnlock() - //tmp := self.transState return self.transState } func (self *ChainManager) setTransState(statedb *state.StateDB) { - self.tsmu.Lock() - defer self.tsmu.Unlock() self.transState = statedb } @@ -361,6 +358,9 @@ func (bc *ChainManager) Stop() { } func (self *ChainManager) InsertChain(chain types.Blocks) error { + self.tsmu.Lock() + defer self.tsmu.Unlock() + for _, block := range chain { td, err := self.processor.Process(block) if err != nil { @@ -376,6 +376,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } block.Td = td + var chain, split bool self.mu.Lock() { self.write(block) @@ -383,16 +384,26 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { if td.Cmp(self.td) > 0 { if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, ethutil.Big1)) < 0 { chainlogger.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, block.Hash()[:4], td, cblock.Header().Number, cblock.Hash()[:4], self.td) + split = true } self.setTotalDifficulty(td) self.insert(block) - self.setTransState(state.New(cblock.Root(), self.db)) - self.eventMux.Post(ChainEvent{block, td}) + chain = true } } self.mu.Unlock() + + if chain { + //self.setTransState(state.New(block.Root(), self.db)) + self.eventMux.Post(ChainEvent{block, td}) + } + + if split { + self.setTransState(state.New(block.Root(), self.db)) + self.eventMux.Post(ChainSplitEvent{block}) + } } return nil @@ -402,3 +413,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { func (self *ChainManager) GetAccount(addr []byte) *state.StateObject { return self.State().GetAccount(addr) } + +func (self *ChainManager) TransMut() *sync.RWMutex { + return &self.tsmu +} diff --git a/core/error.go b/core/error.go index 6af48ac2d..e86bacb2d 100644 --- a/core/error.go +++ b/core/error.go @@ -68,23 +68,6 @@ func IsValidationErr(err error) bool { return ok } -type GasLimitErr struct { - Message string - Is, Max *big.Int -} - -func IsGasLimitErr(err error) bool { - _, ok := err.(*GasLimitErr) - - return ok -} -func (err *GasLimitErr) Error() string { - return err.Message -} -func GasLimitError(is, max *big.Int) *GasLimitErr { - return &GasLimitErr{Message: fmt.Sprintf("GasLimit error. Max %s, transaction would take it to %s", max, is), Is: is, Max: max} -} - type NonceErr struct { Message string Is, Exp uint64 diff --git a/core/events.go b/core/events.go index fe106da49..4cbbc609c 100644 --- a/core/events.go +++ b/core/events.go @@ -13,3 +13,6 @@ type NewBlockEvent struct{ Block *types.Block } // NewMinedBlockEvent is posted when a block has been imported. type NewMinedBlockEvent struct{ Block *types.Block } + +// ChainSplit is posted when a new head is detected +type ChainSplitEvent struct{ Block *types.Block } diff --git a/core/state_transition.go b/core/state_transition.go index 33dd45f02..e82be647d 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -166,7 +166,8 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { defer self.RefundGas() // Increment the nonce for the next transaction - sender.Nonce += 1 + self.state.SetNonce(sender.Address(), sender.Nonce+1) + //sender.Nonce += 1 // Transaction gas if err = self.UseGas(vm.GasTx); err != nil { diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 7a901fcae..894b6c440 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -3,6 +3,7 @@ package core import ( "errors" "fmt" + "sync" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" @@ -35,6 +36,7 @@ type TxProcessor interface { // guarantee a non blocking pool we use a queue channel which can be // independently read without needing access to the actual pool. type TxPool struct { + mu sync.RWMutex // Queueing channel for reading and writing incoming // transactions to queueChan chan *types.Transaction @@ -97,7 +99,7 @@ func (self *TxPool) addTx(tx *types.Transaction) { self.txs[string(tx.Hash())] = tx } -func (self *TxPool) Add(tx *types.Transaction) error { +func (self *TxPool) add(tx *types.Transaction) error { if self.txs[string(tx.Hash())] != nil { return fmt.Errorf("Known transaction (%x)", tx.Hash()[0:4]) } @@ -128,17 +130,28 @@ func (self *TxPool) Size() int { return len(self.txs) } +func (self *TxPool) Add(tx *types.Transaction) error { + self.mu.Lock() + defer self.mu.Unlock() + return self.add(tx) +} func (self *TxPool) AddTransactions(txs []*types.Transaction) { + self.mu.Lock() + defer self.mu.Unlock() + for _, tx := range txs { - if err := self.Add(tx); err != nil { - txplogger.Infoln(err) + if err := self.add(tx); err != nil { + txplogger.Debugln(err) } else { - txplogger.Infof("tx %x\n", tx.Hash()[0:4]) + txplogger.Debugf("tx %x\n", tx.Hash()[0:4]) } } } func (self *TxPool) GetTransactions() (txs types.Transactions) { + self.mu.RLock() + defer self.mu.RUnlock() + txs = make(types.Transactions, self.Size()) i := 0 for _, tx := range self.txs { @@ -150,30 +163,32 @@ func (self *TxPool) GetTransactions() (txs types.Transactions) { } func (pool *TxPool) RemoveInvalid(query StateQuery) { + pool.mu.Lock() + var removedTxs types.Transactions for _, tx := range pool.txs { sender := query.GetAccount(tx.From()) err := pool.ValidateTransaction(tx) - fmt.Println(err, sender.Nonce, tx.Nonce()) if err != nil || sender.Nonce >= tx.Nonce() { removedTxs = append(removedTxs, tx) } } + pool.mu.Unlock() pool.RemoveSet(removedTxs) } func (self *TxPool) RemoveSet(txs types.Transactions) { + self.mu.Lock() + defer self.mu.Unlock() + for _, tx := range txs { delete(self.txs, string(tx.Hash())) } } -func (pool *TxPool) Flush() []*types.Transaction { - txList := pool.GetTransactions() +func (pool *TxPool) Flush() { pool.txs = make(map[string]*types.Transaction) - - return txList } func (pool *TxPool) Start() { diff --git a/ethutil/common.go b/ethutil/common.go index 271c56fd5..2ef2440c7 100644 --- a/ethutil/common.go +++ b/ethutil/common.go @@ -4,6 +4,7 @@ import ( "fmt" "math/big" "runtime" + "time" ) func IsWindows() bool { @@ -86,3 +87,9 @@ var ( Big256 = big.NewInt(0xff) Big257 = big.NewInt(257) ) + +func Bench(pre string, cb func()) { + start := time.Now() + cb() + fmt.Println(pre, ": took:", time.Since(start)) +} diff --git a/miner/worker.go b/miner/worker.go index 47b462e53..1f3a52ab5 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -109,14 +109,18 @@ func (self *worker) register(agent Agent) { } func (self *worker) update() { - events := self.mux.Subscribe(core.ChainEvent{}, core.TxPreEvent{}) + events := self.mux.Subscribe(core.ChainEvent{}, core.NewMinedBlockEvent{}) out: for { select { case event := <-events.Chan(): - switch event.(type) { - case core.ChainEvent, core.TxPreEvent: + switch ev := event.(type) { + case core.ChainEvent: + if self.current.block != ev.Block { + self.commitNewWork() + } + case core.NewMinedBlockEvent: self.commitNewWork() } case <-self.quit: @@ -172,17 +176,19 @@ func (self *worker) commitNewWork() { transactions := self.eth.TxPool().GetTransactions() sort.Sort(types.TxByNonce{transactions}) + minerlogger.Infof("committing new work with %d txs\n", len(transactions)) // Keep track of transactions which return errors so they can be removed var remove types.Transactions +gasLimit: for _, tx := range transactions { err := self.commitTransaction(tx) switch { case core.IsNonceErr(err): // Remove invalid transactions remove = append(remove, tx) - case core.IsGasLimitErr(err): + case state.IsGasLimitErr(err): // Break on gas limit - break + break gasLimit } if err != nil { @@ -227,11 +233,9 @@ func (self *worker) commitUncle(uncle *types.Header) error { } func (self *worker) commitTransaction(tx *types.Transaction) error { - snapshot := self.current.state.Copy() + //fmt.Printf("proc %x %v\n", tx.Hash()[:3], tx.Nonce()) receipt, _, err := self.proc.ApplyTransaction(self.current.coinbase, self.current.state, self.current.block, tx, self.current.totalUsedGas, true) - if err != nil && (core.IsNonceErr(err) || core.IsGasLimitErr(err)) { - self.current.state.Set(snapshot) - + if err != nil && (core.IsNonceErr(err) || state.IsGasLimitErr(err)) { return err } diff --git a/pow/ezp/pow.go b/pow/ezp/pow.go index 540381243..f4a8b80e5 100644 --- a/pow/ezp/pow.go +++ b/pow/ezp/pow.go @@ -21,7 +21,7 @@ type EasyPow struct { } func New() *EasyPow { - return &EasyPow{turbo: false} + return &EasyPow{turbo: true} } func (pow *EasyPow) GetHashrate() int64 { diff --git a/rpc/packages.go b/rpc/packages.go index 7044d9d12..63eea54d6 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -180,6 +180,7 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error { result, _ := p.xeth.Transact( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data) *reply = result } + return nil } diff --git a/state/state_object.go b/state/state_object.go index eaa91c713..d50c9fd7a 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -53,6 +53,7 @@ type StateObject struct { // When an object is marked for deletion it will be delete from the trie // during the "update" phase of the state transition remove bool + dirty bool } func (self *StateObject) Reset() { @@ -211,6 +212,8 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { return GasLimitError(self.gasPool, gas) } + self.gasPool.Sub(self.gasPool, gas) + rGas := new(big.Int).Set(gas) rGas.Mul(rGas, price) @@ -241,6 +244,7 @@ func (self *StateObject) Copy() *StateObject { stateObject.storage = self.storage.Copy() stateObject.gasPool.Set(self.gasPool) stateObject.remove = self.remove + stateObject.dirty = self.dirty return stateObject } diff --git a/state/statedb.go b/state/statedb.go index c83d59ed7..8c8a21db9 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -78,43 +78,45 @@ func (self *StateDB) GetNonce(addr []byte) uint64 { return 0 } -func (self *StateDB) SetNonce(addr []byte, nonce uint64) { +func (self *StateDB) GetCode(addr []byte) []byte { stateObject := self.GetStateObject(addr) if stateObject != nil { - stateObject.Nonce = nonce + return stateObject.Code } + + return nil } -func (self *StateDB) GetCode(addr []byte) []byte { - stateObject := self.GetStateObject(addr) +func (self *StateDB) GetState(a, b []byte) []byte { + stateObject := self.GetStateObject(a) if stateObject != nil { - return stateObject.Code + return stateObject.GetState(b).Bytes() } return nil } -func (self *StateDB) SetCode(addr, code []byte) { +func (self *StateDB) SetNonce(addr []byte, nonce uint64) { stateObject := self.GetStateObject(addr) if stateObject != nil { - stateObject.SetCode(code) + stateObject.Nonce = nonce + stateObject.dirty = true } } -// TODO vars -func (self *StateDB) GetState(a, b []byte) []byte { - stateObject := self.GetStateObject(a) +func (self *StateDB) SetCode(addr, code []byte) { + stateObject := self.GetStateObject(addr) if stateObject != nil { - return stateObject.GetState(b).Bytes() + stateObject.SetCode(code) + stateObject.dirty = true } - - return nil } func (self *StateDB) SetState(addr, key []byte, value interface{}) { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.SetState(key, ethutil.NewValue(value)) + stateObject.dirty = true } } @@ -122,6 +124,7 @@ func (self *StateDB) Delete(addr []byte) bool { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.MarkForDeletion() + stateObject.dirty = true return true } @@ -282,16 +285,18 @@ func (self *StateDB) Refunds() map[string]*big.Int { } func (self *StateDB) Update(gasUsed *big.Int) { - self.refund = make(map[string]*big.Int) for _, stateObject := range self.stateObjects { - if stateObject.remove { - self.DeleteStateObject(stateObject) - } else { - stateObject.Sync() - - self.UpdateStateObject(stateObject) + if stateObject.dirty { + if stateObject.remove { + self.DeleteStateObject(stateObject) + } else { + stateObject.Sync() + + self.UpdateStateObject(stateObject) + } + stateObject.dirty = false } } } diff --git a/xeth/xeth.go b/xeth/xeth.go index f005105bb..d578c03c9 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -7,6 +7,7 @@ package xeth import ( "bytes" "encoding/json" + "fmt" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -241,7 +242,6 @@ func (self *XEth) Call(toStr, valueStr, gasStr, gasPriceStr, dataStr string) (st } func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { - var ( to []byte value = ethutil.NewValue(valueStr) @@ -265,29 +265,32 @@ func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string) tx = types.NewTransactionMessage(to, value.BigInt(), gas.BigInt(), price.BigInt(), data) } - state := self.chainManager.TransState() + var err error + state := self.eth.ChainManager().TransState() + if balance := state.GetBalance(key.Address()); balance.Cmp(tx.Value()) < 0 { + return "", fmt.Errorf("insufficient balance. balance=%v tx=%v", balance, tx.Value()) + } nonce := state.GetNonce(key.Address()) tx.SetNonce(nonce) tx.Sign(key.PrivateKey) - // Do some pre processing for our "pre" events and hooks - block := self.chainManager.NewBlock(key.Address()) - coinbase := state.GetOrNewStateObject(key.Address()) - coinbase.SetGasPool(block.GasLimit()) - self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true) + //fmt.Printf("create tx: %x %v\n", tx.Hash()[:4], tx.Nonce()) - err := self.eth.TxPool().Add(tx) + /* + // Do some pre processing for our "pre" events and hooks + block := self.chainManager.NewBlock(key.Address()) + coinbase := state.GetOrNewStateObject(key.Address()) + coinbase.SetGasPool(block.GasLimit()) + self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true) + */ + + err = self.eth.TxPool().Add(tx) if err != nil { return "", err } state.SetNonce(key.Address(), nonce+1) - if contractCreation { - addr := core.AddressFromMessage(tx) - pipelogger.Infof("Contract addr %x\n", addr) - } - if types.IsContractAddr(to) { return toHex(core.AddressFromMessage(tx)), nil } -- cgit v1.2.3 From 81dea2d8e796b60ca9325bd2a3e502b71e25e6cc Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 11:35:40 +0100 Subject: update-license.go: add blank line after build tag This silences "go install ./...". For some reason it started complaining with go 1.4.2. --- update-license.go | 1 + 1 file changed, 1 insertion(+) diff --git a/update-license.go b/update-license.go index d5e21fdd3..832a94712 100644 --- a/update-license.go +++ b/update-license.go @@ -1,4 +1,5 @@ // +build none + /* This command generates GPL license headers on top of all source files. You can run it once per month, before cutting a release or just -- cgit v1.2.3 From 4ab7a290cdc6495a7ebcea9384cdc6622f2fd000 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 11:36:50 +0100 Subject: accounts: use crypto/randentropy in test --- accounts/accounts_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go index da9406ebe..30e8c6285 100644 --- a/accounts/accounts_test.go +++ b/accounts/accounts_test.go @@ -1,8 +1,10 @@ package accounts import ( - "github.com/ethereum/go-ethereum/crypto" "testing" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/randentropy" ) func TestAccountManager(t *testing.T) { @@ -10,7 +12,7 @@ func TestAccountManager(t *testing.T) { am := NewAccountManager(ks) pass := "" // not used but required by API a1, err := am.NewAccount(pass) - toSign := crypto.GetEntropyCSPRNG(32) + toSign := randentropy.GetEntropyCSPRNG(32) _, err = am.Sign(a1, pass, toSign) if err != nil { t.Fatal(err) -- cgit v1.2.3 From 01ce066d4307e6e8cab815eab9295a0b259130b9 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 11:37:33 +0100 Subject: state: improve TestDump --- state/state_test.go | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/state/state_test.go b/state/state_test.go index 7c54cedc0..ee1cf9286 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -1,6 +1,8 @@ package state import ( + "math/big" + checker "gopkg.in/check.v1" "github.com/ethereum/go-ethereum/ethdb" @@ -16,11 +18,42 @@ var _ = checker.Suite(&StateSuite{}) // var ZeroHash256 = make([]byte, 32) func (s *StateSuite) TestDump(c *checker.C) { - key := []byte{0x01} - value := []byte("foo") - s.state.trie.Update(key, value) - dump := s.state.Dump() - c.Assert(dump, checker.NotNil) + // generate a few entries + obj1 := s.state.GetOrNewStateObject([]byte{0x01}) + obj1.AddBalance(big.NewInt(22)) + obj2 := s.state.GetOrNewStateObject([]byte{0x01, 0x02}) + obj2.SetCode([]byte{3, 3, 3, 3, 3, 3, 3}) + obj3 := s.state.GetOrNewStateObject([]byte{0x02}) + obj3.SetBalance(big.NewInt(44)) + + // write some of them to the trie + s.state.UpdateStateObject(obj1) + s.state.UpdateStateObject(obj2) + + // check that dump contains the state objects that are in trie + got := string(s.state.Dump()) + want := `{ + "root": "4e3a59299745ba6752247c8b91d0f716dac9ec235861c91f5ac1894a361d87ba", + "accounts": { + "0000000000000000000000000000000000000001": { + "balance": "22", + "nonce": 0, + "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": {} + }, + "0000000000000000000000000000000000000102": { + "balance": "0", + "nonce": 0, + "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", + "storage": {} + } + } +}` + if got != want { + c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", got, want) + } } func (s *StateSuite) SetUpTest(c *checker.C) { -- cgit v1.2.3 From b3b6210886abd0962f97add91c081ac732639102 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 11:38:52 +0100 Subject: tests/vm: add non-test Go file This removes the annoying warning printed by "go install ./...". --- tests/vm/nowarn.go | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/vm/nowarn.go diff --git a/tests/vm/nowarn.go b/tests/vm/nowarn.go new file mode 100644 index 000000000..2a45a6cc6 --- /dev/null +++ b/tests/vm/nowarn.go @@ -0,0 +1,3 @@ +// This silences the warning given by 'go install ./...'. + +package vm -- cgit v1.2.3 From 66abe2e3d43c1004630c0c2f52a7f427bd51293b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 11:55:13 +0100 Subject: gocoverage.sh: skip . This is an attempt to get Travis working again. --- gocoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gocoverage.sh b/gocoverage.sh index 4245e3901..d353bd08a 100755 --- a/gocoverage.sh +++ b/gocoverage.sh @@ -13,7 +13,7 @@ for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d) do if ls $dir/*.go &> /dev/null; then # echo $dir - if [[ $dir != "./tests/vm" ]] + if [[ $dir != "./tests/vm" && $dir != "." ]] then go test -covermode=count -coverprofile=$dir/profile.tmp $dir fi -- cgit v1.2.3 From 654f7f707c9bd327fcbf0dcb89715a5930f915eb Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 12:15:08 +0100 Subject: .travis.yml: speed up tests on Travis This should decrease test runtime to about 30 seconds. --- .travis.yml | 3 --- gocoverage.sh | 11 ++++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2dfb7e283..cf8b02f5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,7 @@ install: # - go get golang.org/x/tools/cmd/vet - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi - go get github.com/mattn/goveralls - - go get gopkg.in/check.v1 - - go get github.com/tools/godep before_script: - - godep restore - gofmt -l -w . - goimports -l -w . - golint . diff --git a/gocoverage.sh b/gocoverage.sh index d353bd08a..e54a5cab0 100755 --- a/gocoverage.sh +++ b/gocoverage.sh @@ -1,11 +1,16 @@ #!/bin/bash -# The script does automatic checking on a Go package and its sub-packages, including: -# 6. test coverage (http://blog.golang.org/cover) set -e -# Run test coverage on each subdirectories and merge the coverage profile. +# Add godep workspace to GOPATH. We do it manually instead of using +# 'godep go test' or 'godep restore' so godep doesn't need to be installed. +GOPATH="$PWD/Godeps/_workspace:$GOPATH" + +# Install packages before testing. Not doing this would cause +# 'go test' to recompile all package dependencies before testing each package. +go install ./... +# Run test coverage on each subdirectories and merge the coverage profile. echo "mode: count" > profile.cov # Standard go tooling behavior is to ignore dirs with leading underscors -- cgit v1.2.3 From 3b12a9293c35fd336122d9387ab6bc9b67d2803a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 12:17:24 +0100 Subject: .travis.yml: don't run gofmt, goimports, golint This should yield another 30-second speed up. Nobody looks at the output of those anyway. We might want bring back gofmt later and actually fail the build if source is not formatted. --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index cf8b02f5c..1b3104826 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,15 +6,10 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -yqq libgmp3-dev libreadline6-dev qt54quickcontrols qt54webengine install: - - go get code.google.com/p/go.tools/cmd/goimports - - go get github.com/golang/lint/golint # - go get golang.org/x/tools/cmd/vet - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi - go get github.com/mattn/goveralls before_script: - - gofmt -l -w . - - goimports -l -w . - - golint . # - go vet ./... # - go test -race ./... script: -- cgit v1.2.3 From 982f73fa6d6f12874729faacd0db14fc78d518dd Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 12:59:54 +0100 Subject: Added timeout for filter & removed clipboard. Closes #350 --- rpc/packages.go | 72 +++++++++++++++++++++++++++++++++++-------- rpc/packages_test.go | 37 ++++++++++++++++++++++ rpc/util.go | 33 ++++++++++++++++++++ ui/qt/clipboard/capi.hpp | 11 ------- ui/qt/clipboard/clipboard.cpp | 20 ------------ ui/qt/clipboard/clipboard.go | 15 --------- ui/qt/clipboard/clipboard.hpp | 23 -------------- 7 files changed, 129 insertions(+), 82 deletions(-) create mode 100644 rpc/packages_test.go delete mode 100644 ui/qt/clipboard/capi.hpp delete mode 100644 ui/qt/clipboard/clipboard.cpp delete mode 100644 ui/qt/clipboard/clipboard.go delete mode 100644 ui/qt/clipboard/clipboard.hpp diff --git a/rpc/packages.go b/rpc/packages.go index 63eea54d6..7411392c2 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -13,6 +13,7 @@ import ( "math/big" "strings" "sync" + "time" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" @@ -31,13 +32,14 @@ const ( type EthereumApi struct { xeth *xeth.XEth + quit chan struct{} filterManager *filter.FilterManager logMut sync.RWMutex - logs map[int]state.Logs + logs map[int]*logFilter messagesMut sync.RWMutex - messages map[int][]xeth.WhisperMessage + messages map[int]*whisperFilter // Register keeps a list of accounts and transaction data regmut sync.Mutex register map[string][]*NewTxArgs @@ -49,12 +51,14 @@ func NewEthereumApi(eth *xeth.XEth) *EthereumApi { db, _ := ethdb.NewLDBDatabase("dapps") api := &EthereumApi{ xeth: eth, + quit: make(chan struct{}), filterManager: filter.NewFilterManager(eth.Backend().EventMux()), - logs: make(map[int]state.Logs), - messages: make(map[int][]xeth.WhisperMessage), + logs: make(map[int]*logFilter), + messages: make(map[int]*whisperFilter), db: db, } go api.filterManager.Start() + go api.start() return api } @@ -97,7 +101,11 @@ func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) erro self.logMut.Lock() defer self.logMut.Unlock() - self.logs[id] = append(self.logs[id], logs...) + if self.logs[id] == nil { + self.logs[id] = &logFilter{timeout: time.Now()} + } + + self.logs[id].add(logs...) } id = self.filterManager.InstallFilter(filter) *reply = id @@ -113,7 +121,11 @@ func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error self.logMut.Lock() defer self.logMut.Unlock() - self.logs[id] = append(self.logs[id], &state.StateLog{}) + if self.logs[id] == nil { + self.logs[id] = &logFilter{timeout: time.Now()} + } + + self.logs[id].add(&state.StateLog{}) } if args == "pending" { filter.PendingCallback = callback @@ -131,9 +143,9 @@ func (self *EthereumApi) FilterChanged(id int, reply *interface{}) error { self.logMut.Lock() defer self.logMut.Unlock() - *reply = toLogs(self.logs[id]) - - self.logs[id] = nil // empty the logs + if self.logs[id] != nil { + *reply = toLogs(self.logs[id].get()) + } return nil } @@ -331,7 +343,10 @@ func (p *EthereumApi) NewWhisperFilter(args *xeth.Options, reply *interface{}) e args.Fn = func(msg xeth.WhisperMessage) { p.messagesMut.Lock() defer p.messagesMut.Unlock() - p.messages[id] = append(p.messages[id], msg) + if p.messages[id] == nil { + p.messages[id] = &whisperFilter{timeout: time.Now()} + } + p.messages[id].add(msg) // = append(p.messages[id], msg) } id = p.xeth.Whisper().Watch(args) *reply = id @@ -342,9 +357,9 @@ func (self *EthereumApi) MessagesChanged(id int, reply *interface{}) error { self.messagesMut.Lock() defer self.messagesMut.Unlock() - *reply = self.messages[id] - - self.messages[id] = nil // empty the messages + if self.messages[id] != nil { + *reply = self.messages[id].get() + } return nil } @@ -535,3 +550,34 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error rpclogger.DebugDetailf("Reply: %T %s", reply, reply) return nil } + +var filterTickerTime = 15 * time.Second + +func (self *EthereumApi) start() { + timer := time.NewTicker(filterTickerTime) +done: + for { + select { + case <-timer.C: + self.logMut.Lock() + self.messagesMut.Lock() + for id, filter := range self.logs { + if time.Since(filter.timeout) > 20*time.Second { + delete(self.logs, id) + } + } + + for id, filter := range self.messages { + if time.Since(filter.timeout) > 20*time.Second { + delete(self.messages, id) + } + } + case <-self.quit: + break done + } + } +} + +func (self *EthereumApi) stop() { + close(self.quit) +} diff --git a/rpc/packages_test.go b/rpc/packages_test.go new file mode 100644 index 000000000..037fd78b3 --- /dev/null +++ b/rpc/packages_test.go @@ -0,0 +1,37 @@ +package rpc + +import ( + "sync" + "testing" + "time" +) + +func TestFilterClose(t *testing.T) { + api := &EthereumApi{ + logs: make(map[int]*logFilter), + messages: make(map[int]*whisperFilter), + quit: make(chan struct{}), + } + + filterTickerTime = 1 + api.logs[0] = &logFilter{} + api.messages[0] = &whisperFilter{} + var wg sync.WaitGroup + wg.Add(1) + go api.start() + go func() { + select { + case <-time.After(500 * time.Millisecond): + api.stop() + wg.Done() + } + }() + wg.Wait() + if len(api.logs) != 0 { + t.Error("expected logs to be empty") + } + + if len(api.messages) != 0 { + t.Error("expected messages to be empty") + } +} diff --git a/rpc/util.go b/rpc/util.go index 366e315ac..29824bcdb 100644 --- a/rpc/util.go +++ b/rpc/util.go @@ -20,10 +20,12 @@ import ( "encoding/json" "io" "net/http" + "time" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/state" + "github.com/ethereum/go-ethereum/xeth" ) var rpclogger = logger.NewLogger("RPC") @@ -100,3 +102,34 @@ func toLogs(logs state.Logs) (ls []Log) { return } + +type whisperFilter struct { + messages []xeth.WhisperMessage + timeout time.Time +} + +func (w *whisperFilter) add(msgs ...xeth.WhisperMessage) { + w.messages = append(w.messages, msgs...) +} +func (w *whisperFilter) get() []xeth.WhisperMessage { + w.timeout = time.Now() + tmp := w.messages + w.messages = nil + return tmp +} + +type logFilter struct { + logs state.Logs + timeout time.Time +} + +func (l *logFilter) add(logs ...state.Log) { + l.logs = append(l.logs, logs...) +} + +func (l *logFilter) get() state.Logs { + l.timeout = time.Now() + tmp := l.logs + l.logs = nil + return tmp +} diff --git a/ui/qt/clipboard/capi.hpp b/ui/qt/clipboard/capi.hpp deleted file mode 100644 index 202613469..000000000 --- a/ui/qt/clipboard/capi.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "clipboard.hpp" - -typedef void Clipboard_; - -Clipboard_ *initClipboard() -{ - Clipboard *clipboard = new(Clipboard); - return static_cast(clipboard); -} diff --git a/ui/qt/clipboard/clipboard.cpp b/ui/qt/clipboard/clipboard.cpp deleted file mode 100644 index 192aa7a2b..000000000 --- a/ui/qt/clipboard/clipboard.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "clipboard.h" - -#include - -Clipboard::Clipboard() -{ - connect(QApplication::clipboard(), &QClipboard::dataChanged, [this] { emit clipboardChanged();}); -} - -QString Clipboard::get() const -{ - QClipboard *clipboard = QApplication::clipboard(); - return clipboard->text(); -} - -void Clipboard::toClipboard(QString _text) -{ - QClipboard *clipboard = QApplicationion::clipboard(); - clipboard->setText(_text); -} diff --git a/ui/qt/clipboard/clipboard.go b/ui/qt/clipboard/clipboard.go deleted file mode 100644 index 064ee954d..000000000 --- a/ui/qt/clipboard/clipboard.go +++ /dev/null @@ -1,15 +0,0 @@ -package clipboard - -// #cgo CPPFLAGS: -I./ -// #cgo CXXFLAGS: -std=c++0x -pedantic-errors -Wall -fno-strict-aliasing -// #cgo LDFLAGS: -lstdc++ -// #cgo pkg-config: Qt5Quick -// -// #include "capi.hpp" -import "C" - -import "github.com/obscuren/qml" - -func SetQMLClipboard(context *qml.Context) { - context.SetVar("clipboard", (unsafe.Pointer)(C.initClipboard())) -} diff --git a/ui/qt/clipboard/clipboard.hpp b/ui/qt/clipboard/clipboard.hpp deleted file mode 100644 index 1aa213ceb..000000000 --- a/ui/qt/clipboard/clipboard.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -class Clipboard : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString get READ get WRITE toClipboard NOTIFY clipboardChanged) -public: - Clipboard(); - virtual ~Clipboard(){} - - Q_INVOKABLE void toClipboard(QString _text); - -signals: - void clipboardChanged(); -}; - -#ifdef __cplusplus -} // extern "C" -#endif -- cgit v1.2.3 From d8ac267f4128117c3fb9736a40f3dbc327582e32 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 14:01:30 +0100 Subject: dirty tracking for state objects fixed --- core/block_processor.go | 7 ++----- core/chain_manager.go | 2 +- eth/protocol.go | 2 +- state/state_object.go | 10 +++++++++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index a9795385f..bfd9d4560 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -296,16 +296,13 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren r := new(big.Int) r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16)) - uncleAccount := statedb.GetAccount(uncle.Coinbase) - uncleAccount.AddAmount(r) + statedb.AddBalance(uncle.Coinbase, r) reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) } // Get the account associated with the coinbase - account := statedb.GetAccount(block.Header().Coinbase) - // Reward amount of ether to the coinbase address - account.AddAmount(reward) + statedb.AddBalance(block.Header().Coinbase, reward) return nil } diff --git a/core/chain_manager.go b/core/chain_manager.go index 003781791..dd0dd3cbe 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -397,7 +397,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { if chain { //self.setTransState(state.New(block.Root(), self.db)) - self.eventMux.Post(ChainEvent{block, td}) + //self.eventMux.Post(ChainEvent{block, td}) } if split { diff --git a/eth/protocol.go b/eth/protocol.go index fb694c877..44a1184f2 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -13,7 +13,7 @@ import ( ) const ( - ProtocolVersion = 52 + ProtocolVersion = 53 NetworkId = 0 ProtocolLength = uint64(8) ProtocolMaxMsgSize = 10 * 1024 * 1024 diff --git a/state/state_object.go b/state/state_object.go index d50c9fd7a..226c25299 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -65,7 +65,7 @@ func NewStateObject(addr []byte, db ethutil.Database) *StateObject { // This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter. address := ethutil.Address(addr) - object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int)} + object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true} object.State = New(nil, db) //New(trie.New(ethutil.Config.Db, "")) object.storage = make(Storage) object.gasPool = new(big.Int) @@ -118,6 +118,7 @@ func (self *StateObject) GetStorage(key *big.Int) *ethutil.Value { } func (self *StateObject) SetStorage(key *big.Int, value *ethutil.Value) { self.SetState(key.Bytes(), value) + self.dirty = true } func (self *StateObject) Storage() map[string]*ethutil.Value { @@ -142,6 +143,7 @@ func (self *StateObject) GetState(k []byte) *ethutil.Value { func (self *StateObject) SetState(k []byte, value *ethutil.Value) { key := ethutil.LeftPadBytes(k, 32) self.storage[string(key)] = value.Copy() + self.dirty = true } func (self *StateObject) Sync() { @@ -166,6 +168,7 @@ func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value { func (c *StateObject) AddBalance(amount *big.Int) { c.SetBalance(new(big.Int).Add(c.balance, amount)) + c.dirty = true statelogger.Debugf("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.balance, amount) } @@ -180,6 +183,7 @@ func (c *StateObject) SubAmount(amount *big.Int) { c.SubBalance(amount) } func (c *StateObject) SetBalance(amount *big.Int) { c.balance = amount + c.dirty = true } func (self *StateObject) Balance() *big.Int { return self.balance } @@ -198,6 +202,8 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error { c.SubAmount(total) + c.dirty = true + return nil } @@ -219,6 +225,8 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error { self.AddAmount(rGas) + self.dirty = true + return nil } -- cgit v1.2.3 From ea9a549bbdc8377bca73f1417f2dc4a18396a382 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 14:19:34 +0100 Subject: Removed exported fields from state object and added proper set/getters --- cmd/ethtest/main.go | 4 +-- cmd/mist/ui_lib.go | 4 +-- core/state_transition.go | 8 +++--- core/transaction_pool.go | 2 +- state/dump.go | 4 +-- state/state_object.go | 67 +++++++++++++++++++++++++++++++----------------- state/statedb.go | 12 +++------ tests/vm/gh_test.go | 4 +-- xeth/xeth.go | 6 ++--- 9 files changed, 64 insertions(+), 47 deletions(-) diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index e1c4806ad..40874616c 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -51,8 +51,8 @@ func StateObjectFromAccount(db ethutil.Database, addr string, account Account) * if ethutil.IsHex(account.Code) { account.Code = account.Code[2:] } - obj.Code = ethutil.Hex2Bytes(account.Code) - obj.Nonce = ethutil.Big(account.Nonce).Uint64() + obj.SetCode(ethutil.Hex2Bytes(account.Code)) + obj.SetNonce(ethutil.Big(account.Nonce).Uint64()) return obj } diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index 1a4d21012..4fa6e8e55 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -146,8 +146,8 @@ func (ui *UiLib) AssetPath(p string) string { func (self *UiLib) StartDbWithContractAndData(contractHash, data string) { dbWindow := NewDebuggerWindow(self) object := self.eth.ChainManager().State().GetStateObject(ethutil.Hex2Bytes(contractHash)) - if len(object.Code) > 0 { - dbWindow.SetCode(ethutil.Bytes2Hex(object.Code)) + if len(object.Code()) > 0 { + dbWindow.SetCode(ethutil.Bytes2Hex(object.Code())) } dbWindow.SetData(data) diff --git a/core/state_transition.go b/core/state_transition.go index e82be647d..36ffa23d9 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -138,8 +138,8 @@ func (self *StateTransition) preCheck() (err error) { ) // Make sure this transaction's nonce is correct - if sender.Nonce != msg.Nonce() { - return NonceError(msg.Nonce(), sender.Nonce) + if sender.Nonce() != msg.Nonce() { + return NonceError(msg.Nonce(), sender.Nonce()) } // Pre-pay gas / Buy gas of the coinbase account @@ -166,7 +166,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { defer self.RefundGas() // Increment the nonce for the next transaction - self.state.SetNonce(sender.Address(), sender.Nonce+1) + self.state.SetNonce(sender.Address(), sender.Nonce()+1) //sender.Nonce += 1 // Transaction gas @@ -242,7 +242,7 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject { addr := AddressFromMessage(msg) contract := state.GetOrNewStateObject(addr) - contract.InitCode = msg.Data() + contract.SetInitCode(msg.Data()) return contract } diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 894b6c440..050cff3d8 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -169,7 +169,7 @@ func (pool *TxPool) RemoveInvalid(query StateQuery) { for _, tx := range pool.txs { sender := query.GetAccount(tx.From()) err := pool.ValidateTransaction(tx) - if err != nil || sender.Nonce >= tx.Nonce() { + if err != nil || sender.Nonce() >= tx.Nonce() { removedTxs = append(removedTxs, tx) } } diff --git a/state/dump.go b/state/dump.go index ac646480c..81895f1a3 100644 --- a/state/dump.go +++ b/state/dump.go @@ -30,7 +30,7 @@ func (self *StateDB) Dump() []byte { for it.Next() { stateObject := NewStateObjectFromBytes(it.Key, it.Value, self.db) - account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.Nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)} + account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)} account.Storage = make(map[string]string) storageIt := stateObject.State.trie.Iterator() @@ -50,7 +50,7 @@ func (self *StateDB) Dump() []byte { // Debug stuff func (self *StateObject) CreateOutputForDiff() { - fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce) + fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.nonce) it := self.State.trie.Iterator() for it.Next() { fmt.Printf("%x %x\n", it.Key, it.Value) diff --git a/state/state_object.go b/state/state_object.go index 226c25299..477b912a1 100644 --- a/state/state_object.go +++ b/state/state_object.go @@ -36,11 +36,11 @@ type StateObject struct { // Shared attributes balance *big.Int codeHash []byte - Nonce uint64 + nonce uint64 // Contract related attributes State *StateDB - Code Code - InitCode Code + code Code + initCode Code storage Storage @@ -89,20 +89,21 @@ func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateOb object := &StateObject{address: address, db: db} //object.RlpDecode(data) - object.Nonce = extobject.Nonce + object.nonce = extobject.Nonce object.balance = extobject.Balance object.codeHash = extobject.CodeHash object.State = New(extobject.Root, db) object.storage = make(map[string]*ethutil.Value) object.gasPool = new(big.Int) - object.Code, _ = db.Get(extobject.CodeHash) + object.code, _ = db.Get(extobject.CodeHash) return object } func (self *StateObject) MarkForDeletion() { self.remove = true - statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.Nonce, self.balance) + self.dirty = true + statelogger.DebugDetailf("%x: #%d %v (deletion)\n", self.Address(), self.nonce, self.balance) } func (c *StateObject) getAddr(addr []byte) *ethutil.Value { @@ -159,25 +160,24 @@ func (self *StateObject) Sync() { } func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value { - if int64(len(c.Code)-1) < pc.Int64() { + if int64(len(c.code)-1) < pc.Int64() { return ethutil.NewValue(0) } - return ethutil.NewValueFromBytes([]byte{c.Code[pc.Int64()]}) + return ethutil.NewValueFromBytes([]byte{c.code[pc.Int64()]}) } func (c *StateObject) AddBalance(amount *big.Int) { c.SetBalance(new(big.Int).Add(c.balance, amount)) - c.dirty = true - statelogger.Debugf("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.balance, amount) + statelogger.Debugf("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount) } func (c *StateObject) AddAmount(amount *big.Int) { c.AddBalance(amount) } func (c *StateObject) SubBalance(amount *big.Int) { c.SetBalance(new(big.Int).Sub(c.balance, amount)) - statelogger.Debugf("%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.balance, amount) + statelogger.Debugf("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount) } func (c *StateObject) SubAmount(amount *big.Int) { c.SubBalance(amount) } @@ -186,8 +186,6 @@ func (c *StateObject) SetBalance(amount *big.Int) { c.dirty = true } -func (self *StateObject) Balance() *big.Int { return self.balance } - // // Gas setters and getters // @@ -243,12 +241,12 @@ func (self *StateObject) Copy() *StateObject { stateObject := NewStateObject(self.Address(), self.db) stateObject.balance.Set(self.balance) stateObject.codeHash = ethutil.CopyBytes(self.codeHash) - stateObject.Nonce = self.Nonce + stateObject.nonce = self.nonce if self.State != nil { stateObject.State = self.State.Copy() } - stateObject.Code = ethutil.CopyBytes(self.Code) - stateObject.InitCode = ethutil.CopyBytes(self.InitCode) + stateObject.code = ethutil.CopyBytes(self.code) + stateObject.initCode = ethutil.CopyBytes(self.initCode) stateObject.storage = self.storage.Copy() stateObject.gasPool.Set(self.gasPool) stateObject.remove = self.remove @@ -265,8 +263,12 @@ func (self *StateObject) Set(stateObject *StateObject) { // Attribute accessors // +func (self *StateObject) Balance() *big.Int { + return self.balance +} + func (c *StateObject) N() *big.Int { - return big.NewInt(int64(c.Nonce)) + return big.NewInt(int64(c.nonce)) } // Returns the address of the contract/account @@ -276,7 +278,7 @@ func (c *StateObject) Address() []byte { // Returns the initialization Code func (c *StateObject) Init() Code { - return c.InitCode + return c.initCode } func (self *StateObject) Trie() *trie.Trie { @@ -287,8 +289,27 @@ func (self *StateObject) Root() []byte { return self.Trie().Root() } +func (self *StateObject) Code() []byte { + return self.code +} + func (self *StateObject) SetCode(code []byte) { - self.Code = code + self.code = code + self.dirty = true +} + +func (self *StateObject) SetInitCode(code []byte) { + self.initCode = code + self.dirty = true +} + +func (self *StateObject) SetNonce(nonce uint64) { + self.nonce = nonce + self.dirty = true +} + +func (self *StateObject) Nonce() uint64 { + return self.nonce } // @@ -297,16 +318,16 @@ func (self *StateObject) SetCode(code []byte) { // State object encoding methods func (c *StateObject) RlpEncode() []byte { - return ethutil.Encode([]interface{}{c.Nonce, c.balance, c.Root(), c.CodeHash()}) + return ethutil.Encode([]interface{}{c.nonce, c.balance, c.Root(), c.CodeHash()}) } func (c *StateObject) CodeHash() ethutil.Bytes { - return crypto.Sha3(c.Code) + return crypto.Sha3(c.code) } func (c *StateObject) RlpDecode(data []byte) { decoder := ethutil.NewValueFromBytes(data) - c.Nonce = decoder.Get(0).Uint() + c.nonce = decoder.Get(0).Uint() c.balance = decoder.Get(1).BigInt() c.State = New(decoder.Get(2).Bytes(), c.db) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) c.storage = make(map[string]*ethutil.Value) @@ -314,7 +335,7 @@ func (c *StateObject) RlpDecode(data []byte) { c.codeHash = decoder.Get(3).Bytes() - c.Code, _ = c.db.Get(c.codeHash) + c.code, _ = c.db.Get(c.codeHash) } // Storage change object. Used by the manifest for notifying changes to diff --git a/state/statedb.go b/state/statedb.go index 8c8a21db9..7e2b24b94 100644 --- a/state/statedb.go +++ b/state/statedb.go @@ -72,7 +72,7 @@ func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { func (self *StateDB) GetNonce(addr []byte) uint64 { stateObject := self.GetStateObject(addr) if stateObject != nil { - return stateObject.Nonce + return stateObject.nonce } return 0 @@ -81,7 +81,7 @@ func (self *StateDB) GetNonce(addr []byte) uint64 { func (self *StateDB) GetCode(addr []byte) []byte { stateObject := self.GetStateObject(addr) if stateObject != nil { - return stateObject.Code + return stateObject.code } return nil @@ -99,8 +99,7 @@ func (self *StateDB) GetState(a, b []byte) []byte { func (self *StateDB) SetNonce(addr []byte, nonce uint64) { stateObject := self.GetStateObject(addr) if stateObject != nil { - stateObject.Nonce = nonce - stateObject.dirty = true + stateObject.SetNonce(nonce) } } @@ -108,7 +107,6 @@ func (self *StateDB) SetCode(addr, code []byte) { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.SetCode(code) - stateObject.dirty = true } } @@ -116,7 +114,6 @@ func (self *StateDB) SetState(addr, key []byte, value interface{}) { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.SetState(key, ethutil.NewValue(value)) - stateObject.dirty = true } } @@ -124,7 +121,6 @@ func (self *StateDB) Delete(addr []byte) bool { stateObject := self.GetStateObject(addr) if stateObject != nil { stateObject.MarkForDeletion() - stateObject.dirty = true return true } @@ -141,7 +137,7 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) { addr := stateObject.Address() if len(stateObject.CodeHash()) > 0 { - self.db.Put(stateObject.CodeHash(), stateObject.Code) + self.db.Put(stateObject.CodeHash(), stateObject.code) } self.trie.Update(addr, stateObject.RlpEncode()) diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go index 17f945910..2151cf9a5 100644 --- a/tests/vm/gh_test.go +++ b/tests/vm/gh_test.go @@ -46,8 +46,8 @@ func StateObjectFromAccount(db ethutil.Database, addr string, account Account) * if ethutil.IsHex(account.Code) { account.Code = account.Code[2:] } - obj.Code = ethutil.Hex2Bytes(account.Code) - obj.Nonce = ethutil.Big(account.Nonce).Uint64() + obj.SetCode(ethutil.Hex2Bytes(account.Code)) + obj.SetNonce(ethutil.Big(account.Nonce).Uint64()) return obj } diff --git a/xeth/xeth.go b/xeth/xeth.go index d578c03c9..67dac948c 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -128,15 +128,15 @@ func (self *XEth) BalanceAt(addr string) string { } func (self *XEth) TxCountAt(address string) int { - return int(self.State().SafeGet(address).Nonce) + return int(self.State().SafeGet(address).Nonce()) } func (self *XEth) CodeAt(address string) string { - return toHex(self.State().SafeGet(address).Code) + return toHex(self.State().SafeGet(address).Code()) } func (self *XEth) IsContract(address string) bool { - return len(self.State().SafeGet(address).Code) > 0 + return len(self.State().SafeGet(address).Code()) > 0 } func (self *XEth) SecretToAddress(key string) string { -- cgit v1.2.3 From e282ad25a83e93f7a5ac085e3580ee9051daad10 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 15:24:19 +0100 Subject: eth: add poc-8.ethdev.com as second default bootstrap node --- eth/backend.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eth/backend.go b/eth/backend.go index b57e9fd69..f060ec3b6 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -25,7 +25,10 @@ var ( jsonlogger = ethlogger.NewJsonLogger() defaultBootNodes = []*discover.Node{ + // ETH/DEV cmd/bootnode discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"), + // ETH/DEV cpp-ethereum (poc-8.ethdev.com) + discover.MustParseNode("enode://4a44599974518ea5b0f14c31c4463692ac0329cb84851f3435e6d1b18ee4eae4aa495f846a0fa1219bd58035671881d44423876e57db2abd57254d0197da0ebe@5.1.83.226:30303"), } ) -- cgit v1.2.3 From e968928613a5d49ad67e921a52883268d4ad74d1 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Feb 2015 15:26:50 +0100 Subject: eth: persist node key between sessions (#304) --- eth/backend.go | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index f060ec3b6..0e5d24429 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -3,6 +3,8 @@ package eth import ( "crypto/ecdsa" "fmt" + "io/ioutil" + "path" "strings" "github.com/ethereum/go-ethereum/core" @@ -80,6 +82,27 @@ func (cfg *Config) parseBootNodes() []*discover.Node { return ns } +func (cfg *Config) nodeKey() (*ecdsa.PrivateKey, error) { + // use explicit key from command line args if set + if cfg.NodeKey != nil { + return cfg.NodeKey, nil + } + // use persistent key if present + keyfile := path.Join(cfg.DataDir, "nodekey") + key, err := crypto.LoadECDSA(keyfile) + if err == nil { + return key, nil + } + // no persistent key, generate and store a new one + if key, err = crypto.GenerateKey(); err != nil { + return nil, fmt.Errorf("could not generate server key: %v", err) + } + if err := ioutil.WriteFile(keyfile, crypto.FromECDSA(key), 0600); err != nil { + logger.Errorln("could not persist nodekey: ", err) + } + return key, nil +} + type Ethereum struct { // Channel for shutting down the ethereum shutdownChan chan bool @@ -164,18 +187,16 @@ func New(config *Config) (*Ethereum, error) { insertChain := eth.chainManager.InsertChain eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify) + netprv, err := config.nodeKey() + if err != nil { + return nil, err + } ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool) protocols := []p2p.Protocol{ethProto} if config.Shh { protocols = append(protocols, eth.whisper.Protocol()) } - netprv := config.NodeKey - if netprv == nil { - if netprv, err = crypto.GenerateKey(); err != nil { - return nil, fmt.Errorf("could not generate server key: %v", err) - } - } eth.net = &p2p.Server{ PrivateKey: netprv, Name: config.Name, -- cgit v1.2.3 From 66d5559866f37a79a7b5aeccd03dfe1b4401542b Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 16:59:08 +0100 Subject: Fixed chain event issue --- core/chain_manager.go | 4 +--- rpc/packages.go | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/core/chain_manager.go b/core/chain_manager.go index 47cad825d..600dc3db5 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -396,9 +396,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.mu.Unlock() if chain { - fmt.Println("POST START") - self.eventMux.Post(ChainEvent{block, td}) - fmt.Println("POST END") + go self.eventMux.Post(ChainEvent{block, td}) } if split { diff --git a/rpc/packages.go b/rpc/packages.go index 56c1751d7..72e090130 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -101,13 +101,11 @@ func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) erro self.logMut.Lock() defer self.logMut.Unlock() - if self.logs[id] == nil { - self.logs[id] = &logFilter{timeout: time.Now()} - } - self.logs[id].add(logs...) } id = self.filterManager.InstallFilter(filter) + self.logs[id] = &logFilter{timeout: time.Now()} + *reply = id return nil -- cgit v1.2.3 From cc43ab9a810125239636143a91609389b19b49c7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 18:05:46 +0100 Subject: Minor updates for release --- cmd/ethereum/main.go | 2 +- cmd/mist/assets/qml/main.qml | 2 +- cmd/mist/main.go | 2 +- core/chain_manager.go | 3 ++- core/genesis.go | 44 +++++++++++++++++++++++++++++++------------- eth/protocol.go | 2 +- ethutil/common_test.go | 2 +- miner/worker.go | 2 -- 8 files changed, 38 insertions(+), 21 deletions(-) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 1f1a0b761..fcf7f8ef0 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -37,7 +37,7 @@ import ( const ( ClientIdentifier = "Ethereum(G)" - Version = "0.8.3" + Version = "0.9.0" ) var clilogger = logger.NewLogger("CLI") diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 937670bd2..c421d696c 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -964,7 +964,7 @@ ApplicationWindow { anchors.top: parent.top anchors.topMargin: 30 font.pointSize: 12 - text: "

Mist (0.7.10)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy

UX

Alex van de Sande
" + text: "

Mist (0.9.0)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy
Gustav Simonsson

UX/UI

Alex van de Sande
Fabian Vogelsteller" } } diff --git a/cmd/mist/main.go b/cmd/mist/main.go index d41aa34bf..c7152347d 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -36,7 +36,7 @@ import ( const ( ClientIdentifier = "Mist" - Version = "0.8.3" + Version = "0.9.0" ) var ethereum *eth.Ethereum diff --git a/core/chain_manager.go b/core/chain_manager.go index 600dc3db5..9ef091c3c 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -268,6 +268,7 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain break } } + fmt.Printf("get hash %x (%d)\n", hash, len(chain)) return } @@ -396,7 +397,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.mu.Unlock() if chain { - go self.eventMux.Post(ChainEvent{block, td}) + self.eventMux.Post(ChainEvent{block, td}) } if split { diff --git a/core/genesis.go b/core/genesis.go index c870ce61e..75b4fc100 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -1,7 +1,10 @@ package core import ( + "encoding/json" + "fmt" "math/big" + "os" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -31,24 +34,39 @@ func GenesisBlock(db ethutil.Database) *types.Block { genesis.SetTransactions(types.Transactions{}) genesis.SetReceipts(types.Receipts{}) + var accounts map[string]struct{ Balance string } + err := json.Unmarshal(genesisData, &accounts) + if err != nil { + fmt.Println("enable to decode genesis json data:", err) + os.Exit(1) + } + statedb := state.New(genesis.Root(), db) - for _, addr := range []string{ - "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6", - "e4157b34ea9615cfbde6b4fda419828124b70c78", - "b9c015918bdaba24b4ff057a92a3873d6eb201be", - "6c386a4b26f73c802f34673f7248bb118f97424a", - "cd2a3d9f938e13cd947ec05abc7fe734df8dd826", - "2ef47100e0787b915105fd5e3f4ff6752079d5cb", - "e6716f9544a56c530d868e4bfbacb172315bdead", - "1a26338f0d905e295fccb71fa9ea849ffa12aaf4", - } { + for addr, account := range accounts { codedAddr := ethutil.Hex2Bytes(addr) - account := statedb.GetAccount(codedAddr) - account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200) - statedb.UpdateStateObject(account) + accountState := statedb.GetAccount(codedAddr) + accountState.SetBalance(ethutil.Big(account.Balance)) + statedb.UpdateStateObject(accountState) } statedb.Sync() genesis.Header().Root = statedb.Root() + fmt.Printf("+++ genesis +++\nRoot: %x\nHash: %x\n", genesis.Header().Root, genesis.Hash()) + return genesis } + +var genesisData = []byte(`{ + "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "e4157b34ea9615cfbde6b4fda419828124b70c78": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "b9c015918bdaba24b4ff057a92a3873d6eb201be": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "6c386a4b26f73c802f34673f7248bb118f97424a": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "cd2a3d9f938e13cd947ec05abc7fe734df8dd826": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "2ef47100e0787b915105fd5e3f4ff6752079d5cb": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "e6716f9544a56c530d868e4bfbacb172315bdead": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "1a26338f0d905e295fccb71fa9ea849ffa12aaf4": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "b0afc46d9ce366d06ab4952ca27db1d9557ae9fd": {"balance": "154162184000000000000000"}, + "f6b1e9dc460d4d62cc22ec5f987d726929c0f9f0": {"balance": "102774789000000000000000"}, + "cc45122d8b7fa0b1eaa6b29e0fb561422a9239d0": {"balance": "51387394000000000000000"}, + "b7576e9d314df41ec5506494293afb1bd5d3f65d": {"balance": "69423399000000000000000"} +}`) diff --git a/eth/protocol.go b/eth/protocol.go index 44a1184f2..8221c1b29 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -13,7 +13,7 @@ import ( ) const ( - ProtocolVersion = 53 + ProtocolVersion = 54 NetworkId = 0 ProtocolLength = uint64(8) ProtocolMaxMsgSize = 10 * 1024 * 1024 diff --git a/ethutil/common_test.go b/ethutil/common_test.go index c2b6077e9..aa30f311a 100644 --- a/ethutil/common_test.go +++ b/ethutil/common_test.go @@ -39,7 +39,7 @@ func (s *CommonSuite) TestCommon(c *checker.C) { douglas := CurrencyToString(BigPow(10, 43)) einstein := CurrencyToString(BigPow(10, 22)) ether := CurrencyToString(BigPow(10, 19)) - finney := CurrencyToString(BigPow(10, 16)) + finney := CurrencyToString(BigPow(10, 15)) szabo := CurrencyToString(BigPow(10, 13)) shannon := CurrencyToString(BigPow(10, 10)) babbage := CurrencyToString(BigPow(10, 7)) diff --git a/miner/worker.go b/miner/worker.go index aea5cc535..1f3a52ab5 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -117,11 +117,9 @@ out: case event := <-events.Chan(): switch ev := event.(type) { case core.ChainEvent: - println("miner start") if self.current.block != ev.Block { self.commitNewWork() } - println("miner end") case core.NewMinedBlockEvent: self.commitNewWork() } -- cgit v1.2.3 From 9feb657763b85cd5beece82efc9e6477235b7d67 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 18:06:45 +0100 Subject: Turbo off --- pow/ezp/pow.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pow/ezp/pow.go b/pow/ezp/pow.go index f4a8b80e5..540381243 100644 --- a/pow/ezp/pow.go +++ b/pow/ezp/pow.go @@ -21,7 +21,7 @@ type EasyPow struct { } func New() *EasyPow { - return &EasyPow{turbo: true} + return &EasyPow{turbo: false} } func (pow *EasyPow) GetHashrate() int64 { -- cgit v1.2.3 From d586a633ff005ac01c9f1eb33552d147cf6c883e Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 18:13:39 +0100 Subject: Updated readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6dd2182de..3f7329a47 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Ethereum Go Client © 2014 Jeffrey Wilcke. - | Linux | OSX | Windows -----------|---------|-----|-------- -develop | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A -master | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](http://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](http://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A + | Linux | OSX | Windows | Tests +----------|---------|-----|---------|------ +develop | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) +master | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](http://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](http://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) [![Bugs](https://badge.waffle.io/ethereum/go-ethereum.png?label=bug&title=Bugs)](https://waffle.io/ethereum/go-ethereum) [![Stories in Ready](https://badge.waffle.io/ethereum/go-ethereum.png?label=ready&title=Ready)](https://waffle.io/ethereum/go-ethereum) -- cgit v1.2.3 From 113cf4208b279eb3d7abd4daadb64da221a95554 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Feb 2015 20:52:03 +0100 Subject: Update build status links to https --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f7329a47..18392816a 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ Ethereum Go Client © 2014 Jeffrey Wilcke. | Linux | OSX | Windows | Tests ----------|---------|-----|---------|------ -develop | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](http://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) -master | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](http://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](http://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) +develop | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) +master | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) [![Bugs](https://badge.waffle.io/ethereum/go-ethereum.png?label=bug&title=Bugs)](https://waffle.io/ethereum/go-ethereum) [![Stories in Ready](https://badge.waffle.io/ethereum/go-ethereum.png?label=ready&title=Ready)](https://waffle.io/ethereum/go-ethereum) -- cgit v1.2.3 From f9663b8f4f0af5dd456c3dd9682d86912091204b Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 20 Feb 2015 20:57:45 +0100 Subject: Fix test for Finney --- ethutil/common_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethutil/common_test.go b/ethutil/common_test.go index aa30f311a..c2b6077e9 100644 --- a/ethutil/common_test.go +++ b/ethutil/common_test.go @@ -39,7 +39,7 @@ func (s *CommonSuite) TestCommon(c *checker.C) { douglas := CurrencyToString(BigPow(10, 43)) einstein := CurrencyToString(BigPow(10, 22)) ether := CurrencyToString(BigPow(10, 19)) - finney := CurrencyToString(BigPow(10, 15)) + finney := CurrencyToString(BigPow(10, 16)) szabo := CurrencyToString(BigPow(10, 13)) shannon := CurrencyToString(BigPow(10, 10)) babbage := CurrencyToString(BigPow(10, 7)) -- cgit v1.2.3 From 92337baa5a51f4d4ec39cb5004bdcc4b07d321e0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 21 Feb 2015 00:42:57 +0100 Subject: reverted back to proper version number --- cmd/ethereum/main.go | 2 +- cmd/mist/assets/qml/main.qml | 2 +- cmd/mist/main.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index fcf7f8ef0..53a558a99 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -37,7 +37,7 @@ import ( const ( ClientIdentifier = "Ethereum(G)" - Version = "0.9.0" + Version = "0.8.4" ) var clilogger = logger.NewLogger("CLI") diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index c421d696c..ca37dbf3c 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -964,7 +964,7 @@ ApplicationWindow { anchors.top: parent.top anchors.topMargin: 30 font.pointSize: 12 - text: "

Mist (0.9.0)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy
Gustav Simonsson

UX/UI

Alex van de Sande
Fabian Vogelsteller" + text: "

Mist (0.8.4)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy
Gustav Simonsson

UX/UI

Alex van de Sande
Fabian Vogelsteller" } } diff --git a/cmd/mist/main.go b/cmd/mist/main.go index c7152347d..45eddeb28 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -36,7 +36,7 @@ import ( const ( ClientIdentifier = "Mist" - Version = "0.9.0" + Version = "0.8.4" ) var ethereum *eth.Ethereum -- cgit v1.2.3 From cb7cd0391992e1800e25e1dc049c5d64a5432fe4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 21 Feb 2015 00:53:27 +0100 Subject: unlock mutex --- rpc/packages.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpc/packages.go b/rpc/packages.go index 72e090130..aed43cae2 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -617,6 +617,8 @@ done: delete(self.messages, id) } } + self.logMut.Unlock() + self.messagesMut.Unlock() case <-self.quit: break done } -- cgit v1.2.3 From fd3793b8cf04e2ca78b9c0a01844a09aa25b91e9 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Sat, 21 Feb 2015 05:33:51 +0100 Subject: Correct stack size validation for MUL, CALLDATACOPY, EXTCODESIZE, BLOCKHASH --- vm/vm.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/vm.go b/vm/vm.go index 5ec507ddc..bb293eb9b 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -779,9 +779,9 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo // Stack Check, memory resize & gas phase switch op { // Stack checks only - case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1 + case ISZERO, CALLDATALOAD, POP, JUMP, NOT, EXTCODESIZE, BLOCKHASH: // 1 stack.require(1) - case JUMPI, ADD, SUB, DIV, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2 + case JUMPI, ADD, SUB, DIV, MUL, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2 stack.require(2) case ADDMOD, MULMOD: // 3 stack.require(3) @@ -859,7 +859,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) additionalGas.Set(stack.data[stack.Len()-2]) case CALLDATACOPY: - stack.require(2) + stack.require(3) newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) additionalGas.Set(stack.data[stack.Len()-3]) -- cgit v1.2.3 From d8f7cb2f55e7e8cf1c831b65e8962bb0bdd2599e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 21 Feb 2015 13:48:09 +0100 Subject: Don't print per-function testing results --- .travis.yml | 5 +++++ gocoverage.sh | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b3104826..5499cf257 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,15 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -yqq libgmp3-dev libreadline6-dev qt54quickcontrols qt54webengine install: + # - go get code.google.com/p/go.tools/cmd/goimports + # - go get github.com/golang/lint/golint # - go get golang.org/x/tools/cmd/vet - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi - go get github.com/mattn/goveralls before_script: + # - gofmt -l -w . + # - goimports -l -w . + # - golint . # - go vet ./... # - go test -race ./... script: diff --git a/gocoverage.sh b/gocoverage.sh index e54a5cab0..5479d8d3b 100755 --- a/gocoverage.sh +++ b/gocoverage.sh @@ -29,6 +29,3 @@ if ls $dir/*.go &> /dev/null; then fi fi done - -go tool cover -func profile.cov - -- cgit v1.2.3 From 483d96a89d68023360d211ab329400f4b960fe48 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 22 Feb 2015 13:12:01 +0100 Subject: Added eth_logs & fixed issue with manual log filtering * Implemented `eth_logs` * Fixed issue with `filter.Find()` where logs were appended to an incorrect, non-returned slice resulting in no logs found --- cmd/mist/assets/examples/coin.html | 23 +++++++++++------------ cmd/utils/cmd.go | 2 +- core/block_processor.go | 16 ++++++---------- core/filter.go | 5 ++--- rpc/packages.go | 15 +++++++++++++++ xeth/xeth.go | 12 +++++------- 6 files changed, 40 insertions(+), 33 deletions(-) diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html index cb9d471de..18a6811d7 100644 --- a/cmd/mist/assets/examples/coin.html +++ b/cmd/mist/assets/examples/coin.html @@ -14,8 +14,9 @@
- Amount: + Address: + Amount:
@@ -58,7 +59,7 @@ }], "outputs": [] }, { - "name":"received", + "name":"Changed", "type":"event", "inputs": [ {"name":"from","type":"address","indexed":true}, @@ -69,18 +70,14 @@ var address = localStorage.getItem("address"); // deploy if not exist if (address == null) { - var code = "0x60056013565b61012b806100346000396000f35b6103e8600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a681461002b578063d0679d3414610039578063e3d670d71461004d57005b610033610126565b60006000f35b610047600435602435610062565b60006000f35b610058600435610104565b8060005260206000f35b80600033600160a060020a0316600052602052604060002054101561008657610100565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a0316600052602052604060002090815401908190555033600160a060020a0316600052806020527ff11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef60406000a15b5050565b6000600082600160a060020a03166000526020526040600020549050919050565b5b60008156"; + var code = "0x60056013565b61014f8061003a6000396000f35b620f42406000600033600160a060020a0316815260200190815260200160002081905550560060e060020a600035048063d0679d3414610020578063e3d670d71461003457005b61002e600435602435610049565b60006000f35b61003f600435610129565b8060005260206000f35b806000600033600160a060020a03168152602001908152602001600020541061007157610076565b610125565b806000600033600160a060020a03168152602001908152602001600020908154039081905550806000600084600160a060020a031681526020019081526020016000209081540190819055508033600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a38082600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a35b5050565b60006000600083600160a060020a0316815260200190815260200160002054905091905056"; address = web3.eth.transact({data: code}); localStorage.setItem("address", address); } - document.querySelector("#contract_addr").innerHTML = address.toUpperCase(); + document.querySelector("#contract_addr").innerHTML = address; var contract = web3.eth.contract(address, desc); - contract.received({from: eth.coinbase}).changed(function() { - refresh(); - }); - - eth.watch('chain').changed(function() { + contract.Changed({from: eth.coinbase}).changed(function() { refresh(); }); @@ -93,7 +90,7 @@ var storage = eth.storageAt(address); table.innerHTML = ""; for( var item in storage ) { - table.innerHTML += ""+item.toUpperCase()+""+web3.toDecimal(storage[item])+""; + table.innerHTML += ""+item+""+web3.toDecimal(storage[item])+""; } } @@ -106,6 +103,7 @@ } var value = parseInt( document.querySelector("#amount").value ); + console.log("transact: ", to, " => ", value) contract.send( to, value ); } @@ -121,7 +119,7 @@ contract JevCoin { balances[msg.sender] = 1000000; } - event changed(address indexed from, address indexed to); + event Changed(address indexed from, uint indexed amount); function send(address to, uint value) { if( balances[msg.sender] < value ) return; @@ -129,7 +127,8 @@ contract JevCoin { balances[msg.sender] -= value; balances[to] += value; - changed(msg.sender, to); + Changed(msg.sender, value); + Changed(to, value); } function balance(address who) constant returns(uint t) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index d252f3ab2..bc8fafafb 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -272,7 +272,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error { parent := ethereum.ChainManager().GetBlock(block.ParentHash()) statedb := state.New(parent.Root(), ethereum.Db()) - _, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block) + _, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block, true) if err != nil { return err } diff --git a/core/block_processor.go b/core/block_processor.go index bfd9d4560..fd591a29d 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -60,12 +60,12 @@ func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainM return sm } -func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) { +func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) { coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase) coinbase.SetGasPool(CalcGasLimit(parent, block)) // Process the transactions on to parent state - receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false) + receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) if err != nil { return nil, err } @@ -100,10 +100,9 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated // Notify all subscribers if !transientProcess { go self.eventMux.Post(TxPostEvent{tx}) + go self.eventMux.Post(statedb.Logs()) } - go self.eventMux.Post(statedb.Logs()) - return receipt, txGas, err } @@ -179,7 +178,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big return } - receipts, err := sm.TransitionState(state, parent, block) + receipts, err := sm.TransitionState(state, parent, block, false) if err != nil { return } @@ -316,13 +315,10 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro var ( parent = sm.bc.GetBlock(block.Header().ParentHash) - //state = state.New(parent.Trie().Copy()) - state = state.New(parent.Root(), sm.db) + state = state.New(parent.Root(), sm.db) ) - defer state.Reset() - - sm.TransitionState(state, parent, block) + sm.TransitionState(state, parent, block, true) sm.AccumulateRewards(state, block, parent) return state.Logs(), nil diff --git a/core/filter.go b/core/filter.go index 88f12a67c..cdf7b282d 100644 --- a/core/filter.go +++ b/core/filter.go @@ -111,14 +111,14 @@ func (self *Filter) Find() state.Logs { // current parameters if self.bloomFilter(block) { // Get the logs of the block - logs, err := self.eth.BlockProcessor().GetLogs(block) + unfiltered, err := self.eth.BlockProcessor().GetLogs(block) if err != nil { chainlogger.Warnln("err: filter get logs ", err) break } - logs = append(logs, self.FilterLogs(logs)...) + logs = append(logs, self.FilterLogs(unfiltered)...) } block = self.eth.ChainManager().GetBlock(block.ParentHash()) @@ -146,7 +146,6 @@ func (self *Filter) FilterLogs(logs state.Logs) state.Logs { Logs: for _, log := range logs { if !includes(self.address, log.Address()) { - //if !bytes.Equal(self.address, log.Address()) { continue } diff --git a/rpc/packages.go b/rpc/packages.go index aed43cae2..b51bde7ce 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -167,6 +167,15 @@ func (self *EthereumApi) Logs(id int, reply *interface{}) error { return nil } +func (self *EthereumApi) AllLogs(args *FilterOptions, reply *interface{}) error { + filter := core.NewFilter(self.xeth.Backend()) + filter.SetOptions(toFilterOptions(args)) + + *reply = toLogs(filter.Find()) + + return nil +} + func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error { err := args.requirements() if err != nil { @@ -509,6 +518,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return err } return p.Logs(args, reply) + case "eth_logs": + args, err := req.ToFilterArgs() + if err != nil { + return err + } + return p.AllLogs(args, reply) case "eth_gasPrice": *reply = defaultGasPrice return nil diff --git a/xeth/xeth.go b/xeth/xeth.go index f3569e454..5907a8329 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -288,13 +288,11 @@ func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string) //fmt.Printf("create tx: %x %v\n", tx.Hash()[:4], tx.Nonce()) - /* - // Do some pre processing for our "pre" events and hooks - block := self.chainManager.NewBlock(key.Address()) - coinbase := state.GetOrNewStateObject(key.Address()) - coinbase.SetGasPool(block.GasLimit()) - self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true) - */ + // Do some pre processing for our "pre" events and hooks + block := self.chainManager.NewBlock(key.Address()) + coinbase := state.GetOrNewStateObject(key.Address()) + coinbase.SetGasPool(block.GasLimit()) + self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true) err = self.eth.TxPool().Add(tx) if err != nil { -- cgit v1.2.3 From bba85a207488d27819dc6f6f5758b80947ea200b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 22 Feb 2015 13:24:26 +0100 Subject: Added Number to logs --- rpc/util.go | 2 ++ state/log.go | 11 +++++++++-- vm/environment.go | 5 +++++ vm/vm.go | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/rpc/util.go b/rpc/util.go index 29824bcdb..1939b3474 100644 --- a/rpc/util.go +++ b/rpc/util.go @@ -84,6 +84,7 @@ type Log struct { Address string `json:"address"` Topic []string `json:"topics"` Data string `json:"data"` + Number uint64 `json:"number"` } func toLogs(logs state.Logs) (ls []Log) { @@ -94,6 +95,7 @@ func toLogs(logs state.Logs) (ls []Log) { l.Topic = make([]string, len(log.Topics())) l.Address = toHex(log.Address()) l.Data = toHex(log.Data()) + l.Number = log.Number() for j, topic := range log.Topics() { l.Topic[j] = toHex(topic) } diff --git a/state/log.go b/state/log.go index 46360f4aa..d503bd1a0 100644 --- a/state/log.go +++ b/state/log.go @@ -12,16 +12,19 @@ type Log interface { Address() []byte Topics() [][]byte Data() []byte + + Number() uint64 } type StateLog struct { address []byte topics [][]byte data []byte + number uint64 } -func NewLog(address []byte, topics [][]byte, data []byte) *StateLog { - return &StateLog{address, topics, data} +func NewLog(address []byte, topics [][]byte, data []byte, number uint64) *StateLog { + return &StateLog{address, topics, data, number} } func (self *StateLog) Address() []byte { @@ -36,6 +39,10 @@ func (self *StateLog) Data() []byte { return self.data } +func (self *StateLog) Number() uint64 { + return self.number +} + func NewLogFromValue(decoder *ethutil.Value) *StateLog { log := &StateLog{ address: decoder.Get(0).Bytes(), diff --git a/vm/environment.go b/vm/environment.go index 8507e248f..5b4d6c8f0 100644 --- a/vm/environment.go +++ b/vm/environment.go @@ -54,6 +54,7 @@ type Log struct { address []byte topics [][]byte data []byte + log uint64 } func (self *Log) Address() []byte { @@ -68,6 +69,10 @@ func (self *Log) Data() []byte { return self.data } +func (self *Log) Number() uint64 { + return self.log +} + func (self *Log) RlpData() interface{} { return []interface{}{self.address, ethutil.ByteSliceToInterface(self.topics), self.data} } diff --git a/vm/vm.go b/vm/vm.go index 5ec507ddc..b20d7b603 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -578,7 +578,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I } data := mem.Get(mStart.Int64(), mSize.Int64()) - log := &Log{context.Address(), topics, data} + log := &Log{context.Address(), topics, data, self.env.BlockNumber().Uint64()} self.env.AddLog(log) self.Printf(" => %v", log) -- cgit v1.2.3 From 321dce1f47135f673730cb86fdf1faf03dc6cbd4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 22 Feb 2015 13:26:10 +0100 Subject: Bump --- cmd/ethereum/main.go | 2 +- cmd/mist/assets/qml/main.qml | 2 +- cmd/mist/main.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 53a558a99..9c840de58 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -37,7 +37,7 @@ import ( const ( ClientIdentifier = "Ethereum(G)" - Version = "0.8.4" + Version = "0.8.5" ) var clilogger = logger.NewLogger("CLI") diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index ca37dbf3c..e80bd87e0 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -964,7 +964,7 @@ ApplicationWindow { anchors.top: parent.top anchors.topMargin: 30 font.pointSize: 12 - text: "

Mist (0.8.4)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy
Gustav Simonsson

UX/UI

Alex van de Sande
Fabian Vogelsteller" + text: "

Mist (0.8.5)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy
Gustav Simonsson

UX/UI

Alex van de Sande
Fabian Vogelsteller" } } diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 45eddeb28..ad6eb5bec 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -36,7 +36,7 @@ import ( const ( ClientIdentifier = "Mist" - Version = "0.8.4" + Version = "0.8.5" ) var ethereum *eth.Ethereum -- cgit v1.2.3