mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-11-14 03:50:26 +00:00
Use upstream whatsapp again (#809)
This commit is contained in:
parent
9619dff334
commit
3418e8c9af
@ -6,9 +6,9 @@ import (
|
|||||||
|
|
||||||
"github.com/42wim/matterbridge/bridge/config"
|
"github.com/42wim/matterbridge/bridge/config"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
|
|
||||||
whatsappExt "github.com/matterbridge/mautrix-whatsapp/whatsapp-ext"
|
whatsappExt "maunium.net/go/mautrix-whatsapp/whatsapp-ext"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
|
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func qrFromTerminal(invert bool) chan string {
|
func qrFromTerminal(invert bool) chan string {
|
||||||
|
@ -11,10 +11,9 @@ import (
|
|||||||
|
|
||||||
"github.com/42wim/matterbridge/bridge"
|
"github.com/42wim/matterbridge/bridge"
|
||||||
"github.com/42wim/matterbridge/bridge/config"
|
"github.com/42wim/matterbridge/bridge/config"
|
||||||
|
"github.com/Rhymen/go-whatsapp"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
whatsappExt "maunium.net/go/mautrix-whatsapp/whatsapp-ext"
|
||||||
|
|
||||||
whatsappExt "github.com/matterbridge/mautrix-whatsapp/whatsapp-ext"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -89,7 +88,7 @@ func (b *Bwhatsapp) Connect() error {
|
|||||||
b.Log.Debugln("Restoring WhatsApp session..")
|
b.Log.Debugln("Restoring WhatsApp session..")
|
||||||
|
|
||||||
// https://github.com/Rhymen/go-whatsapp#restore
|
// https://github.com/Rhymen/go-whatsapp#restore
|
||||||
session, err = b.conn.RestoreSession(session)
|
session, err = b.conn.RestoreWithSession(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO return or continue to normal login?
|
// TODO return or continue to normal login?
|
||||||
// restore session connection timed out (I couldn't get over it without logging in again)
|
// restore session connection timed out (I couldn't get over it without logging in again)
|
||||||
|
6
go.mod
6
go.mod
@ -6,6 +6,7 @@ require (
|
|||||||
github.com/BurntSushi/toml v0.0.0-20170318202913-d94612f9fc14 // indirect
|
github.com/BurntSushi/toml v0.0.0-20170318202913-d94612f9fc14 // indirect
|
||||||
github.com/Jeffail/gabs v1.1.1 // indirect
|
github.com/Jeffail/gabs v1.1.1 // indirect
|
||||||
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329
|
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329
|
||||||
|
github.com/Rhymen/go-whatsapp v0.0.2-0.20190325075644-cc2581bbf24d
|
||||||
github.com/bwmarrin/discordgo v0.19.0
|
github.com/bwmarrin/discordgo v0.19.0
|
||||||
github.com/d5/tengo v1.20.0
|
github.com/d5/tengo v1.20.0
|
||||||
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
|
github.com/dfordsoft/golib v0.0.0-20180902042739-76ee6ab99bec
|
||||||
@ -27,12 +28,10 @@ require (
|
|||||||
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect
|
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect
|
||||||
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 // indirect
|
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 // indirect
|
||||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
|
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d
|
||||||
github.com/matterbridge/go-whatsapp v0.0.1-0.20190301204034-f2f1b29d441b
|
|
||||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
|
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
|
||||||
github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea
|
github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea
|
||||||
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18
|
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18
|
||||||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
|
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
|
||||||
github.com/matterbridge/mautrix-whatsapp v0.0.0-20190301210046-3539cf52ed6e
|
|
||||||
github.com/mattermost/mattermost-server v5.5.0+incompatible
|
github.com/mattermost/mattermost-server v5.5.0+incompatible
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
|
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
|
||||||
@ -45,7 +44,6 @@ require (
|
|||||||
github.com/paulrosania/go-charset v0.0.0-20151028000031-621bb39fcc83
|
github.com/paulrosania/go-charset v0.0.0-20151028000031-621bb39fcc83
|
||||||
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 // indirect
|
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 // indirect
|
||||||
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320
|
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320
|
||||||
github.com/pkg/errors v0.8.0 // indirect
|
|
||||||
github.com/rs/xid v1.2.1
|
github.com/rs/xid v1.2.1
|
||||||
github.com/russross/blackfriday v1.5.2
|
github.com/russross/blackfriday v1.5.2
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
||||||
@ -68,7 +66,9 @@ require (
|
|||||||
go.uber.org/multierr v1.1.0 // indirect
|
go.uber.org/multierr v1.1.0 // indirect
|
||||||
go.uber.org/zap v1.9.1 // indirect
|
go.uber.org/zap v1.9.1 // indirect
|
||||||
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9
|
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
gopkg.in/fsnotify.v1 v1.4.7 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
|
maunium.net/go/mautrix-whatsapp v0.0.0-20190406194125-7e1028726f0f
|
||||||
)
|
)
|
||||||
|
22
go.sum
22
go.sum
@ -8,6 +8,9 @@ github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
|
|||||||
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
||||||
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329 h1:xZBoq249G9MSt+XuY7sVQzcfONJ6IQuwpCK+KAaOpnY=
|
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329 h1:xZBoq249G9MSt+XuY7sVQzcfONJ6IQuwpCK+KAaOpnY=
|
||||||
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
|
github.com/Philipp15b/go-steam v1.0.1-0.20180818081528-681bd9573329/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
|
||||||
|
github.com/Rhymen/go-whatsapp v0.0.0-20190208090600-c1173899de99/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
|
||||||
|
github.com/Rhymen/go-whatsapp v0.0.2-0.20190325075644-cc2581bbf24d h1:1jxx8vYOakqfKIg4oeQ6R7yZAGd6BG077d4FiNqJygE=
|
||||||
|
github.com/Rhymen/go-whatsapp v0.0.2-0.20190325075644-cc2581bbf24d/go.mod h1:XQ87CLQwmWe3c/2DFsbD6A5b5INpj06JecJbpTC3BbE=
|
||||||
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs+h+PaYkxGeMVmVCX75Zj/pqdjbu12ciCYE=
|
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs+h+PaYkxGeMVmVCX75Zj/pqdjbu12ciCYE=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5awQiY=
|
github.com/bwmarrin/discordgo v0.19.0 h1:kMED/DB0NR1QhRcalb85w0Cu3Ep2OrGAqZH1R5awQiY=
|
||||||
@ -31,6 +34,8 @@ github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9
|
|||||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||||
|
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||||
github.com/google/gops v0.3.5 h1:SIWvPLiYvy5vMwjxB3rVFTE4QBhUFj2KKWr3Xm7CKhw=
|
github.com/google/gops v0.3.5 h1:SIWvPLiYvy5vMwjxB3rVFTE4QBhUFj2KKWr3Xm7CKhw=
|
||||||
github.com/google/gops v0.3.5/go.mod h1:pMQgrscwEK/aUSW1IFSaBPbJX82FPHWaSoJw1axQfD0=
|
github.com/google/gops v0.3.5/go.mod h1:pMQgrscwEK/aUSW1IFSaBPbJX82FPHWaSoJw1axQfD0=
|
||||||
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
|
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
|
||||||
@ -68,6 +73,7 @@ github.com/labstack/echo/v4 v4.0.0 h1:q1GH+caIXPP7H2StPIdzy/ez9CO0EepqYeUg6vi9SW
|
|||||||
github.com/labstack/echo/v4 v4.0.0/go.mod h1:tZv7nai5buKSg5h/8E6zz4LsD/Dqh9/91Mvs7Z5Zyno=
|
github.com/labstack/echo/v4 v4.0.0/go.mod h1:tZv7nai5buKSg5h/8E6zz4LsD/Dqh9/91Mvs7Z5Zyno=
|
||||||
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
||||||
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lrstanley/girc v0.0.0-20190210212025-51b8e096d398 h1:a40kRmhA1p2XFJ6gqXfCExSyuDDCp/U9LA8ZY27u2Lk=
|
github.com/lrstanley/girc v0.0.0-20190210212025-51b8e096d398 h1:a40kRmhA1p2XFJ6gqXfCExSyuDDCp/U9LA8ZY27u2Lk=
|
||||||
github.com/lrstanley/girc v0.0.0-20190210212025-51b8e096d398/go.mod h1:7cRs1SIBfKQ7e3Tam6GKTILSNHzR862JD0JpINaZoJk=
|
github.com/lrstanley/girc v0.0.0-20190210212025-51b8e096d398/go.mod h1:7cRs1SIBfKQ7e3Tam6GKTILSNHzR862JD0JpINaZoJk=
|
||||||
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU=
|
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU=
|
||||||
@ -78,8 +84,6 @@ github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDe
|
|||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
|
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d h1:F+Sr+C0ojSlYQ37BLylQtSFmyQULe3jbAygcyXQ9mVs=
|
||||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
||||||
github.com/matterbridge/go-whatsapp v0.0.1-0.20190301204034-f2f1b29d441b h1:cO6Z+yj4Ivq/ay/IxSrV90oSIW/SSXWLa+XHsiLKMrw=
|
|
||||||
github.com/matterbridge/go-whatsapp v0.0.1-0.20190301204034-f2f1b29d441b/go.mod h1:dW19fYkkdUZsBAx7zv9fDh0n6NRqYIaKwB2JEBw8d0U=
|
|
||||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91 h1:KzDEcy8eDbTx881giW8a6llsAck3e2bJvMyKvh1IK+k=
|
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91 h1:KzDEcy8eDbTx881giW8a6llsAck3e2bJvMyKvh1IK+k=
|
||||||
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
|
github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
|
||||||
github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea h1:kaADGqpK4gGO2BpzEyJrBxq2Jc57Rsar4i2EUxcACUc=
|
github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea h1:kaADGqpK4gGO2BpzEyJrBxq2Jc57Rsar4i2EUxcACUc=
|
||||||
@ -88,8 +92,6 @@ github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18 h1:fLhwXtW
|
|||||||
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA=
|
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA=
|
||||||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61 h1:R/MgM/eUyRBQx2FiH6JVmXck8PaAuKfe2M1tWIzW7nE=
|
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61 h1:R/MgM/eUyRBQx2FiH6JVmXck8PaAuKfe2M1tWIzW7nE=
|
||||||
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
|
github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
|
||||||
github.com/matterbridge/mautrix-whatsapp v0.0.0-20190301210046-3539cf52ed6e h1:1NqciL8sz+0UYeFrd/UQlL8tJPhFxOBmg+a94DN2sJU=
|
|
||||||
github.com/matterbridge/mautrix-whatsapp v0.0.0-20190301210046-3539cf52ed6e/go.mod h1:DrIFGcFumRlEW5k3PJjWGKPd4+w37d3SwOxlh1ZAL+4=
|
|
||||||
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
|
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
|
||||||
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
|
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
@ -125,8 +127,8 @@ github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181
|
|||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320 h1:YxcQy/DV+48NGv1lxx1vsWBzs6W1f1ogubkuCozxpX0=
|
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320 h1:YxcQy/DV+48NGv1lxx1vsWBzs6W1f1ogubkuCozxpX0=
|
||||||
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320/go.mod h1:G7LufuPajuIvdt9OitkNt2qh0mmvD4bfRgRM7bhDIOA=
|
github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320/go.mod h1:G7LufuPajuIvdt9OitkNt2qh0mmvD4bfRgRM7bhDIOA=
|
||||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||||
@ -201,20 +203,26 @@ golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664/go.mod h1:6SG95UA2DQfeDnf
|
|||||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY=
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY=
|
||||||
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9 h1:+vH8qNweCrORN49012OX3h0oWEXO3p+rRnpAGQinddk=
|
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9 h1:+vH8qNweCrORN49012OX3h0oWEXO3p+rRnpAGQinddk=
|
||||||
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190110200230-915654e7eabc h1:Yx9JGxI1SBhVLFjpAkWMaO1TF+xyqtHLjZpvQboJGiM=
|
golang.org/x/net v0.0.0-20190110200230-915654e7eabc h1:Yx9JGxI1SBhVLFjpAkWMaO1TF+xyqtHLjZpvQboJGiM=
|
||||||
golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e h1:oF7qaQxUH6KzFdKN4ww7NpPdo53SZi4UlcksLrb2y/o=
|
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e h1:oF7qaQxUH6KzFdKN4ww7NpPdo53SZi4UlcksLrb2y/o=
|
||||||
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@ -230,3 +238,5 @@ maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfk
|
|||||||
maunium.net/go/maulogger/v2 v2.0.0/go.mod h1:Hbbkq3NV6jvJodByZu1mgEF3fpT7Kz9z0MjEZ3/BusI=
|
maunium.net/go/maulogger/v2 v2.0.0/go.mod h1:Hbbkq3NV6jvJodByZu1mgEF3fpT7Kz9z0MjEZ3/BusI=
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3/go.mod h1:GTVu6WDHR+98DKOrYetWsXorvUeKQV3jsSWO6ScbuFI=
|
maunium.net/go/mautrix v0.1.0-alpha.3/go.mod h1:GTVu6WDHR+98DKOrYetWsXorvUeKQV3jsSWO6ScbuFI=
|
||||||
maunium.net/go/mautrix-appservice v0.1.0-alpha.3/go.mod h1:wOnWOIuprYad7ly12rHIo3JLCPh4jwvx1prVrAB9RhM=
|
maunium.net/go/mautrix-appservice v0.1.0-alpha.3/go.mod h1:wOnWOIuprYad7ly12rHIo3JLCPh4jwvx1prVrAB9RhM=
|
||||||
|
maunium.net/go/mautrix-whatsapp v0.0.0-20190406194125-7e1028726f0f h1:J6eQrwVdnhiAyX56YaKyalRDGxMlXX21+Gqd00eGsro=
|
||||||
|
maunium.net/go/mautrix-whatsapp v0.0.0-20190406194125-7e1028726f0f/go.mod h1:iqJEzlNB8kmssHfS4rmV77Pv+toWkchfUI+NCyauOIA=
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
.idea/
|
.idea/
|
||||||
docs/
|
docs/
|
||||||
|
build/
|
@ -3,7 +3,7 @@ Package rhymen/go-whatsapp implements the WhatsApp Web API to provide a clean in
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```sh
|
```sh
|
||||||
go get github.com/rhymen/go-whatsapp
|
go get github.com/Rhymen/go-whatsapp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
@ -2,7 +2,7 @@ package binary
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matterbridge/go-whatsapp/binary/token"
|
"github.com/Rhymen/go-whatsapp/binary/token"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
@ -2,7 +2,7 @@ package binary
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matterbridge/go-whatsapp/binary/token"
|
"github.com/Rhymen/go-whatsapp/binary/token"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
@ -2,7 +2,7 @@ package binary
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
pb "github.com/matterbridge/go-whatsapp/binary/proto"
|
pb "github.com/Rhymen/go-whatsapp/binary/proto"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
210
vendor/github.com/Rhymen/go-whatsapp/conn.go
generated
vendored
Normal file
210
vendor/github.com/Rhymen/go-whatsapp/conn.go
generated
vendored
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
//Package whatsapp provides a developer API to interact with the WhatsAppWeb-Servers.
|
||||||
|
package whatsapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type metric byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
debugLog metric = iota + 1
|
||||||
|
queryResume
|
||||||
|
queryReceipt
|
||||||
|
queryMedia
|
||||||
|
queryChat
|
||||||
|
queryContacts
|
||||||
|
queryMessages
|
||||||
|
presence
|
||||||
|
presenceSubscribe
|
||||||
|
group
|
||||||
|
read
|
||||||
|
chat
|
||||||
|
received
|
||||||
|
pic
|
||||||
|
status
|
||||||
|
message
|
||||||
|
queryActions
|
||||||
|
block
|
||||||
|
queryGroup
|
||||||
|
queryPreview
|
||||||
|
queryEmoji
|
||||||
|
queryMessageInfo
|
||||||
|
spam
|
||||||
|
querySearch
|
||||||
|
queryIdentity
|
||||||
|
queryUrl
|
||||||
|
profile
|
||||||
|
contact
|
||||||
|
queryVcard
|
||||||
|
queryStatus
|
||||||
|
queryStatusUpdate
|
||||||
|
privacyStatus
|
||||||
|
queryLiveLocations
|
||||||
|
liveLocation
|
||||||
|
queryVname
|
||||||
|
queryLabels
|
||||||
|
call
|
||||||
|
queryCall
|
||||||
|
queryQuickReplies
|
||||||
|
)
|
||||||
|
|
||||||
|
type flag byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
ignore flag = 1 << (7 - iota)
|
||||||
|
ackRequest
|
||||||
|
available
|
||||||
|
notAvailable
|
||||||
|
expires
|
||||||
|
skipOffline
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conn is created by NewConn. Interacting with the initialized Conn is the main way of interacting with our package.
|
||||||
|
It holds all necessary information to make the package work internally.
|
||||||
|
*/
|
||||||
|
type Conn struct {
|
||||||
|
ws *websocketWrapper
|
||||||
|
listener *listenerWrapper
|
||||||
|
|
||||||
|
connected bool
|
||||||
|
loggedIn bool
|
||||||
|
wg *sync.WaitGroup
|
||||||
|
|
||||||
|
session *Session
|
||||||
|
sessionLock uint32
|
||||||
|
handler []Handler
|
||||||
|
msgCount int
|
||||||
|
msgTimeout time.Duration
|
||||||
|
Info *Info
|
||||||
|
Store *Store
|
||||||
|
ServerLastSeen time.Time
|
||||||
|
|
||||||
|
longClientName string
|
||||||
|
shortClientName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type websocketWrapper struct {
|
||||||
|
sync.Mutex
|
||||||
|
conn *websocket.Conn
|
||||||
|
close chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type listenerWrapper struct {
|
||||||
|
sync.RWMutex
|
||||||
|
m map[string]chan string
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates a new connection with a given timeout. The websocket connection to the WhatsAppWeb servers get´s established.
|
||||||
|
The goroutine for handling incoming messages is started
|
||||||
|
*/
|
||||||
|
func NewConn(timeout time.Duration) (*Conn, error) {
|
||||||
|
wac := &Conn{
|
||||||
|
handler: make([]Handler, 0),
|
||||||
|
msgCount: 0,
|
||||||
|
msgTimeout: timeout,
|
||||||
|
Store: newStore(),
|
||||||
|
|
||||||
|
longClientName: "github.com/rhymen/go-whatsapp",
|
||||||
|
shortClientName: "go-whatsapp",
|
||||||
|
}
|
||||||
|
return wac, wac.connect()
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect should be guarded with wsWriteMutex
|
||||||
|
func (wac *Conn) connect() (err error) {
|
||||||
|
if wac.connected {
|
||||||
|
return ErrAlreadyConnected
|
||||||
|
}
|
||||||
|
wac.connected = true
|
||||||
|
defer func() { // set connected to false on error
|
||||||
|
if err != nil {
|
||||||
|
wac.connected = false
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
dialer := &websocket.Dialer{
|
||||||
|
ReadBufferSize: 25 * 1024 * 1024,
|
||||||
|
WriteBufferSize: 10 * 1024 * 1024,
|
||||||
|
HandshakeTimeout: wac.msgTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
headers := http.Header{"Origin": []string{"https://web.whatsapp.com"}}
|
||||||
|
wsConn, _, err := dialer.Dial("wss://web.whatsapp.com/ws", headers)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "couldn't dial whatsapp web websocket")
|
||||||
|
}
|
||||||
|
|
||||||
|
wsConn.SetCloseHandler(func(code int, text string) error {
|
||||||
|
// from default CloseHandler
|
||||||
|
message := websocket.FormatCloseMessage(code, "")
|
||||||
|
err := wsConn.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second))
|
||||||
|
|
||||||
|
// our close handling
|
||||||
|
_, _ = wac.Disconnect()
|
||||||
|
wac.handle(&ErrConnectionClosed{Code: code, Text: text})
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
wac.ws = &websocketWrapper{
|
||||||
|
conn: wsConn,
|
||||||
|
close: make(chan struct{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
wac.listener = &listenerWrapper{
|
||||||
|
m: make(map[string]chan string),
|
||||||
|
}
|
||||||
|
|
||||||
|
wac.wg = &sync.WaitGroup{}
|
||||||
|
wac.wg.Add(2)
|
||||||
|
go wac.readPump()
|
||||||
|
go wac.keepAlive(20000, 60000)
|
||||||
|
|
||||||
|
wac.loggedIn = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) Disconnect() (Session, error) {
|
||||||
|
if !wac.connected {
|
||||||
|
return Session{}, ErrNotConnected
|
||||||
|
}
|
||||||
|
wac.connected = false
|
||||||
|
wac.loggedIn = false
|
||||||
|
|
||||||
|
close(wac.ws.close) //signal close
|
||||||
|
wac.wg.Wait() //wait for close
|
||||||
|
|
||||||
|
err := wac.ws.conn.Close()
|
||||||
|
wac.ws = nil
|
||||||
|
|
||||||
|
if wac.session == nil {
|
||||||
|
return Session{}, err
|
||||||
|
}
|
||||||
|
return *wac.session, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) keepAlive(minIntervalMs int, maxIntervalMs int) {
|
||||||
|
defer wac.wg.Done()
|
||||||
|
|
||||||
|
for {
|
||||||
|
err := wac.sendKeepAlive()
|
||||||
|
if err != nil {
|
||||||
|
wac.handle(errors.Wrap(err, "keepAlive failed"))
|
||||||
|
//TODO: Consequences?
|
||||||
|
}
|
||||||
|
interval := rand.Intn(maxIntervalMs-minIntervalMs) + minIntervalMs
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Duration(interval) * time.Millisecond):
|
||||||
|
case <-wac.ws.close:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ package whatsapp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matterbridge/go-whatsapp/binary"
|
"github.com/Rhymen/go-whatsapp/binary"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -18,21 +18,21 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//TODO: filename? WhatsApp uses Store.Contacts for these functions
|
//TODO: filename? WhatsApp uses Store.Contacts for these functions
|
||||||
//TODO: functions probably shouldn't return a string, maybe build a struct / return json
|
// functions probably shouldn't return a string, maybe build a struct / return json
|
||||||
//TODO: check for further queries
|
// check for further queries
|
||||||
func (wac *Conn) GetProfilePicThumb(jid string) (<-chan string, error) {
|
func (wac *Conn) GetProfilePicThumb(jid string) (<-chan string, error) {
|
||||||
data := []interface{}{"query", "ProfilePicThumb", jid}
|
data := []interface{}{"query", "ProfilePicThumb", jid}
|
||||||
return wac.write(data)
|
return wac.writeJson(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wac *Conn) GetStatus(jid string) (<-chan string, error) {
|
func (wac *Conn) GetStatus(jid string) (<-chan string, error) {
|
||||||
data := []interface{}{"query", "Status", jid}
|
data := []interface{}{"query", "Status", jid}
|
||||||
return wac.write(data)
|
return wac.writeJson(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wac *Conn) SubscribePresence(jid string) (<-chan string, error) {
|
func (wac *Conn) SubscribePresence(jid string) (<-chan string, error) {
|
||||||
data := []interface{}{"action", "presence", "subscribe", jid}
|
data := []interface{}{"action", "presence", "subscribe", jid}
|
||||||
return wac.write(data)
|
return wac.writeJson(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wac *Conn) Search(search string, count, page int) (*binary.Node, error) {
|
func (wac *Conn) Search(search string, count, page int) (*binary.Node, error) {
|
||||||
@ -84,7 +84,7 @@ func (wac *Conn) Presence(jid string, presence Presence) (<-chan string, error)
|
|||||||
|
|
||||||
func (wac *Conn) Exist(jid string) (<-chan string, error) {
|
func (wac *Conn) Exist(jid string) (<-chan string, error) {
|
||||||
data := []interface{}{"query", "exist", jid}
|
data := []interface{}{"query", "exist", jid}
|
||||||
return wac.write(data)
|
return wac.writeJson(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wac *Conn) Emoji() (*binary.Node, error) {
|
func (wac *Conn) Emoji() (*binary.Node, error) {
|
35
vendor/github.com/Rhymen/go-whatsapp/errors.go
generated
vendored
Normal file
35
vendor/github.com/Rhymen/go-whatsapp/errors.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package whatsapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrAlreadyConnected = errors.New("already connected")
|
||||||
|
ErrAlreadyLoggedIn = errors.New("already logged in")
|
||||||
|
ErrInvalidSession = errors.New("invalid session")
|
||||||
|
ErrLoginInProgress = errors.New("login or restore already running")
|
||||||
|
ErrNotConnected = errors.New("not connected")
|
||||||
|
ErrInvalidWsData = errors.New("received invalid data")
|
||||||
|
ErrConnectionTimeout = errors.New("connection timed out")
|
||||||
|
ErrMissingMessageTag = errors.New("no messageTag specified or to short")
|
||||||
|
ErrInvalidHmac = errors.New("invalid hmac")
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrConnectionFailed struct {
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrConnectionFailed) Error() string {
|
||||||
|
return fmt.Sprintf("connection to WhatsApp servers failed: %v", e.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrConnectionClosed struct {
|
||||||
|
Code int
|
||||||
|
Text string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrConnectionClosed) Error() string {
|
||||||
|
return fmt.Sprintf("server closed connection,code: %d,text: %s", e.Code, e.Text)
|
||||||
|
}
|
8
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
Normal file
8
vendor/github.com/Rhymen/go-whatsapp/go.mod
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module github.com/Rhymen/go-whatsapp
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/golang/protobuf v1.3.0
|
||||||
|
github.com/gorilla/websocket v1.4.0
|
||||||
|
github.com/pkg/errors v0.8.1
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||||
|
)
|
14
vendor/github.com/Rhymen/go-whatsapp/go.sum
generated
vendored
Normal file
14
vendor/github.com/Rhymen/go-whatsapp/go.sum
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||||
|
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||||
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func (wac *Conn) GetGroupMetaData(jid string) (<-chan string, error) {
|
func (wac *Conn) GetGroupMetaData(jid string) (<-chan string, error) {
|
||||||
data := []interface{}{"query", "GroupMetadata", jid}
|
data := []interface{}{"query", "GroupMetadata", jid}
|
||||||
return wac.write(data)
|
return wac.writeJson(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wac *Conn) CreateGroup(subject string, participants []string) (<-chan string, error) {
|
func (wac *Conn) CreateGroup(subject string, participants []string) (<-chan string, error) {
|
||||||
@ -41,7 +41,7 @@ func (wac *Conn) LeaveGroup(jid string) (<-chan string, error) {
|
|||||||
|
|
||||||
func (wac *Conn) GroupInviteLink(jid string) (string, error) {
|
func (wac *Conn) GroupInviteLink(jid string) (string, error) {
|
||||||
request := []interface{}{"query", "inviteCode", jid}
|
request := []interface{}{"query", "inviteCode", jid}
|
||||||
ch, err := wac.write(request)
|
ch, err := wac.writeJson(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -63,3 +63,28 @@ func (wac *Conn) GroupInviteLink(jid string) (string, error) {
|
|||||||
|
|
||||||
return response["code"].(string), nil
|
return response["code"].(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) GroupAcceptInviteCode(code string) (jid string, err error) {
|
||||||
|
request := []interface{}{"action", "invite", code}
|
||||||
|
ch, err := wac.writeJson(request)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response map[string]interface{}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case r := <-ch:
|
||||||
|
if err := json.Unmarshal([]byte(r), &response); err != nil {
|
||||||
|
return "", fmt.Errorf("error decoding response message: %v\n", err)
|
||||||
|
}
|
||||||
|
case <-time.After(wac.msgTimeout):
|
||||||
|
return "", fmt.Errorf("request timed out")
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(response["status"].(float64)) != 200 {
|
||||||
|
return "", fmt.Errorf("request responded with %d", response["status"])
|
||||||
|
}
|
||||||
|
|
||||||
|
return response["gid"].(string), nil
|
||||||
|
}
|
@ -2,9 +2,10 @@ package whatsapp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matterbridge/go-whatsapp/binary"
|
|
||||||
"github.com/matterbridge/go-whatsapp/binary/proto"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/Rhymen/go-whatsapp/binary"
|
||||||
|
"github.com/Rhymen/go-whatsapp/binary/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -88,6 +89,27 @@ func (wac *Conn) AddHandler(handler Handler) {
|
|||||||
wac.handler = append(wac.handler, handler)
|
wac.handler = append(wac.handler, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveHandler removes a handler from the list of handlers that receive dispatched messages.
|
||||||
|
func (wac *Conn) RemoveHandler(handler Handler) bool {
|
||||||
|
i := -1
|
||||||
|
for k, v := range wac.handler {
|
||||||
|
if v == handler {
|
||||||
|
i = k
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i > -1 {
|
||||||
|
wac.handler = append(wac.handler[:i], wac.handler[i+1:]...)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveHandlers empties the list of handlers that receive dispatched messages.
|
||||||
|
func (wac *Conn) RemoveHandlers() {
|
||||||
|
wac.handler = make([]Handler, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func (wac *Conn) handle(message interface{}) {
|
func (wac *Conn) handle(message interface{}) {
|
||||||
switch m := message.(type) {
|
switch m := message.(type) {
|
||||||
case error:
|
case error:
|
@ -8,8 +8,8 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matterbridge/go-whatsapp/crypto/cbc"
|
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||||
"github.com/matterbridge/go-whatsapp/crypto/hkdf"
|
"github.com/Rhymen/go-whatsapp/crypto/hkdf"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
@ -133,7 +133,7 @@ func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (url string, mediaK
|
|||||||
}
|
}
|
||||||
|
|
||||||
uploadReq := []interface{}{"action", "encr_upload", filetype, base64.StdEncoding.EncodeToString(fileEncSha256)}
|
uploadReq := []interface{}{"action", "encr_upload", filetype, base64.StdEncoding.EncodeToString(fileEncSha256)}
|
||||||
ch, err := wac.write(uploadReq)
|
ch, err := wac.writeJson(uploadReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, nil, nil, 0, err
|
return "", nil, nil, nil, 0, err
|
||||||
}
|
}
|
@ -4,8 +4,8 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/matterbridge/go-whatsapp/binary"
|
"github.com/Rhymen/go-whatsapp/binary"
|
||||||
"github.com/matterbridge/go-whatsapp/binary/proto"
|
"github.com/Rhymen/go-whatsapp/binary/proto"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
111
vendor/github.com/Rhymen/go-whatsapp/read.go
generated
vendored
Normal file
111
vendor/github.com/Rhymen/go-whatsapp/read.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package whatsapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"github.com/Rhymen/go-whatsapp/binary"
|
||||||
|
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (wac *Conn) readPump() {
|
||||||
|
defer wac.wg.Done()
|
||||||
|
|
||||||
|
var readErr error
|
||||||
|
var msgType int
|
||||||
|
var reader io.Reader
|
||||||
|
|
||||||
|
for {
|
||||||
|
readerFound := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
msgType, reader, readErr = wac.ws.conn.NextReader()
|
||||||
|
close(readerFound)
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case <-readerFound:
|
||||||
|
if readErr != nil {
|
||||||
|
wac.handle(&ErrConnectionFailed{Err: readErr})
|
||||||
|
_, _ = wac.Disconnect()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg, err := ioutil.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
wac.handle(errors.Wrap(err, "error reading message from Reader"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = wac.processReadData(msgType, msg)
|
||||||
|
if err != nil {
|
||||||
|
wac.handle(errors.Wrap(err, "error processing data"))
|
||||||
|
}
|
||||||
|
case <-wac.ws.close:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) processReadData(msgType int, msg []byte) error {
|
||||||
|
data := strings.SplitN(string(msg), ",", 2)
|
||||||
|
|
||||||
|
if data[0][0] == '!' { //Keep-Alive Timestamp
|
||||||
|
data = append(data, data[0][1:]) //data[1]
|
||||||
|
data[0] = "!"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) != 2 || len(data[1]) == 0 {
|
||||||
|
return ErrInvalidWsData
|
||||||
|
}
|
||||||
|
|
||||||
|
wac.listener.RLock()
|
||||||
|
listener, hasListener := wac.listener.m[data[0]]
|
||||||
|
wac.listener.RUnlock()
|
||||||
|
|
||||||
|
if hasListener {
|
||||||
|
// listener only exists for TextMessages query messages out of contact.go
|
||||||
|
// If these binary query messages can be handled another way,
|
||||||
|
// then the TextMessages, which are all JSON encoded, can directly
|
||||||
|
// be unmarshalled. The listener chan could then be changed from type
|
||||||
|
// chan string to something like chan map[string]interface{}. The unmarshalling
|
||||||
|
// in several places, especially in session.go, would then be gone.
|
||||||
|
listener <- data[1]
|
||||||
|
|
||||||
|
wac.listener.Lock()
|
||||||
|
delete(wac.listener.m, data[0])
|
||||||
|
wac.listener.Unlock()
|
||||||
|
} else if msgType == websocket.BinaryMessage && wac.loggedIn {
|
||||||
|
message, err := wac.decryptBinaryMessage([]byte(data[1]))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error decoding binary")
|
||||||
|
}
|
||||||
|
wac.dispatch(message)
|
||||||
|
} else { //RAW json status updates
|
||||||
|
wac.handle(string(data[1]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) decryptBinaryMessage(msg []byte) (*binary.Node, error) {
|
||||||
|
//message validation
|
||||||
|
h2 := hmac.New(sha256.New, wac.session.MacKey)
|
||||||
|
h2.Write([]byte(msg[32:]))
|
||||||
|
if !hmac.Equal(h2.Sum(nil), msg[:32]) {
|
||||||
|
return nil, ErrInvalidHmac
|
||||||
|
}
|
||||||
|
|
||||||
|
// message decrypt
|
||||||
|
d, err := cbc.Decrypt(wac.session.EncKey, nil, msg[32:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "decrypting message with AES-CBC failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// message unmarshal
|
||||||
|
message, err := binary.Unmarshal(d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not decode binary")
|
||||||
|
}
|
||||||
|
|
||||||
|
return message, nil
|
||||||
|
}
|
@ -7,11 +7,12 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp/crypto/cbc"
|
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||||
"github.com/matterbridge/go-whatsapp/crypto/curve25519"
|
"github.com/Rhymen/go-whatsapp/crypto/curve25519"
|
||||||
"github.com/matterbridge/go-whatsapp/crypto/hkdf"
|
"github.com/Rhymen/go-whatsapp/crypto/hkdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -121,7 +122,21 @@ github.com/Baozisoftware/qrcode-terminal-go Example login procedure:
|
|||||||
*/
|
*/
|
||||||
func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
|
func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
|
||||||
session := Session{}
|
session := Session{}
|
||||||
|
//Makes sure that only a single Login or Restore can happen at the same time
|
||||||
|
if !atomic.CompareAndSwapUint32(&wac.sessionLock, 0, 1) {
|
||||||
|
return session, ErrLoginInProgress
|
||||||
|
}
|
||||||
|
defer atomic.StoreUint32(&wac.sessionLock, 0)
|
||||||
|
|
||||||
|
if wac.loggedIn {
|
||||||
|
return session, ErrAlreadyLoggedIn
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := wac.connect(); err != nil && err != ErrAlreadyConnected {
|
||||||
|
return session, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//logged in?!?
|
||||||
if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) {
|
if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) {
|
||||||
return session, fmt.Errorf("already logged in")
|
return session, fmt.Errorf("already logged in")
|
||||||
}
|
}
|
||||||
@ -135,7 +150,7 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
|
|||||||
session.ClientId = base64.StdEncoding.EncodeToString(clientId)
|
session.ClientId = base64.StdEncoding.EncodeToString(clientId)
|
||||||
//oldVersion=8691
|
//oldVersion=8691
|
||||||
login := []interface{}{"admin", "init", []int{0, 3, 225}, []string{wac.longClientName, wac.shortClientName}, session.ClientId, true}
|
login := []interface{}{"admin", "init", []int{0, 3, 225}, []string{wac.longClientName, wac.shortClientName}, session.ClientId, true}
|
||||||
loginChan, err := wac.write(login)
|
loginChan, err := wac.writeJson(login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return session, fmt.Errorf("error writing login: %v\n", err)
|
return session, fmt.Errorf("error writing login: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -160,14 +175,16 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//listener for Login response
|
//listener for Login response
|
||||||
messageTag := "s1"
|
s1 := make(chan string, 1)
|
||||||
wac.listener[messageTag] = make(chan string, 1)
|
wac.listener.Lock()
|
||||||
|
wac.listener.m["s1"] = s1
|
||||||
|
wac.listener.Unlock()
|
||||||
|
|
||||||
qrChan <- fmt.Sprintf("%v,%v,%v", ref, base64.StdEncoding.EncodeToString(pub[:]), session.ClientId)
|
qrChan <- fmt.Sprintf("%v,%v,%v", ref, base64.StdEncoding.EncodeToString(pub[:]), session.ClientId)
|
||||||
|
|
||||||
var resp2 []interface{}
|
var resp2 []interface{}
|
||||||
select {
|
select {
|
||||||
case r1 := <-wac.listener[messageTag]:
|
case r1 := <-s1:
|
||||||
if err := json.Unmarshal([]byte(r1), &resp2); err != nil {
|
if err := json.Unmarshal([]byte(r1), &resp2); err != nil {
|
||||||
return session, fmt.Errorf("error decoding qr code resp: %v", err)
|
return session, fmt.Errorf("error decoding qr code resp: %v", err)
|
||||||
}
|
}
|
||||||
@ -226,90 +243,136 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
|
|||||||
session.EncKey = keyDecrypted[:32]
|
session.EncKey = keyDecrypted[:32]
|
||||||
session.MacKey = keyDecrypted[32:64]
|
session.MacKey = keyDecrypted[32:64]
|
||||||
wac.session = &session
|
wac.session = &session
|
||||||
|
wac.loggedIn = true
|
||||||
|
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: GoDoc
|
||||||
/*
|
/*
|
||||||
|
Basically the old RestoreSession functionality
|
||||||
|
*/
|
||||||
|
func (wac *Conn) RestoreWithSession(session Session) (_ Session, err error) {
|
||||||
|
if wac.loggedIn {
|
||||||
|
return Session{}, ErrAlreadyLoggedIn
|
||||||
|
}
|
||||||
|
old := wac.session
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
wac.session = old
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
wac.session = &session
|
||||||
|
|
||||||
|
if err = wac.Restore(); err != nil {
|
||||||
|
wac.session = nil
|
||||||
|
return Session{}, err
|
||||||
|
}
|
||||||
|
return *wac.session, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//TODO: GoDoc
|
||||||
RestoreSession is the function that restores a given session. It will try to reestablish the connection to the
|
RestoreSession is the function that restores a given session. It will try to reestablish the connection to the
|
||||||
WhatsAppWeb servers with the provided session. If it succeeds it will return a new session. This new session has to be
|
WhatsAppWeb servers with the provided session. If it succeeds it will return a new session. This new session has to be
|
||||||
saved because the Client and Server-Token will change after every login. Logging in with old tokens is possible, but not
|
saved because the Client and Server-Token will change after every login. Logging in with old tokens is possible, but not
|
||||||
suggested. If so, a challenge has to be resolved which is just another possible point of failure.
|
suggested. If so, a challenge has to be resolved which is just another possible point of failure.
|
||||||
*/
|
*/
|
||||||
func (wac *Conn) RestoreSession(session Session) (Session, error) {
|
func (wac *Conn) Restore() error {
|
||||||
if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) {
|
//Makes sure that only a single Login or Restore can happen at the same time
|
||||||
return Session{}, fmt.Errorf("already logged in")
|
if !atomic.CompareAndSwapUint32(&wac.sessionLock, 0, 1) {
|
||||||
|
return ErrLoginInProgress
|
||||||
|
}
|
||||||
|
defer atomic.StoreUint32(&wac.sessionLock, 0)
|
||||||
|
|
||||||
|
if wac.session == nil {
|
||||||
|
return ErrInvalidSession
|
||||||
}
|
}
|
||||||
|
|
||||||
wac.session = &session
|
if err := wac.connect(); err != nil && err != ErrAlreadyConnected {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if wac.loggedIn {
|
||||||
|
return ErrAlreadyLoggedIn
|
||||||
|
}
|
||||||
|
|
||||||
//listener for Conn or challenge; s1 is not allowed to drop
|
//listener for Conn or challenge; s1 is not allowed to drop
|
||||||
wac.listener["s1"] = make(chan string, 1)
|
s1 := make(chan string, 1)
|
||||||
|
wac.listener.Lock()
|
||||||
|
wac.listener.m["s1"] = s1
|
||||||
|
wac.listener.Unlock()
|
||||||
|
|
||||||
//admin init
|
//admin init
|
||||||
init := []interface{}{"admin", "init", []int{0, 3, 225}, []string{wac.longClientName, wac.shortClientName}, session.ClientId, true}
|
init := []interface{}{"admin", "init", []int{0, 3, 225}, []string{wac.longClientName, wac.shortClientName}, wac.session.ClientId, true}
|
||||||
initChan, err := wac.write(init)
|
initChan, err := wac.writeJson(init)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error writing admin init: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error writing admin init: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//admin login with takeover
|
//admin login with takeover
|
||||||
login := []interface{}{"admin", "login", session.ClientToken, session.ServerToken, session.ClientId, "takeover"}
|
login := []interface{}{"admin", "login", wac.session.ClientToken, wac.session.ServerToken, wac.session.ClientId, "takeover"}
|
||||||
loginChan, err := wac.write(login)
|
loginChan, err := wac.writeJson(login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error writing admin login: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error writing admin login: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case r := <-initChan:
|
case r := <-initChan:
|
||||||
var resp map[string]interface{}
|
var resp map[string]interface{}
|
||||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error decoding login connResp: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error decoding login connResp: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(resp["status"].(float64)) != 200 {
|
if int(resp["status"].(float64)) != 200 {
|
||||||
wac.session = nil
|
return fmt.Errorf("init responded with %d", resp["status"])
|
||||||
return Session{}, fmt.Errorf("init responded with %d", resp["status"])
|
|
||||||
}
|
}
|
||||||
case <-time.After(wac.msgTimeout):
|
case <-time.After(wac.msgTimeout):
|
||||||
wac.session = nil
|
return fmt.Errorf("restore session init timed out")
|
||||||
return Session{}, fmt.Errorf("restore session init timed out")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//wait for s1
|
//wait for s1
|
||||||
var connResp []interface{}
|
var connResp []interface{}
|
||||||
select {
|
select {
|
||||||
case r1 := <-wac.listener["s1"]:
|
case r1 := <-s1:
|
||||||
if err := json.Unmarshal([]byte(r1), &connResp); err != nil {
|
if err := json.Unmarshal([]byte(r1), &connResp); err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error decoding s1 message: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error decoding s1 message: %v\n", err)
|
|
||||||
}
|
}
|
||||||
case <-time.After(wac.msgTimeout):
|
case <-time.After(wac.msgTimeout):
|
||||||
wac.session = nil
|
|
||||||
return Session{}, fmt.Errorf("restore session connection timed out")
|
//check for an error message
|
||||||
|
select {
|
||||||
|
case r := <-loginChan:
|
||||||
|
var resp map[string]interface{}
|
||||||
|
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||||
|
return fmt.Errorf("error decoding login connResp: %v\n", err)
|
||||||
|
}
|
||||||
|
if int(resp["status"].(float64)) != 200 {
|
||||||
|
return fmt.Errorf("admin login responded with %d", int(resp["status"].(float64)))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// not even an error message – assume timeout
|
||||||
|
return fmt.Errorf("restore session connection timed out")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if challenge is present
|
//check if challenge is present
|
||||||
if len(connResp) == 2 && connResp[0] == "Cmd" && connResp[1].(map[string]interface{})["type"] == "challenge" {
|
if len(connResp) == 2 && connResp[0] == "Cmd" && connResp[1].(map[string]interface{})["type"] == "challenge" {
|
||||||
wac.listener["s2"] = make(chan string, 1)
|
s2 := make(chan string, 1)
|
||||||
|
wac.listener.Lock()
|
||||||
|
wac.listener.m["s2"] = s2
|
||||||
|
wac.listener.Unlock()
|
||||||
|
|
||||||
if err := wac.resolveChallenge(connResp[1].(map[string]interface{})["challenge"].(string)); err != nil {
|
if err := wac.resolveChallenge(connResp[1].(map[string]interface{})["challenge"].(string)); err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error resolving challenge: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error resolving challenge: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case r := <-wac.listener["s2"]:
|
case r := <-s2:
|
||||||
if err := json.Unmarshal([]byte(r), &connResp); err != nil {
|
if err := json.Unmarshal([]byte(r), &connResp); err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error decoding s2 message: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error decoding s2 message: %v\n", err)
|
|
||||||
}
|
}
|
||||||
case <-time.After(wac.msgTimeout):
|
case <-time.After(wac.msgTimeout):
|
||||||
wac.session = nil
|
return fmt.Errorf("restore session challenge timed out")
|
||||||
return Session{}, fmt.Errorf("restore session challenge timed out")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,17 +381,14 @@ func (wac *Conn) RestoreSession(session Session) (Session, error) {
|
|||||||
case r := <-loginChan:
|
case r := <-loginChan:
|
||||||
var resp map[string]interface{}
|
var resp map[string]interface{}
|
||||||
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
if err = json.Unmarshal([]byte(r), &resp); err != nil {
|
||||||
wac.session = nil
|
return fmt.Errorf("error decoding login connResp: %v\n", err)
|
||||||
return Session{}, fmt.Errorf("error decoding login connResp: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(resp["status"].(float64)) != 200 {
|
if int(resp["status"].(float64)) != 200 {
|
||||||
wac.session = nil
|
return fmt.Errorf("admin login responded with %d", resp["status"])
|
||||||
return Session{}, fmt.Errorf("admin login responded with %d", resp["status"])
|
|
||||||
}
|
}
|
||||||
case <-time.After(wac.msgTimeout):
|
case <-time.After(wac.msgTimeout):
|
||||||
wac.session = nil
|
return fmt.Errorf("restore session login timed out")
|
||||||
return Session{}, fmt.Errorf("restore session login timed out")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info := connResp[1].(map[string]interface{})
|
info := connResp[1].(map[string]interface{})
|
||||||
@ -336,11 +396,12 @@ func (wac *Conn) RestoreSession(session Session) (Session, error) {
|
|||||||
wac.Info = newInfoFromReq(info)
|
wac.Info = newInfoFromReq(info)
|
||||||
|
|
||||||
//set new tokens
|
//set new tokens
|
||||||
session.ClientToken = info["clientToken"].(string)
|
wac.session.ClientToken = info["clientToken"].(string)
|
||||||
session.ServerToken = info["serverToken"].(string)
|
wac.session.ServerToken = info["serverToken"].(string)
|
||||||
session.Wid = info["wid"].(string)
|
wac.session.Wid = info["wid"].(string)
|
||||||
|
wac.loggedIn = true
|
||||||
|
|
||||||
return *wac.session, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wac *Conn) resolveChallenge(challenge string) error {
|
func (wac *Conn) resolveChallenge(challenge string) error {
|
||||||
@ -353,7 +414,7 @@ func (wac *Conn) resolveChallenge(challenge string) error {
|
|||||||
h2.Write([]byte(decoded))
|
h2.Write([]byte(decoded))
|
||||||
|
|
||||||
ch := []interface{}{"admin", "challenge", base64.StdEncoding.EncodeToString(h2.Sum(nil)), wac.session.ServerToken, wac.session.ClientId}
|
ch := []interface{}{"admin", "challenge", base64.StdEncoding.EncodeToString(h2.Sum(nil)), wac.session.ServerToken, wac.session.ClientId}
|
||||||
challengeChan, err := wac.write(ch)
|
challengeChan, err := wac.writeJson(ch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error writing challenge: %v\n", err)
|
return fmt.Errorf("error writing challenge: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -380,7 +441,7 @@ The session can not be resumed and will disappear on your phone in the WhatsAppW
|
|||||||
*/
|
*/
|
||||||
func (wac *Conn) Logout() error {
|
func (wac *Conn) Logout() error {
|
||||||
login := []interface{}{"admin", "Conn", "disconnect"}
|
login := []interface{}{"admin", "Conn", "disconnect"}
|
||||||
_, err := wac.write(login)
|
_, err := wac.writeJson(login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error writing logout: %v\n", err)
|
return fmt.Errorf("error writing logout: %v\n", err)
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package whatsapp
|
package whatsapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/matterbridge/go-whatsapp/binary"
|
"github.com/Rhymen/go-whatsapp/binary"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
125
vendor/github.com/Rhymen/go-whatsapp/write.go
generated
vendored
Normal file
125
vendor/github.com/Rhymen/go-whatsapp/write.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package whatsapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Rhymen/go-whatsapp/binary"
|
||||||
|
"github.com/Rhymen/go-whatsapp/crypto/cbc"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//writeJson enqueues a json message into the writeChan
|
||||||
|
func (wac *Conn) writeJson(data []interface{}) (<-chan string, error) {
|
||||||
|
d, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := time.Now().Unix()
|
||||||
|
messageTag := fmt.Sprintf("%d.--%d", ts, wac.msgCount)
|
||||||
|
bytes := []byte(fmt.Sprintf("%s,%s", messageTag, d))
|
||||||
|
|
||||||
|
ch, err := wac.write(websocket.TextMessage, messageTag, bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
wac.msgCount++
|
||||||
|
return ch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) writeBinary(node binary.Node, metric metric, flag flag, messageTag string) (<-chan string, error) {
|
||||||
|
if len(messageTag) < 2 {
|
||||||
|
return nil, ErrMissingMessageTag
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := wac.encryptBinaryMessage(node)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "encryptBinaryMessage(node) failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes := []byte(messageTag + ",")
|
||||||
|
bytes = append(bytes, byte(metric), byte(flag))
|
||||||
|
bytes = append(bytes, data...)
|
||||||
|
|
||||||
|
ch, err := wac.write(websocket.BinaryMessage, messageTag, bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to write message")
|
||||||
|
}
|
||||||
|
|
||||||
|
wac.msgCount++
|
||||||
|
return ch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) sendKeepAlive() error {
|
||||||
|
bytes := []byte("?,,")
|
||||||
|
respChan, err := wac.write(websocket.TextMessage, "!", bytes)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error sending keepAlive")
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case resp := <-respChan:
|
||||||
|
msecs, err := strconv.ParseInt(resp, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error converting time string to uint")
|
||||||
|
}
|
||||||
|
wac.ServerLastSeen = time.Unix(msecs/1000, (msecs%1000)*int64(time.Millisecond))
|
||||||
|
|
||||||
|
case <-time.After(wac.msgTimeout):
|
||||||
|
return ErrConnectionTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) write(messageType int, answerMessageTag string, data []byte) (<-chan string, error) {
|
||||||
|
var ch chan string
|
||||||
|
if answerMessageTag != "" {
|
||||||
|
ch = make(chan string, 1)
|
||||||
|
|
||||||
|
wac.listener.Lock()
|
||||||
|
wac.listener.m[answerMessageTag] = ch
|
||||||
|
wac.listener.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
wac.ws.Lock()
|
||||||
|
err := wac.ws.conn.WriteMessage(messageType, data)
|
||||||
|
wac.ws.Unlock()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if answerMessageTag != "" {
|
||||||
|
wac.listener.Lock()
|
||||||
|
delete(wac.listener.m, answerMessageTag)
|
||||||
|
wac.listener.Unlock()
|
||||||
|
}
|
||||||
|
return nil, errors.Wrap(err, "error writing to websocket")
|
||||||
|
}
|
||||||
|
return ch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wac *Conn) encryptBinaryMessage(node binary.Node) (data []byte, err error) {
|
||||||
|
b, err := binary.Marshal(node)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "binary node marshal failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher, err := cbc.Encrypt(wac.session.EncKey, nil, b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "encrypt failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
h := hmac.New(sha256.New, wac.session.MacKey)
|
||||||
|
h.Write(cipher)
|
||||||
|
hash := h.Sum(nil)
|
||||||
|
|
||||||
|
data = append(data, hash[:32]...)
|
||||||
|
data = append(data, cipher...)
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
1
vendor/github.com/golang/protobuf/proto/decode.go
generated
vendored
1
vendor/github.com/golang/protobuf/proto/decode.go
generated
vendored
@ -186,7 +186,6 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
|||||||
if b&0x80 == 0 {
|
if b&0x80 == 0 {
|
||||||
goto done
|
goto done
|
||||||
}
|
}
|
||||||
// x -= 0x80 << 63 // Always zero.
|
|
||||||
|
|
||||||
return 0, errOverflow
|
return 0, errOverflow
|
||||||
|
|
||||||
|
63
vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
Normal file
63
vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
func GetStats() Stats { return Stats{} }
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
func MarshalMessageSet(interface{}) ([]byte, error) {
|
||||||
|
return nil, errors.New("proto: not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
func UnmarshalMessageSet([]byte, interface{}) error {
|
||||||
|
return errors.New("proto: not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
func MarshalMessageSetJSON(interface{}) ([]byte, error) {
|
||||||
|
return nil, errors.New("proto: not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
func UnmarshalMessageSetJSON([]byte, interface{}) error {
|
||||||
|
return errors.New("proto: not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: do not use.
|
||||||
|
func RegisterMessageSetType(Message, int32, string) {}
|
3
vendor/github.com/golang/protobuf/proto/equal.go
generated
vendored
3
vendor/github.com/golang/protobuf/proto/equal.go
generated
vendored
@ -246,7 +246,8 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
m1, m2 := e1.value, e2.value
|
m1 := extensionAsLegacyType(e1.value)
|
||||||
|
m2 := extensionAsLegacyType(e2.value)
|
||||||
|
|
||||||
if m1 == nil && m2 == nil {
|
if m1 == nil && m2 == nil {
|
||||||
// Both have only encoded form.
|
// Both have only encoded form.
|
||||||
|
78
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
78
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
@ -185,9 +185,25 @@ type Extension struct {
|
|||||||
// extension will have only enc set. When such an extension is
|
// extension will have only enc set. When such an extension is
|
||||||
// accessed using GetExtension (or GetExtensions) desc and value
|
// accessed using GetExtension (or GetExtensions) desc and value
|
||||||
// will be set.
|
// will be set.
|
||||||
desc *ExtensionDesc
|
desc *ExtensionDesc
|
||||||
|
|
||||||
|
// value is a concrete value for the extension field. Let the type of
|
||||||
|
// desc.ExtensionType be the "API type" and the type of Extension.value
|
||||||
|
// be the "storage type". The API type and storage type are the same except:
|
||||||
|
// * For scalars (except []byte), the API type uses *T,
|
||||||
|
// while the storage type uses T.
|
||||||
|
// * For repeated fields, the API type uses []T, while the storage type
|
||||||
|
// uses *[]T.
|
||||||
|
//
|
||||||
|
// The reason for the divergence is so that the storage type more naturally
|
||||||
|
// matches what is expected of when retrieving the values through the
|
||||||
|
// protobuf reflection APIs.
|
||||||
|
//
|
||||||
|
// The value may only be populated if desc is also populated.
|
||||||
value interface{}
|
value interface{}
|
||||||
enc []byte
|
|
||||||
|
// enc is the raw bytes for the extension field.
|
||||||
|
enc []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRawExtension is for testing only.
|
// SetRawExtension is for testing only.
|
||||||
@ -334,7 +350,7 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
|||||||
// descriptors with the same field number.
|
// descriptors with the same field number.
|
||||||
return nil, errors.New("proto: descriptor conflict")
|
return nil, errors.New("proto: descriptor conflict")
|
||||||
}
|
}
|
||||||
return e.value, nil
|
return extensionAsLegacyType(e.value), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if extension.ExtensionType == nil {
|
if extension.ExtensionType == nil {
|
||||||
@ -349,11 +365,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
|||||||
|
|
||||||
// Remember the decoded version and drop the encoded version.
|
// Remember the decoded version and drop the encoded version.
|
||||||
// That way it is safe to mutate what we return.
|
// That way it is safe to mutate what we return.
|
||||||
e.value = v
|
e.value = extensionAsStorageType(v)
|
||||||
e.desc = extension
|
e.desc = extension
|
||||||
e.enc = nil
|
e.enc = nil
|
||||||
emap[extension.Field] = e
|
emap[extension.Field] = e
|
||||||
return e.value, nil
|
return extensionAsLegacyType(e.value), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultExtensionValue returns the default value for extension.
|
// defaultExtensionValue returns the default value for extension.
|
||||||
@ -488,7 +504,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
|
|||||||
}
|
}
|
||||||
typ := reflect.TypeOf(extension.ExtensionType)
|
typ := reflect.TypeOf(extension.ExtensionType)
|
||||||
if typ != reflect.TypeOf(value) {
|
if typ != reflect.TypeOf(value) {
|
||||||
return errors.New("proto: bad extension value type")
|
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
|
||||||
}
|
}
|
||||||
// nil extension values need to be caught early, because the
|
// nil extension values need to be caught early, because the
|
||||||
// encoder can't distinguish an ErrNil due to a nil extension
|
// encoder can't distinguish an ErrNil due to a nil extension
|
||||||
@ -500,7 +516,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
extmap := epb.extensionsWrite()
|
extmap := epb.extensionsWrite()
|
||||||
extmap[extension.Field] = Extension{desc: extension, value: value}
|
extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,3 +557,51 @@ func RegisterExtension(desc *ExtensionDesc) {
|
|||||||
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
||||||
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extensionAsLegacyType converts an value in the storage type as the API type.
|
||||||
|
// See Extension.value.
|
||||||
|
func extensionAsLegacyType(v interface{}) interface{} {
|
||||||
|
switch rv := reflect.ValueOf(v); rv.Kind() {
|
||||||
|
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
||||||
|
// Represent primitive types as a pointer to the value.
|
||||||
|
rv2 := reflect.New(rv.Type())
|
||||||
|
rv2.Elem().Set(rv)
|
||||||
|
v = rv2.Interface()
|
||||||
|
case reflect.Ptr:
|
||||||
|
// Represent slice types as the value itself.
|
||||||
|
switch rv.Type().Elem().Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
if rv.IsNil() {
|
||||||
|
v = reflect.Zero(rv.Type().Elem()).Interface()
|
||||||
|
} else {
|
||||||
|
v = rv.Elem().Interface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// extensionAsStorageType converts an value in the API type as the storage type.
|
||||||
|
// See Extension.value.
|
||||||
|
func extensionAsStorageType(v interface{}) interface{} {
|
||||||
|
switch rv := reflect.ValueOf(v); rv.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
// Represent slice types as the value itself.
|
||||||
|
switch rv.Type().Elem().Kind() {
|
||||||
|
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
||||||
|
if rv.IsNil() {
|
||||||
|
v = reflect.Zero(rv.Type().Elem()).Interface()
|
||||||
|
} else {
|
||||||
|
v = rv.Elem().Interface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
// Represent slice types as a pointer to the value.
|
||||||
|
if rv.Type().Elem().Kind() != reflect.Uint8 {
|
||||||
|
rv2 := reflect.New(rv.Type())
|
||||||
|
rv2.Elem().Set(rv)
|
||||||
|
v = rv2.Interface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
38
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
38
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
@ -341,26 +341,6 @@ type Message interface {
|
|||||||
ProtoMessage()
|
ProtoMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stats records allocation details about the protocol buffer encoders
|
|
||||||
// and decoders. Useful for tuning the library itself.
|
|
||||||
type Stats struct {
|
|
||||||
Emalloc uint64 // mallocs in encode
|
|
||||||
Dmalloc uint64 // mallocs in decode
|
|
||||||
Encode uint64 // number of encodes
|
|
||||||
Decode uint64 // number of decodes
|
|
||||||
Chit uint64 // number of cache hits
|
|
||||||
Cmiss uint64 // number of cache misses
|
|
||||||
Size uint64 // number of sizes
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set to true to enable stats collection.
|
|
||||||
const collectStats = false
|
|
||||||
|
|
||||||
var stats Stats
|
|
||||||
|
|
||||||
// GetStats returns a copy of the global Stats structure.
|
|
||||||
func GetStats() Stats { return stats }
|
|
||||||
|
|
||||||
// A Buffer is a buffer manager for marshaling and unmarshaling
|
// A Buffer is a buffer manager for marshaling and unmarshaling
|
||||||
// protocol buffers. It may be reused between invocations to
|
// protocol buffers. It may be reused between invocations to
|
||||||
// reduce memory usage. It is not necessary to use a Buffer;
|
// reduce memory usage. It is not necessary to use a Buffer;
|
||||||
@ -960,13 +940,19 @@ func isProto3Zero(v reflect.Value) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
const (
|
||||||
// to assert that that code is compatible with this version of the proto package.
|
// ProtoPackageIsVersion3 is referenced from generated protocol buffer files
|
||||||
const ProtoPackageIsVersion2 = true
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
|
ProtoPackageIsVersion3 = true
|
||||||
|
|
||||||
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
||||||
// to assert that that code is compatible with this version of the proto package.
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
const ProtoPackageIsVersion1 = true
|
ProtoPackageIsVersion2 = true
|
||||||
|
|
||||||
|
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||||
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
|
ProtoPackageIsVersion1 = true
|
||||||
|
)
|
||||||
|
|
||||||
// InternalMessageInfo is a type used internally by generated .pb.go files.
|
// InternalMessageInfo is a type used internally by generated .pb.go files.
|
||||||
// This type is not intended to be used by non-generated code.
|
// This type is not intended to be used by non-generated code.
|
||||||
|
137
vendor/github.com/golang/protobuf/proto/message_set.go
generated
vendored
137
vendor/github.com/golang/protobuf/proto/message_set.go
generated
vendored
@ -36,13 +36,7 @@ package proto
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
||||||
@ -145,46 +139,9 @@ func skipVarint(buf []byte) []byte {
|
|||||||
return buf[i+1:]
|
return buf[i+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||||
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
|
||||||
func MarshalMessageSet(exts interface{}) ([]byte, error) {
|
|
||||||
return marshalMessageSet(exts, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
|
|
||||||
func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
|
|
||||||
switch exts := exts.(type) {
|
|
||||||
case *XXX_InternalExtensions:
|
|
||||||
var u marshalInfo
|
|
||||||
siz := u.sizeMessageSet(exts)
|
|
||||||
b := make([]byte, 0, siz)
|
|
||||||
return u.appendMessageSet(b, exts, deterministic)
|
|
||||||
|
|
||||||
case map[int32]Extension:
|
|
||||||
// This is an old-style extension map.
|
|
||||||
// Wrap it in a new-style XXX_InternalExtensions.
|
|
||||||
ie := XXX_InternalExtensions{
|
|
||||||
p: &struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
extensionMap map[int32]Extension
|
|
||||||
}{
|
|
||||||
extensionMap: exts,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var u marshalInfo
|
|
||||||
siz := u.sizeMessageSet(&ie)
|
|
||||||
b := make([]byte, 0, siz)
|
|
||||||
return u.appendMessageSet(b, &ie, deterministic)
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, errors.New("proto: not an extension map")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
|
||||||
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
func unmarshalMessageSet(buf []byte, exts interface{}) error {
|
||||||
var m map[int32]Extension
|
var m map[int32]Extension
|
||||||
switch exts := exts.(type) {
|
switch exts := exts.(type) {
|
||||||
case *XXX_InternalExtensions:
|
case *XXX_InternalExtensions:
|
||||||
@ -222,93 +179,3 @@ func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
|
||||||
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
|
||||||
func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
|
|
||||||
var m map[int32]Extension
|
|
||||||
switch exts := exts.(type) {
|
|
||||||
case *XXX_InternalExtensions:
|
|
||||||
var mu sync.Locker
|
|
||||||
m, mu = exts.extensionsRead()
|
|
||||||
if m != nil {
|
|
||||||
// Keep the extensions map locked until we're done marshaling to prevent
|
|
||||||
// races between marshaling and unmarshaling the lazily-{en,de}coded
|
|
||||||
// values.
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
}
|
|
||||||
case map[int32]Extension:
|
|
||||||
m = exts
|
|
||||||
default:
|
|
||||||
return nil, errors.New("proto: not an extension map")
|
|
||||||
}
|
|
||||||
var b bytes.Buffer
|
|
||||||
b.WriteByte('{')
|
|
||||||
|
|
||||||
// Process the map in key order for deterministic output.
|
|
||||||
ids := make([]int32, 0, len(m))
|
|
||||||
for id := range m {
|
|
||||||
ids = append(ids, id)
|
|
||||||
}
|
|
||||||
sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
|
|
||||||
|
|
||||||
for i, id := range ids {
|
|
||||||
ext := m[id]
|
|
||||||
msd, ok := messageSetMap[id]
|
|
||||||
if !ok {
|
|
||||||
// Unknown type; we can't render it, so skip it.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if i > 0 && b.Len() > 1 {
|
|
||||||
b.WriteByte(',')
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(&b, `"[%s]":`, msd.name)
|
|
||||||
|
|
||||||
x := ext.value
|
|
||||||
if x == nil {
|
|
||||||
x = reflect.New(msd.t.Elem()).Interface()
|
|
||||||
if err := Unmarshal(ext.enc, x.(Message)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d, err := json.Marshal(x)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
b.Write(d)
|
|
||||||
}
|
|
||||||
b.WriteByte('}')
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
|
||||||
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
|
||||||
func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
|
|
||||||
// Common-case fast path.
|
|
||||||
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is fairly tricky, and it's not clear that it is needed.
|
|
||||||
return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// A global registry of types that can be used in a MessageSet.
|
|
||||||
|
|
||||||
var messageSetMap = make(map[int32]messageSetDesc)
|
|
||||||
|
|
||||||
type messageSetDesc struct {
|
|
||||||
t reflect.Type // pointer to struct
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterMessageSetType is called from the generated code.
|
|
||||||
func RegisterMessageSetType(m Message, fieldNum int32, name string) {
|
|
||||||
messageSetMap[fieldNum] = messageSetDesc{
|
|
||||||
t: reflect.TypeOf(m),
|
|
||||||
name: name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
5
vendor/github.com/golang/protobuf/proto/pointer_reflect.go
generated
vendored
5
vendor/github.com/golang/protobuf/proto/pointer_reflect.go
generated
vendored
@ -79,10 +79,13 @@ func toPointer(i *Message) pointer {
|
|||||||
|
|
||||||
// toAddrPointer converts an interface to a pointer that points to
|
// toAddrPointer converts an interface to a pointer that points to
|
||||||
// the interface data.
|
// the interface data.
|
||||||
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
func toAddrPointer(i *interface{}, isptr, deref bool) pointer {
|
||||||
v := reflect.ValueOf(*i)
|
v := reflect.ValueOf(*i)
|
||||||
u := reflect.New(v.Type())
|
u := reflect.New(v.Type())
|
||||||
u.Elem().Set(v)
|
u.Elem().Set(v)
|
||||||
|
if deref {
|
||||||
|
u = u.Elem()
|
||||||
|
}
|
||||||
return pointer{v: u}
|
return pointer{v: u}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
generated
vendored
15
vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
generated
vendored
@ -85,16 +85,21 @@ func toPointer(i *Message) pointer {
|
|||||||
|
|
||||||
// toAddrPointer converts an interface to a pointer that points to
|
// toAddrPointer converts an interface to a pointer that points to
|
||||||
// the interface data.
|
// the interface data.
|
||||||
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) {
|
||||||
// Super-tricky - read or get the address of data word of interface value.
|
// Super-tricky - read or get the address of data word of interface value.
|
||||||
if isptr {
|
if isptr {
|
||||||
// The interface is of pointer type, thus it is a direct interface.
|
// The interface is of pointer type, thus it is a direct interface.
|
||||||
// The data word is the pointer data itself. We take its address.
|
// The data word is the pointer data itself. We take its address.
|
||||||
return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
|
p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
|
||||||
|
} else {
|
||||||
|
// The interface is not of pointer type. The data word is the pointer
|
||||||
|
// to the data.
|
||||||
|
p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
||||||
}
|
}
|
||||||
// The interface is not of pointer type. The data word is the pointer
|
if deref {
|
||||||
// to the data.
|
p.p = *(*unsafe.Pointer)(p.p)
|
||||||
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
}
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// valToPointer converts v to a pointer. v must be of pointer type.
|
// valToPointer converts v to a pointer. v must be of pointer type.
|
||||||
|
31
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
31
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
@ -334,9 +334,6 @@ func GetProperties(t reflect.Type) *StructProperties {
|
|||||||
sprop, ok := propertiesMap[t]
|
sprop, ok := propertiesMap[t]
|
||||||
propertiesMu.RUnlock()
|
propertiesMu.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
if collectStats {
|
|
||||||
stats.Chit++
|
|
||||||
}
|
|
||||||
return sprop
|
return sprop
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,17 +343,20 @@ func GetProperties(t reflect.Type) *StructProperties {
|
|||||||
return sprop
|
return sprop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
oneofFuncsIface interface {
|
||||||
|
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||||
|
}
|
||||||
|
oneofWrappersIface interface {
|
||||||
|
XXX_OneofWrappers() []interface{}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// getPropertiesLocked requires that propertiesMu is held.
|
// getPropertiesLocked requires that propertiesMu is held.
|
||||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
if prop, ok := propertiesMap[t]; ok {
|
if prop, ok := propertiesMap[t]; ok {
|
||||||
if collectStats {
|
|
||||||
stats.Chit++
|
|
||||||
}
|
|
||||||
return prop
|
return prop
|
||||||
}
|
}
|
||||||
if collectStats {
|
|
||||||
stats.Cmiss++
|
|
||||||
}
|
|
||||||
|
|
||||||
prop := new(StructProperties)
|
prop := new(StructProperties)
|
||||||
// in case of recursive protos, fill this in now.
|
// in case of recursive protos, fill this in now.
|
||||||
@ -391,13 +391,14 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
|
|||||||
// Re-order prop.order.
|
// Re-order prop.order.
|
||||||
sort.Sort(prop)
|
sort.Sort(prop)
|
||||||
|
|
||||||
type oneofMessage interface {
|
var oots []interface{}
|
||||||
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
||||||
|
case oneofFuncsIface:
|
||||||
|
_, _, _, oots = m.XXX_OneofFuncs()
|
||||||
|
case oneofWrappersIface:
|
||||||
|
oots = m.XXX_OneofWrappers()
|
||||||
}
|
}
|
||||||
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
|
if len(oots) > 0 {
|
||||||
var oots []interface{}
|
|
||||||
_, _, _, oots = om.XXX_OneofFuncs()
|
|
||||||
|
|
||||||
// Interpret oneof metadata.
|
// Interpret oneof metadata.
|
||||||
prop.OneofTypes = make(map[string]*OneofProperties)
|
prop.OneofTypes = make(map[string]*OneofProperties)
|
||||||
for _, oot := range oots {
|
for _, oot := range oots {
|
||||||
|
45
vendor/github.com/golang/protobuf/proto/table_marshal.go
generated
vendored
45
vendor/github.com/golang/protobuf/proto/table_marshal.go
generated
vendored
@ -87,6 +87,7 @@ type marshalElemInfo struct {
|
|||||||
sizer sizer
|
sizer sizer
|
||||||
marshaler marshaler
|
marshaler marshaler
|
||||||
isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
|
isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
|
||||||
|
deref bool // dereference the pointer before operating on it; implies isptr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -320,8 +321,11 @@ func (u *marshalInfo) computeMarshalInfo() {
|
|||||||
|
|
||||||
// get oneof implementers
|
// get oneof implementers
|
||||||
var oneofImplementers []interface{}
|
var oneofImplementers []interface{}
|
||||||
if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
|
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
||||||
|
case oneofFuncsIface:
|
||||||
_, _, _, oneofImplementers = m.XXX_OneofFuncs()
|
_, _, _, oneofImplementers = m.XXX_OneofFuncs()
|
||||||
|
case oneofWrappersIface:
|
||||||
|
oneofImplementers = m.XXX_OneofWrappers()
|
||||||
}
|
}
|
||||||
|
|
||||||
n := t.NumField()
|
n := t.NumField()
|
||||||
@ -407,13 +411,22 @@ func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
|
|||||||
panic("tag is not an integer")
|
panic("tag is not an integer")
|
||||||
}
|
}
|
||||||
wt := wiretype(tags[0])
|
wt := wiretype(tags[0])
|
||||||
|
if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
sizer, marshaler := typeMarshaler(t, tags, false, false)
|
sizer, marshaler := typeMarshaler(t, tags, false, false)
|
||||||
|
var deref bool
|
||||||
|
if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
|
||||||
|
t = reflect.PtrTo(t)
|
||||||
|
deref = true
|
||||||
|
}
|
||||||
e = &marshalElemInfo{
|
e = &marshalElemInfo{
|
||||||
wiretag: uint64(tag)<<3 | wt,
|
wiretag: uint64(tag)<<3 | wt,
|
||||||
tagsize: SizeVarint(uint64(tag) << 3),
|
tagsize: SizeVarint(uint64(tag) << 3),
|
||||||
sizer: sizer,
|
sizer: sizer,
|
||||||
marshaler: marshaler,
|
marshaler: marshaler,
|
||||||
isptr: t.Kind() == reflect.Ptr,
|
isptr: t.Kind() == reflect.Ptr,
|
||||||
|
deref: deref,
|
||||||
}
|
}
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
@ -448,7 +461,7 @@ func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
|
|||||||
|
|
||||||
func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
|
func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
|
||||||
fi.field = toField(f)
|
fi.field = toField(f)
|
||||||
fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
|
fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
|
||||||
fi.isPointer = true
|
fi.isPointer = true
|
||||||
fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
|
fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
|
||||||
fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
|
fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
|
||||||
@ -476,10 +489,6 @@ func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type oneofMessage interface {
|
|
||||||
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// wiretype returns the wire encoding of the type.
|
// wiretype returns the wire encoding of the type.
|
||||||
func wiretype(encoding string) uint64 {
|
func wiretype(encoding string) uint64 {
|
||||||
switch encoding {
|
switch encoding {
|
||||||
@ -2310,8 +2319,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
|
|||||||
for _, k := range m.MapKeys() {
|
for _, k := range m.MapKeys() {
|
||||||
ki := k.Interface()
|
ki := k.Interface()
|
||||||
vi := m.MapIndex(k).Interface()
|
vi := m.MapIndex(k).Interface()
|
||||||
kaddr := toAddrPointer(&ki, false) // pointer to key
|
kaddr := toAddrPointer(&ki, false, false) // pointer to key
|
||||||
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
|
vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
|
||||||
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
||||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||||
}
|
}
|
||||||
@ -2329,8 +2338,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
|
|||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
ki := k.Interface()
|
ki := k.Interface()
|
||||||
vi := m.MapIndex(k).Interface()
|
vi := m.MapIndex(k).Interface()
|
||||||
kaddr := toAddrPointer(&ki, false) // pointer to key
|
kaddr := toAddrPointer(&ki, false, false) // pointer to key
|
||||||
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
|
vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
|
||||||
b = appendVarint(b, tag)
|
b = appendVarint(b, tag)
|
||||||
siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
||||||
b = appendVarint(b, uint64(siz))
|
b = appendVarint(b, uint64(siz))
|
||||||
@ -2399,7 +2408,7 @@ func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
|
|||||||
// the last time this function was called.
|
// the last time this function was called.
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
n += ei.sizer(p, ei.tagsize)
|
n += ei.sizer(p, ei.tagsize)
|
||||||
}
|
}
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
@ -2434,7 +2443,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
@ -2465,7 +2474,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
@ -2510,7 +2519,7 @@ func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
n += ei.sizer(p, 1) // message, tag = 3 (size=1)
|
n += ei.sizer(p, 1) // message, tag = 3 (size=1)
|
||||||
}
|
}
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
@ -2553,7 +2562,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
@ -2591,7 +2600,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
||||||
b = append(b, 1<<3|WireEndGroup)
|
b = append(b, 1<<3|WireEndGroup)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
@ -2621,7 +2630,7 @@ func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
n += ei.sizer(p, ei.tagsize)
|
n += ei.sizer(p, ei.tagsize)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
@ -2656,7 +2665,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr)
|
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
||||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
|
74
vendor/github.com/golang/protobuf/proto/table_unmarshal.go
generated
vendored
74
vendor/github.com/golang/protobuf/proto/table_unmarshal.go
generated
vendored
@ -136,7 +136,7 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
|
|||||||
u.computeUnmarshalInfo()
|
u.computeUnmarshalInfo()
|
||||||
}
|
}
|
||||||
if u.isMessageSet {
|
if u.isMessageSet {
|
||||||
return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
|
return unmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
|
||||||
}
|
}
|
||||||
var reqMask uint64 // bitmask of required fields we've seen.
|
var reqMask uint64 // bitmask of required fields we've seen.
|
||||||
var errLater error
|
var errLater error
|
||||||
@ -362,46 +362,48 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find any types associated with oneof fields.
|
// Find any types associated with oneof fields.
|
||||||
// TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it?
|
var oneofImplementers []interface{}
|
||||||
fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs")
|
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
||||||
if fn.IsValid() {
|
case oneofFuncsIface:
|
||||||
res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{}
|
_, _, _, oneofImplementers = m.XXX_OneofFuncs()
|
||||||
for i := res.Len() - 1; i >= 0; i-- {
|
case oneofWrappersIface:
|
||||||
v := res.Index(i) // interface{}
|
oneofImplementers = m.XXX_OneofWrappers()
|
||||||
tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X
|
}
|
||||||
typ := tptr.Elem() // Msg_X
|
for _, v := range oneofImplementers {
|
||||||
|
tptr := reflect.TypeOf(v) // *Msg_X
|
||||||
|
typ := tptr.Elem() // Msg_X
|
||||||
|
|
||||||
f := typ.Field(0) // oneof implementers have one field
|
f := typ.Field(0) // oneof implementers have one field
|
||||||
baseUnmarshal := fieldUnmarshaler(&f)
|
baseUnmarshal := fieldUnmarshaler(&f)
|
||||||
tags := strings.Split(f.Tag.Get("protobuf"), ",")
|
tags := strings.Split(f.Tag.Get("protobuf"), ",")
|
||||||
fieldNum, err := strconv.Atoi(tags[1])
|
fieldNum, err := strconv.Atoi(tags[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("protobuf tag field not an integer: " + tags[1])
|
panic("protobuf tag field not an integer: " + tags[1])
|
||||||
}
|
}
|
||||||
var name string
|
var name string
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
if strings.HasPrefix(tag, "name=") {
|
if strings.HasPrefix(tag, "name=") {
|
||||||
name = strings.TrimPrefix(tag, "name=")
|
name = strings.TrimPrefix(tag, "name=")
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the oneof field that this struct implements.
|
|
||||||
// Might take O(n^2) to process all of the oneofs, but who cares.
|
|
||||||
for _, of := range oneofFields {
|
|
||||||
if tptr.Implements(of.ityp) {
|
|
||||||
// We have found the corresponding interface for this struct.
|
|
||||||
// That lets us know where this struct should be stored
|
|
||||||
// when we encounter it during unmarshaling.
|
|
||||||
unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
|
|
||||||
u.setTag(fieldNum, of.field, unmarshal, 0, name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the oneof field that this struct implements.
|
||||||
|
// Might take O(n^2) to process all of the oneofs, but who cares.
|
||||||
|
for _, of := range oneofFields {
|
||||||
|
if tptr.Implements(of.ityp) {
|
||||||
|
// We have found the corresponding interface for this struct.
|
||||||
|
// That lets us know where this struct should be stored
|
||||||
|
// when we encounter it during unmarshaling.
|
||||||
|
unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
|
||||||
|
u.setTag(fieldNum, of.field, unmarshal, 0, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get extension ranges, if any.
|
// Get extension ranges, if any.
|
||||||
fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
|
fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
|
||||||
if fn.IsValid() {
|
if fn.IsValid() {
|
||||||
if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
|
if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
|
||||||
panic("a message with extensions, but no extensions field in " + t.Name())
|
panic("a message with extensions, but no extensions field in " + t.Name())
|
||||||
@ -1948,7 +1950,7 @@ func encodeVarint(b []byte, x uint64) []byte {
|
|||||||
// If there is an error, it returns 0,0.
|
// If there is an error, it returns 0,0.
|
||||||
func decodeVarint(b []byte) (uint64, int) {
|
func decodeVarint(b []byte) (uint64, int) {
|
||||||
var x, y uint64
|
var x, y uint64
|
||||||
if len(b) <= 0 {
|
if len(b) == 0 {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
x = uint64(b[0])
|
x = uint64(b[0])
|
||||||
|
601
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
generated
vendored
601
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
11
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
generated
vendored
11
vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto
generated
vendored
@ -417,6 +417,17 @@ message FileOptions {
|
|||||||
// determining the namespace.
|
// determining the namespace.
|
||||||
optional string php_namespace = 41;
|
optional string php_namespace = 41;
|
||||||
|
|
||||||
|
|
||||||
|
// Use this option to change the namespace of php generated metadata classes.
|
||||||
|
// Default is empty. When this option is empty, the proto file name will be used
|
||||||
|
// for determining the namespace.
|
||||||
|
optional string php_metadata_namespace = 44;
|
||||||
|
|
||||||
|
// Use this option to change the package of ruby generated classes. Default
|
||||||
|
// is empty. When this option is not set, the package name will be used for
|
||||||
|
// determining the ruby package.
|
||||||
|
optional string ruby_package = 45;
|
||||||
|
|
||||||
// The parser stores options it doesn't recognize here.
|
// The parser stores options it doesn't recognize here.
|
||||||
// See the documentation for the "Options" section above.
|
// See the documentation for the "Options" section above.
|
||||||
repeated UninterpretedOption uninterpreted_option = 999;
|
repeated UninterpretedOption uninterpreted_option = 999;
|
||||||
|
389
vendor/github.com/matterbridge/go-whatsapp/conn.go
generated
vendored
389
vendor/github.com/matterbridge/go-whatsapp/conn.go
generated
vendored
@ -1,389 +0,0 @@
|
|||||||
//Package whatsapp provides a developer API to interact with the WhatsAppWeb-Servers.
|
|
||||||
package whatsapp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"github.com/matterbridge/go-whatsapp/binary"
|
|
||||||
"github.com/matterbridge/go-whatsapp/crypto/cbc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type metric byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
debugLog metric = iota + 1
|
|
||||||
queryResume
|
|
||||||
queryReceipt
|
|
||||||
queryMedia
|
|
||||||
queryChat
|
|
||||||
queryContacts
|
|
||||||
queryMessages
|
|
||||||
presence
|
|
||||||
presenceSubscribe
|
|
||||||
group
|
|
||||||
read
|
|
||||||
chat
|
|
||||||
received
|
|
||||||
pic
|
|
||||||
status
|
|
||||||
message
|
|
||||||
queryActions
|
|
||||||
block
|
|
||||||
queryGroup
|
|
||||||
queryPreview
|
|
||||||
queryEmoji
|
|
||||||
queryMessageInfo
|
|
||||||
spam
|
|
||||||
querySearch
|
|
||||||
queryIdentity
|
|
||||||
queryUrl
|
|
||||||
profile
|
|
||||||
contact
|
|
||||||
queryVcard
|
|
||||||
queryStatus
|
|
||||||
queryStatusUpdate
|
|
||||||
privacyStatus
|
|
||||||
queryLiveLocations
|
|
||||||
liveLocation
|
|
||||||
queryVname
|
|
||||||
queryLabels
|
|
||||||
call
|
|
||||||
queryCall
|
|
||||||
queryQuickReplies
|
|
||||||
)
|
|
||||||
|
|
||||||
type flag byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
ignore flag = 1 << (7 - iota)
|
|
||||||
ackRequest
|
|
||||||
available
|
|
||||||
notAvailable
|
|
||||||
expires
|
|
||||||
skipOffline
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Conn is created by NewConn. Interacting with the initialized Conn is the main way of interacting with our package.
|
|
||||||
It holds all necessary information to make the package work internally.
|
|
||||||
*/
|
|
||||||
type Conn struct {
|
|
||||||
wsConn *websocket.Conn
|
|
||||||
wsConnOK bool
|
|
||||||
wsConnMutex sync.RWMutex
|
|
||||||
session *Session
|
|
||||||
listener map[string]chan string
|
|
||||||
listenerMutex sync.RWMutex
|
|
||||||
writeChan chan wsMsg
|
|
||||||
handler []Handler
|
|
||||||
msgCount int
|
|
||||||
msgTimeout time.Duration
|
|
||||||
Info *Info
|
|
||||||
Store *Store
|
|
||||||
ServerLastSeen time.Time
|
|
||||||
|
|
||||||
longClientName string
|
|
||||||
shortClientName string
|
|
||||||
}
|
|
||||||
|
|
||||||
type wsMsg struct {
|
|
||||||
messageType int
|
|
||||||
data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates a new connection with a given timeout. The websocket connection to the WhatsAppWeb servers get´s established.
|
|
||||||
The goroutine for handling incoming messages is started
|
|
||||||
*/
|
|
||||||
func NewConn(timeout time.Duration) (*Conn, error) {
|
|
||||||
wac := &Conn{
|
|
||||||
wsConn: nil, // will be set in connect()
|
|
||||||
wsConnMutex: sync.RWMutex{},
|
|
||||||
listener: make(map[string]chan string),
|
|
||||||
listenerMutex: sync.RWMutex{},
|
|
||||||
writeChan: make(chan wsMsg),
|
|
||||||
handler: make([]Handler, 0),
|
|
||||||
msgCount: 0,
|
|
||||||
msgTimeout: timeout,
|
|
||||||
Store: newStore(),
|
|
||||||
|
|
||||||
longClientName: "github.com/rhymen/go-whatsapp",
|
|
||||||
shortClientName: "go-whatsapp",
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := wac.connect(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go wac.readPump()
|
|
||||||
go wac.writePump()
|
|
||||||
go wac.keepAlive(20000, 60000)
|
|
||||||
|
|
||||||
return wac, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) isConnected() bool {
|
|
||||||
wac.wsConnMutex.RLock()
|
|
||||||
defer wac.wsConnMutex.RUnlock()
|
|
||||||
if wac.wsConn == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if wac.wsConnOK {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// just send a keepalive to test the connection
|
|
||||||
wac.sendKeepAlive()
|
|
||||||
|
|
||||||
// this method is expected to be called by loops. So we can just return false
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect should be guarded with wsConnMutex
|
|
||||||
func (wac *Conn) connect() error {
|
|
||||||
dialer := &websocket.Dialer{
|
|
||||||
ReadBufferSize: 25 * 1024 * 1024,
|
|
||||||
WriteBufferSize: 10 * 1024 * 1024,
|
|
||||||
HandshakeTimeout: wac.msgTimeout,
|
|
||||||
}
|
|
||||||
|
|
||||||
headers := http.Header{"Origin": []string{"https://web.whatsapp.com"}}
|
|
||||||
wsConn, _, err := dialer.Dial("wss://web.whatsapp.com/ws", headers)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("couldn't dial whatsapp web websocket: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wsConn.SetCloseHandler(func(code int, text string) error {
|
|
||||||
fmt.Fprintf(os.Stderr, "websocket connection closed(%d, %s)\n", code, text)
|
|
||||||
|
|
||||||
// from default CloseHandler
|
|
||||||
message := websocket.FormatCloseMessage(code, "")
|
|
||||||
wsConn.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second))
|
|
||||||
|
|
||||||
// our close handling
|
|
||||||
if websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
|
|
||||||
fmt.Println("Trigger reconnect")
|
|
||||||
go wac.reconnect()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
wac.wsConn = wsConn
|
|
||||||
wac.wsConnOK = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// reconnect should be run as go routine
|
|
||||||
func (wac *Conn) reconnect() {
|
|
||||||
wac.wsConnMutex.Lock()
|
|
||||||
wac.wsConn.Close()
|
|
||||||
wac.wsConn = nil
|
|
||||||
wac.wsConnOK = false
|
|
||||||
wac.wsConnMutex.Unlock()
|
|
||||||
|
|
||||||
// wait up to 60 seconds and then reconnect. As writePump should send immediately, it might
|
|
||||||
// reconnect as well. So we check its existance before reconnecting
|
|
||||||
for !wac.isConnected() {
|
|
||||||
time.Sleep(time.Duration(rand.Intn(60)) * time.Second)
|
|
||||||
|
|
||||||
wac.wsConnMutex.Lock()
|
|
||||||
if wac.wsConn == nil {
|
|
||||||
if err := wac.connect(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "could not reconnect to websocket: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wac.wsConnMutex.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) write(data []interface{}) (<-chan string, error) {
|
|
||||||
d, err := json.Marshal(data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ts := time.Now().Unix()
|
|
||||||
messageTag := fmt.Sprintf("%d.--%d", ts, wac.msgCount)
|
|
||||||
msg := fmt.Sprintf("%s,%s", messageTag, d)
|
|
||||||
|
|
||||||
ch := make(chan string, 1)
|
|
||||||
|
|
||||||
wac.listenerMutex.Lock()
|
|
||||||
wac.listener[messageTag] = ch
|
|
||||||
wac.listenerMutex.Unlock()
|
|
||||||
|
|
||||||
wac.writeChan <- wsMsg{websocket.TextMessage, []byte(msg)}
|
|
||||||
|
|
||||||
wac.msgCount++
|
|
||||||
return ch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) writeBinary(node binary.Node, metric metric, flag flag, tag string) (<-chan string, error) {
|
|
||||||
if len(tag) < 2 {
|
|
||||||
return nil, fmt.Errorf("no tag specified or to short")
|
|
||||||
}
|
|
||||||
b, err := binary.Marshal(node)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cipher, err := cbc.Encrypt(wac.session.EncKey, nil, b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
h := hmac.New(sha256.New, wac.session.MacKey)
|
|
||||||
h.Write(cipher)
|
|
||||||
hash := h.Sum(nil)
|
|
||||||
|
|
||||||
data := []byte(tag + ",")
|
|
||||||
data = append(data, byte(metric), byte(flag))
|
|
||||||
data = append(data, hash[:32]...)
|
|
||||||
data = append(data, cipher...)
|
|
||||||
|
|
||||||
ch := make(chan string, 1)
|
|
||||||
|
|
||||||
wac.listenerMutex.Lock()
|
|
||||||
wac.listener[tag] = ch
|
|
||||||
wac.listenerMutex.Unlock()
|
|
||||||
|
|
||||||
msg := wsMsg{websocket.BinaryMessage, data}
|
|
||||||
wac.writeChan <- msg
|
|
||||||
|
|
||||||
wac.msgCount++
|
|
||||||
return ch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) readPump() {
|
|
||||||
defer wac.wsConn.Close()
|
|
||||||
|
|
||||||
for {
|
|
||||||
msgType, msg, err := wac.wsConn.ReadMessage()
|
|
||||||
if err != nil {
|
|
||||||
wac.wsConnOK = false
|
|
||||||
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
|
|
||||||
wac.handle(fmt.Errorf("unexpected websocket close: %v", err))
|
|
||||||
}
|
|
||||||
// sleep for a second and retry reading the next message
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
wac.wsConnOK = true
|
|
||||||
|
|
||||||
data := strings.SplitN(string(msg), ",", 2)
|
|
||||||
|
|
||||||
//Kepp-Alive Timestmap
|
|
||||||
if data[0][0] == '!' {
|
|
||||||
msecs, err := strconv.ParseInt(data[0][1:], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Error converting time string to uint: %v\n", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
wac.ServerLastSeen = time.Unix(msecs/1000, (msecs%1000)*int64(time.Millisecond))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
wac.listenerMutex.RLock()
|
|
||||||
listener, hasListener := wac.listener[data[0]]
|
|
||||||
wac.listenerMutex.RUnlock()
|
|
||||||
|
|
||||||
if len(data[1]) == 0 {
|
|
||||||
continue
|
|
||||||
} else if hasListener {
|
|
||||||
listener <- data[1]
|
|
||||||
|
|
||||||
wac.listenerMutex.Lock()
|
|
||||||
delete(wac.listener, data[0])
|
|
||||||
wac.listenerMutex.Unlock()
|
|
||||||
} else if msgType == 2 && wac.session != nil && wac.session.EncKey != nil {
|
|
||||||
message, err := wac.decryptBinaryMessage([]byte(data[1]))
|
|
||||||
if err != nil {
|
|
||||||
wac.handle(fmt.Errorf("error decoding binary: %v", err))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
wac.dispatch(message)
|
|
||||||
} else {
|
|
||||||
wac.handle(string(data[1]))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) writePump() {
|
|
||||||
for msg := range wac.writeChan {
|
|
||||||
for !wac.isConnected() {
|
|
||||||
// reconnect to send the message ASAP
|
|
||||||
wac.wsConnMutex.Lock()
|
|
||||||
if wac.wsConn == nil {
|
|
||||||
if err := wac.connect(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "could not reconnect to websocket: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wac.wsConnMutex.Unlock()
|
|
||||||
if !wac.isConnected() {
|
|
||||||
// reconnecting failed. Sleep for a while and try again afterwards
|
|
||||||
time.Sleep(time.Duration(rand.Intn(5)) * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := wac.wsConn.WriteMessage(msg.messageType, msg.data); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "error writing to socket: %v\n", err)
|
|
||||||
wac.wsConnOK = false
|
|
||||||
// add message to channel again to no loose it
|
|
||||||
go func() {
|
|
||||||
wac.writeChan <- msg
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) sendKeepAlive() {
|
|
||||||
// whatever issues might be there allow sending this message
|
|
||||||
wac.wsConnOK = true
|
|
||||||
wac.writeChan <- wsMsg{
|
|
||||||
messageType: websocket.TextMessage,
|
|
||||||
data: []byte("?,,"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) keepAlive(minIntervalMs int, maxIntervalMs int) {
|
|
||||||
for {
|
|
||||||
wac.sendKeepAlive()
|
|
||||||
interval := rand.Intn(maxIntervalMs-minIntervalMs) + minIntervalMs
|
|
||||||
<-time.After(time.Duration(interval) * time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wac *Conn) decryptBinaryMessage(msg []byte) (*binary.Node, error) {
|
|
||||||
//message validation
|
|
||||||
h2 := hmac.New(sha256.New, wac.session.MacKey)
|
|
||||||
h2.Write([]byte(msg[32:]))
|
|
||||||
if !hmac.Equal(h2.Sum(nil), msg[:32]) {
|
|
||||||
return nil, fmt.Errorf("message received with invalid hmac")
|
|
||||||
}
|
|
||||||
|
|
||||||
// message decrypt
|
|
||||||
d, err := cbc.Decrypt(wac.session.EncKey, nil, msg[32:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error decrypting message with AES: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// message unmarshal
|
|
||||||
message, err := binary.Unmarshal(d)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error decoding binary: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return message, nil
|
|
||||||
}
|
|
8
vendor/github.com/matterbridge/go-whatsapp/go.mod
generated
vendored
8
vendor/github.com/matterbridge/go-whatsapp/go.mod
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
module github.com/matterbridge/go-whatsapp
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/golang/protobuf v1.2.0
|
|
||||||
github.com/gorilla/websocket v1.4.0
|
|
||||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
|
||||||
)
|
|
7
vendor/github.com/matterbridge/go-whatsapp/go.sum
generated
vendored
7
vendor/github.com/matterbridge/go-whatsapp/go.sum
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
|
||||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613 h1:MQ/ZZiDsUapFFiMS+vzwXkCTeEKaum+Do5rINYJDmxc=
|
|
||||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
12
vendor/github.com/pkg/errors/.travis.yml
generated
vendored
12
vendor/github.com/pkg/errors/.travis.yml
generated
vendored
@ -1,10 +1,14 @@
|
|||||||
language: go
|
language: go
|
||||||
go_import_path: github.com/pkg/errors
|
go_import_path: github.com/pkg/errors
|
||||||
go:
|
go:
|
||||||
- 1.4.3
|
- 1.4.x
|
||||||
- 1.5.4
|
- 1.5.x
|
||||||
- 1.6.2
|
- 1.6.x
|
||||||
- 1.7.1
|
- 1.7.x
|
||||||
|
- 1.8.x
|
||||||
|
- 1.9.x
|
||||||
|
- 1.10.x
|
||||||
|
- 1.11.x
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
4
vendor/github.com/pkg/errors/README.md
generated
vendored
4
vendor/github.com/pkg/errors/README.md
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors)
|
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge)
|
||||||
|
|
||||||
Package errors provides simple error handling primitives.
|
Package errors provides simple error handling primitives.
|
||||||
|
|
||||||
@ -47,6 +47,6 @@ We welcome pull requests, bug fixes and issue reports. With that said, the bar f
|
|||||||
|
|
||||||
Before proposing a change, please discuss your change by raising an issue.
|
Before proposing a change, please discuss your change by raising an issue.
|
||||||
|
|
||||||
## Licence
|
## License
|
||||||
|
|
||||||
BSD-2-Clause
|
BSD-2-Clause
|
||||||
|
43
vendor/github.com/pkg/errors/errors.go
generated
vendored
43
vendor/github.com/pkg/errors/errors.go
generated
vendored
@ -6,7 +6,7 @@
|
|||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// which applied recursively up the call stack results in error reports
|
// which when applied recursively up the call stack results in error reports
|
||||||
// without context or debugging information. The errors package allows
|
// without context or debugging information. The errors package allows
|
||||||
// programmers to add context to the failure path in their code in a way
|
// programmers to add context to the failure path in their code in a way
|
||||||
// that does not destroy the original value of the error.
|
// that does not destroy the original value of the error.
|
||||||
@ -15,16 +15,17 @@
|
|||||||
//
|
//
|
||||||
// The errors.Wrap function returns a new error that adds context to the
|
// The errors.Wrap function returns a new error that adds context to the
|
||||||
// original error by recording a stack trace at the point Wrap is called,
|
// original error by recording a stack trace at the point Wrap is called,
|
||||||
// and the supplied message. For example
|
// together with the supplied message. For example
|
||||||
//
|
//
|
||||||
// _, err := ioutil.ReadAll(r)
|
// _, err := ioutil.ReadAll(r)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return errors.Wrap(err, "read failed")
|
// return errors.Wrap(err, "read failed")
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// If additional control is required the errors.WithStack and errors.WithMessage
|
// If additional control is required, the errors.WithStack and
|
||||||
// functions destructure errors.Wrap into its component operations of annotating
|
// errors.WithMessage functions destructure errors.Wrap into its component
|
||||||
// an error with a stack trace and an a message, respectively.
|
// operations: annotating an error with a stack trace and with a message,
|
||||||
|
// respectively.
|
||||||
//
|
//
|
||||||
// Retrieving the cause of an error
|
// Retrieving the cause of an error
|
||||||
//
|
//
|
||||||
@ -38,7 +39,7 @@
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
|
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
|
||||||
// the topmost error which does not implement causer, which is assumed to be
|
// the topmost error that does not implement causer, which is assumed to be
|
||||||
// the original cause. For example:
|
// the original cause. For example:
|
||||||
//
|
//
|
||||||
// switch err := errors.Cause(err).(type) {
|
// switch err := errors.Cause(err).(type) {
|
||||||
@ -48,16 +49,16 @@
|
|||||||
// // unknown error
|
// // unknown error
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// causer interface is not exported by this package, but is considered a part
|
// Although the causer interface is not exported by this package, it is
|
||||||
// of stable public API.
|
// considered a part of its stable public interface.
|
||||||
//
|
//
|
||||||
// Formatted printing of errors
|
// Formatted printing of errors
|
||||||
//
|
//
|
||||||
// All error values returned from this package implement fmt.Formatter and can
|
// All error values returned from this package implement fmt.Formatter and can
|
||||||
// be formatted by the fmt package. The following verbs are supported
|
// be formatted by the fmt package. The following verbs are supported:
|
||||||
//
|
//
|
||||||
// %s print the error. If the error has a Cause it will be
|
// %s print the error. If the error has a Cause it will be
|
||||||
// printed recursively
|
// printed recursively.
|
||||||
// %v see %s
|
// %v see %s
|
||||||
// %+v extended format. Each Frame of the error's StackTrace will
|
// %+v extended format. Each Frame of the error's StackTrace will
|
||||||
// be printed in detail.
|
// be printed in detail.
|
||||||
@ -65,13 +66,13 @@
|
|||||||
// Retrieving the stack trace of an error or wrapper
|
// Retrieving the stack trace of an error or wrapper
|
||||||
//
|
//
|
||||||
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
|
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
|
||||||
// invoked. This information can be retrieved with the following interface.
|
// invoked. This information can be retrieved with the following interface:
|
||||||
//
|
//
|
||||||
// type stackTracer interface {
|
// type stackTracer interface {
|
||||||
// StackTrace() errors.StackTrace
|
// StackTrace() errors.StackTrace
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Where errors.StackTrace is defined as
|
// The returned errors.StackTrace type is defined as
|
||||||
//
|
//
|
||||||
// type StackTrace []Frame
|
// type StackTrace []Frame
|
||||||
//
|
//
|
||||||
@ -85,8 +86,8 @@
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// stackTracer interface is not exported by this package, but is considered a part
|
// Although the stackTracer interface is not exported by this package, it is
|
||||||
// of stable public API.
|
// considered a part of its stable public interface.
|
||||||
//
|
//
|
||||||
// See the documentation for Frame.Format for more details.
|
// See the documentation for Frame.Format for more details.
|
||||||
package errors
|
package errors
|
||||||
@ -192,7 +193,7 @@ func Wrap(err error, message string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wrapf returns an error annotating err with a stack trace
|
// Wrapf returns an error annotating err with a stack trace
|
||||||
// at the point Wrapf is call, and the format specifier.
|
// at the point Wrapf is called, and the format specifier.
|
||||||
// If err is nil, Wrapf returns nil.
|
// If err is nil, Wrapf returns nil.
|
||||||
func Wrapf(err error, format string, args ...interface{}) error {
|
func Wrapf(err error, format string, args ...interface{}) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -220,6 +221,18 @@ func WithMessage(err error, message string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMessagef annotates err with the format specifier.
|
||||||
|
// If err is nil, WithMessagef returns nil.
|
||||||
|
func WithMessagef(err error, format string, args ...interface{}) error {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &withMessage{
|
||||||
|
cause: err,
|
||||||
|
msg: fmt.Sprintf(format, args...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type withMessage struct {
|
type withMessage struct {
|
||||||
cause error
|
cause error
|
||||||
msg string
|
msg string
|
||||||
|
51
vendor/github.com/pkg/errors/stack.go
generated
vendored
51
vendor/github.com/pkg/errors/stack.go
generated
vendored
@ -46,7 +46,8 @@ func (f Frame) line() int {
|
|||||||
//
|
//
|
||||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||||
//
|
//
|
||||||
// %+s path of source file relative to the compile time GOPATH
|
// %+s function name and path of source file relative to the compile time
|
||||||
|
// GOPATH separated by \n\t (<funcname>\n\t<path>)
|
||||||
// %+v equivalent to %+s:%d
|
// %+v equivalent to %+s:%d
|
||||||
func (f Frame) Format(s fmt.State, verb rune) {
|
func (f Frame) Format(s fmt.State, verb rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
@ -79,6 +80,14 @@ func (f Frame) Format(s fmt.State, verb rune) {
|
|||||||
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
|
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
|
||||||
type StackTrace []Frame
|
type StackTrace []Frame
|
||||||
|
|
||||||
|
// Format formats the stack of Frames according to the fmt.Formatter interface.
|
||||||
|
//
|
||||||
|
// %s lists source files for each Frame in the stack
|
||||||
|
// %v lists the source file and line number for each Frame in the stack
|
||||||
|
//
|
||||||
|
// Format accepts flags that alter the printing of some verbs, as follows:
|
||||||
|
//
|
||||||
|
// %+v Prints filename, function, and line number for each Frame in the stack.
|
||||||
func (st StackTrace) Format(s fmt.State, verb rune) {
|
func (st StackTrace) Format(s fmt.State, verb rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -136,43 +145,3 @@ func funcname(name string) string {
|
|||||||
i = strings.Index(name, ".")
|
i = strings.Index(name, ".")
|
||||||
return name[i+1:]
|
return name[i+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimGOPATH(name, file string) string {
|
|
||||||
// Here we want to get the source file path relative to the compile time
|
|
||||||
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
|
|
||||||
// GOPATH at runtime, but we can infer the number of path segments in the
|
|
||||||
// GOPATH. We note that fn.Name() returns the function name qualified by
|
|
||||||
// the import path, which does not include the GOPATH. Thus we can trim
|
|
||||||
// segments from the beginning of the file path until the number of path
|
|
||||||
// separators remaining is one more than the number of path separators in
|
|
||||||
// the function name. For example, given:
|
|
||||||
//
|
|
||||||
// GOPATH /home/user
|
|
||||||
// file /home/user/src/pkg/sub/file.go
|
|
||||||
// fn.Name() pkg/sub.Type.Method
|
|
||||||
//
|
|
||||||
// We want to produce:
|
|
||||||
//
|
|
||||||
// pkg/sub/file.go
|
|
||||||
//
|
|
||||||
// From this we can easily see that fn.Name() has one less path separator
|
|
||||||
// than our desired output. We count separators from the end of the file
|
|
||||||
// path until it finds two more than in the function name and then move
|
|
||||||
// one character forward to preserve the initial path segment without a
|
|
||||||
// leading separator.
|
|
||||||
const sep = "/"
|
|
||||||
goal := strings.Count(name, sep) + 2
|
|
||||||
i := len(file)
|
|
||||||
for n := 0; n < goal; n++ {
|
|
||||||
i = strings.LastIndex(file[:i], sep)
|
|
||||||
if i == -1 {
|
|
||||||
// not enough separators found, set i so that the slice expression
|
|
||||||
// below leaves file unmodified
|
|
||||||
i = -len(sep)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get back to 0 or trim the leading separator
|
|
||||||
file = file[i+len(sep):]
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
11
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go
generated
vendored
11
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go
generated
vendored
@ -6,15 +6,14 @@
|
|||||||
|
|
||||||
package chacha20
|
package chacha20
|
||||||
|
|
||||||
var haveAsm = hasVectorFacility()
|
import (
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
var haveAsm = cpu.S390X.HasVX
|
||||||
|
|
||||||
const bufSize = 256
|
const bufSize = 256
|
||||||
|
|
||||||
// hasVectorFacility reports whether the machine supports the vector
|
|
||||||
// facility (vx).
|
|
||||||
// Implementation in asm_s390x.s.
|
|
||||||
func hasVectorFacility() bool
|
|
||||||
|
|
||||||
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
||||||
// be called when the vector facility is available.
|
// be called when the vector facility is available.
|
||||||
// Implementation in asm_s390x.s.
|
// Implementation in asm_s390x.s.
|
||||||
|
23
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.s
generated
vendored
23
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.s
generated
vendored
@ -258,26 +258,3 @@ tail:
|
|||||||
MOVD R8, R3
|
MOVD R8, R3
|
||||||
MOVD $0, R4
|
MOVD $0, R4
|
||||||
JMP continue
|
JMP continue
|
||||||
|
|
||||||
// func hasVectorFacility() bool
|
|
||||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
|
||||||
MOVD $x-24(SP), R1
|
|
||||||
XC $24, 0(R1), 0(R1) // clear the storage
|
|
||||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
|
||||||
WORD $0xB2B01000 // STFLE 0(R1)
|
|
||||||
XOR R0, R0 // reset the value of R0
|
|
||||||
MOVBZ z-8(SP), R1
|
|
||||||
AND $0x40, R1
|
|
||||||
BEQ novector
|
|
||||||
|
|
||||||
vectorinstalled:
|
|
||||||
// check if the vector instruction has been enabled
|
|
||||||
VLEIB $0, $0xF, V16
|
|
||||||
VLGVB $0, V16, R1
|
|
||||||
CMPBNE R1, $0xF, novector
|
|
||||||
MOVB $1, ret+0(FP) // have vx
|
|
||||||
RET
|
|
||||||
|
|
||||||
novector:
|
|
||||||
MOVB $0, ret+0(FP) // no vx
|
|
||||||
RET
|
|
||||||
|
11
vendor/golang.org/x/crypto/poly1305/mac_noasm.go
generated
vendored
Normal file
11
vendor/golang.org/x/crypto/poly1305/mac_noasm.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build !amd64 gccgo appengine
|
||||||
|
|
||||||
|
package poly1305
|
||||||
|
|
||||||
|
type mac struct{ macGeneric }
|
||||||
|
|
||||||
|
func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} }
|
80
vendor/golang.org/x/crypto/poly1305/poly1305.go
generated
vendored
80
vendor/golang.org/x/crypto/poly1305/poly1305.go
generated
vendored
@ -2,21 +2,19 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
// Package poly1305 implements Poly1305 one-time message authentication code as
|
||||||
Package poly1305 implements Poly1305 one-time message authentication code as
|
// specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
|
||||||
specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
|
//
|
||||||
|
// Poly1305 is a fast, one-time authentication function. It is infeasible for an
|
||||||
Poly1305 is a fast, one-time authentication function. It is infeasible for an
|
// attacker to generate an authenticator for a message without the key. However, a
|
||||||
attacker to generate an authenticator for a message without the key. However, a
|
// key must only be used for a single message. Authenticating two different
|
||||||
key must only be used for a single message. Authenticating two different
|
// messages with the same key allows an attacker to forge authenticators for other
|
||||||
messages with the same key allows an attacker to forge authenticators for other
|
// messages with the same key.
|
||||||
messages with the same key.
|
//
|
||||||
|
// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
|
||||||
Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
|
// used with a fixed key in order to generate one-time keys from an nonce.
|
||||||
used with a fixed key in order to generate one-time keys from an nonce.
|
// However, in this package AES isn't used and the one-time key is specified
|
||||||
However, in this package AES isn't used and the one-time key is specified
|
// directly.
|
||||||
directly.
|
|
||||||
*/
|
|
||||||
package poly1305 // import "golang.org/x/crypto/poly1305"
|
package poly1305 // import "golang.org/x/crypto/poly1305"
|
||||||
|
|
||||||
import "crypto/subtle"
|
import "crypto/subtle"
|
||||||
@ -31,3 +29,55 @@ func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
|
|||||||
Sum(&tmp, m, key)
|
Sum(&tmp, m, key)
|
||||||
return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
|
return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New returns a new MAC computing an authentication
|
||||||
|
// tag of all data written to it with the given key.
|
||||||
|
// This allows writing the message progressively instead
|
||||||
|
// of passing it as a single slice. Common users should use
|
||||||
|
// the Sum function instead.
|
||||||
|
//
|
||||||
|
// The key must be unique for each message, as authenticating
|
||||||
|
// two different messages with the same key allows an attacker
|
||||||
|
// to forge messages at will.
|
||||||
|
func New(key *[32]byte) *MAC {
|
||||||
|
return &MAC{
|
||||||
|
mac: newMAC(key),
|
||||||
|
finalized: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MAC is an io.Writer computing an authentication tag
|
||||||
|
// of the data written to it.
|
||||||
|
//
|
||||||
|
// MAC cannot be used like common hash.Hash implementations,
|
||||||
|
// because using a poly1305 key twice breaks its security.
|
||||||
|
// Therefore writing data to a running MAC after calling
|
||||||
|
// Sum causes it to panic.
|
||||||
|
type MAC struct {
|
||||||
|
mac // platform-dependent implementation
|
||||||
|
|
||||||
|
finalized bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns the number of bytes Sum will return.
|
||||||
|
func (h *MAC) Size() int { return TagSize }
|
||||||
|
|
||||||
|
// Write adds more data to the running message authentication code.
|
||||||
|
// It never returns an error.
|
||||||
|
//
|
||||||
|
// It must not be called after the first call of Sum.
|
||||||
|
func (h *MAC) Write(p []byte) (n int, err error) {
|
||||||
|
if h.finalized {
|
||||||
|
panic("poly1305: write to MAC after Sum")
|
||||||
|
}
|
||||||
|
return h.mac.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum computes the authenticator of all data written to the
|
||||||
|
// message authentication code.
|
||||||
|
func (h *MAC) Sum(b []byte) []byte {
|
||||||
|
var mac [TagSize]byte
|
||||||
|
h.mac.Sum(&mac)
|
||||||
|
h.finalized = true
|
||||||
|
return append(b, mac[:]...)
|
||||||
|
}
|
||||||
|
60
vendor/golang.org/x/crypto/poly1305/sum_amd64.go
generated
vendored
60
vendor/golang.org/x/crypto/poly1305/sum_amd64.go
generated
vendored
@ -6,17 +6,63 @@
|
|||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
// This function is implemented in sum_amd64.s
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
func initialize(state *[7]uint64, key *[32]byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func update(state *[7]uint64, msg []byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func finalize(tag *[TagSize]byte, state *[7]uint64)
|
||||||
|
|
||||||
// Sum generates an authenticator for m using a one-time key and puts the
|
// Sum generates an authenticator for m using a one-time key and puts the
|
||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
// key allows an attacker to forge messages at will.
|
// key allows an attacker to forge messages at will.
|
||||||
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
var mPtr *byte
|
h := newMAC(key)
|
||||||
if len(m) > 0 {
|
h.Write(m)
|
||||||
mPtr = &m[0]
|
h.Sum(out)
|
||||||
}
|
}
|
||||||
poly1305(out, mPtr, uint64(len(m)), key)
|
|
||||||
|
func newMAC(key *[32]byte) (h mac) {
|
||||||
|
initialize(&h.state, key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type mac struct {
|
||||||
|
state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 }
|
||||||
|
|
||||||
|
buffer [TagSize]byte
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *mac) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
|
if h.offset > 0 {
|
||||||
|
remaining := TagSize - h.offset
|
||||||
|
if n < remaining {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
copy(h.buffer[h.offset:], p[:remaining])
|
||||||
|
p = p[remaining:]
|
||||||
|
h.offset = 0
|
||||||
|
update(&h.state, h.buffer[:])
|
||||||
|
}
|
||||||
|
if nn := len(p) - (len(p) % TagSize); nn > 0 {
|
||||||
|
update(&h.state, p[:nn])
|
||||||
|
p = p[nn:]
|
||||||
|
}
|
||||||
|
if len(p) > 0 {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *mac) Sum(out *[16]byte) {
|
||||||
|
state := h.state
|
||||||
|
if h.offset > 0 {
|
||||||
|
update(&state, h.buffer[:h.offset])
|
||||||
|
}
|
||||||
|
finalize(out, &state)
|
||||||
}
|
}
|
||||||
|
61
vendor/golang.org/x/crypto/poly1305/sum_amd64.s
generated
vendored
61
vendor/golang.org/x/crypto/poly1305/sum_amd64.s
generated
vendored
@ -58,20 +58,17 @@ DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
|
|||||||
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
|
||||||
GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
GLOBL ·poly1305Mask<>(SB), RODATA, $16
|
||||||
|
|
||||||
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
// func update(state *[7]uint64, msg []byte)
|
||||||
TEXT ·poly1305(SB), $0-32
|
TEXT ·update(SB), $0-32
|
||||||
MOVQ out+0(FP), DI
|
MOVQ state+0(FP), DI
|
||||||
MOVQ m+8(FP), SI
|
MOVQ msg_base+8(FP), SI
|
||||||
MOVQ mlen+16(FP), R15
|
MOVQ msg_len+16(FP), R15
|
||||||
MOVQ key+24(FP), AX
|
|
||||||
|
|
||||||
MOVQ 0(AX), R11
|
MOVQ 0(DI), R8 // h0
|
||||||
MOVQ 8(AX), R12
|
MOVQ 8(DI), R9 // h1
|
||||||
ANDQ ·poly1305Mask<>(SB), R11 // r0
|
MOVQ 16(DI), R10 // h2
|
||||||
ANDQ ·poly1305Mask<>+8(SB), R12 // r1
|
MOVQ 24(DI), R11 // r0
|
||||||
XORQ R8, R8 // h0
|
MOVQ 32(DI), R12 // r1
|
||||||
XORQ R9, R9 // h1
|
|
||||||
XORQ R10, R10 // h2
|
|
||||||
|
|
||||||
CMPQ R15, $16
|
CMPQ R15, $16
|
||||||
JB bytes_between_0_and_15
|
JB bytes_between_0_and_15
|
||||||
@ -109,16 +106,42 @@ flush_buffer:
|
|||||||
JMP multiply
|
JMP multiply
|
||||||
|
|
||||||
done:
|
done:
|
||||||
MOVQ R8, AX
|
MOVQ R8, 0(DI)
|
||||||
MOVQ R9, BX
|
MOVQ R9, 8(DI)
|
||||||
|
MOVQ R10, 16(DI)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func initialize(state *[7]uint64, key *[32]byte)
|
||||||
|
TEXT ·initialize(SB), $0-16
|
||||||
|
MOVQ state+0(FP), DI
|
||||||
|
MOVQ key+8(FP), SI
|
||||||
|
|
||||||
|
// state[0...7] is initialized with zero
|
||||||
|
MOVOU 0(SI), X0
|
||||||
|
MOVOU 16(SI), X1
|
||||||
|
MOVOU ·poly1305Mask<>(SB), X2
|
||||||
|
PAND X2, X0
|
||||||
|
MOVOU X0, 24(DI)
|
||||||
|
MOVOU X1, 40(DI)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func finalize(tag *[TagSize]byte, state *[7]uint64)
|
||||||
|
TEXT ·finalize(SB), $0-16
|
||||||
|
MOVQ tag+0(FP), DI
|
||||||
|
MOVQ state+8(FP), SI
|
||||||
|
|
||||||
|
MOVQ 0(SI), AX
|
||||||
|
MOVQ 8(SI), BX
|
||||||
|
MOVQ 16(SI), CX
|
||||||
|
MOVQ AX, R8
|
||||||
|
MOVQ BX, R9
|
||||||
SUBQ $0xFFFFFFFFFFFFFFFB, AX
|
SUBQ $0xFFFFFFFFFFFFFFFB, AX
|
||||||
SBBQ $0xFFFFFFFFFFFFFFFF, BX
|
SBBQ $0xFFFFFFFFFFFFFFFF, BX
|
||||||
SBBQ $3, R10
|
SBBQ $3, CX
|
||||||
CMOVQCS R8, AX
|
CMOVQCS R8, AX
|
||||||
CMOVQCS R9, BX
|
CMOVQCS R9, BX
|
||||||
MOVQ key+24(FP), R8
|
ADDQ 40(SI), AX
|
||||||
ADDQ 16(R8), AX
|
ADCQ 48(SI), BX
|
||||||
ADCQ 24(R8), BX
|
|
||||||
|
|
||||||
MOVQ AX, 0(DI)
|
MOVQ AX, 0(DI)
|
||||||
MOVQ BX, 8(DI)
|
MOVQ BX, 8(DI)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -6,21 +6,79 @@ package poly1305
|
|||||||
|
|
||||||
import "encoding/binary"
|
import "encoding/binary"
|
||||||
|
|
||||||
|
const (
|
||||||
|
msgBlock = uint32(1 << 24)
|
||||||
|
finalBlock = uint32(0)
|
||||||
|
)
|
||||||
|
|
||||||
// sumGeneric generates an authenticator for msg using a one-time key and
|
// sumGeneric generates an authenticator for msg using a one-time key and
|
||||||
// puts the 16-byte result into out. This is the generic implementation of
|
// puts the 16-byte result into out. This is the generic implementation of
|
||||||
// Sum and should be called if no assembly implementation is available.
|
// Sum and should be called if no assembly implementation is available.
|
||||||
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
var (
|
h := newMACGeneric(key)
|
||||||
h0, h1, h2, h3, h4 uint32 // the hash accumulators
|
h.Write(msg)
|
||||||
r0, r1, r2, r3, r4 uint64 // the r part of the key
|
h.Sum(out)
|
||||||
)
|
}
|
||||||
|
|
||||||
r0 = uint64(binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff)
|
func newMACGeneric(key *[32]byte) (h macGeneric) {
|
||||||
r1 = uint64((binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03)
|
h.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff
|
||||||
r2 = uint64((binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff)
|
h.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03
|
||||||
r3 = uint64((binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff)
|
h.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff
|
||||||
r4 = uint64((binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff)
|
h.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff
|
||||||
|
h.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff
|
||||||
|
|
||||||
|
h.s[0] = binary.LittleEndian.Uint32(key[16:])
|
||||||
|
h.s[1] = binary.LittleEndian.Uint32(key[20:])
|
||||||
|
h.s[2] = binary.LittleEndian.Uint32(key[24:])
|
||||||
|
h.s[3] = binary.LittleEndian.Uint32(key[28:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type macGeneric struct {
|
||||||
|
h, r [5]uint32
|
||||||
|
s [4]uint32
|
||||||
|
|
||||||
|
buffer [TagSize]byte
|
||||||
|
offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *macGeneric) Write(p []byte) (n int, err error) {
|
||||||
|
n = len(p)
|
||||||
|
if h.offset > 0 {
|
||||||
|
remaining := TagSize - h.offset
|
||||||
|
if n < remaining {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
copy(h.buffer[h.offset:], p[:remaining])
|
||||||
|
p = p[remaining:]
|
||||||
|
h.offset = 0
|
||||||
|
updateGeneric(h.buffer[:], msgBlock, &(h.h), &(h.r))
|
||||||
|
}
|
||||||
|
if nn := len(p) - (len(p) % TagSize); nn > 0 {
|
||||||
|
updateGeneric(p, msgBlock, &(h.h), &(h.r))
|
||||||
|
p = p[nn:]
|
||||||
|
}
|
||||||
|
if len(p) > 0 {
|
||||||
|
h.offset += copy(h.buffer[h.offset:], p)
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *macGeneric) Sum(out *[16]byte) {
|
||||||
|
H, R := h.h, h.r
|
||||||
|
if h.offset > 0 {
|
||||||
|
var buffer [TagSize]byte
|
||||||
|
copy(buffer[:], h.buffer[:h.offset])
|
||||||
|
buffer[h.offset] = 1 // invariant: h.offset < TagSize
|
||||||
|
updateGeneric(buffer[:], finalBlock, &H, &R)
|
||||||
|
}
|
||||||
|
finalizeGeneric(out, &H, &(h.s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateGeneric(msg []byte, flag uint32, h, r *[5]uint32) {
|
||||||
|
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
|
||||||
|
r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4])
|
||||||
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
|
R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
|
||||||
|
|
||||||
for len(msg) >= TagSize {
|
for len(msg) >= TagSize {
|
||||||
@ -29,7 +87,7 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
|||||||
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
|
h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
|
||||||
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
|
h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
|
||||||
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
|
h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
|
||||||
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | (1 << 24)
|
h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | flag
|
||||||
|
|
||||||
// h *= r
|
// h *= r
|
||||||
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
||||||
@ -52,36 +110,11 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
|||||||
msg = msg[TagSize:]
|
msg = msg[TagSize:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(msg) > 0 {
|
h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4
|
||||||
var block [TagSize]byte
|
}
|
||||||
off := copy(block[:], msg)
|
|
||||||
block[off] = 0x01
|
|
||||||
|
|
||||||
// h += msg
|
func finalizeGeneric(out *[TagSize]byte, h *[5]uint32, s *[4]uint32) {
|
||||||
h0 += binary.LittleEndian.Uint32(block[0:]) & 0x3ffffff
|
h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4]
|
||||||
h1 += (binary.LittleEndian.Uint32(block[3:]) >> 2) & 0x3ffffff
|
|
||||||
h2 += (binary.LittleEndian.Uint32(block[6:]) >> 4) & 0x3ffffff
|
|
||||||
h3 += (binary.LittleEndian.Uint32(block[9:]) >> 6) & 0x3ffffff
|
|
||||||
h4 += (binary.LittleEndian.Uint32(block[12:]) >> 8)
|
|
||||||
|
|
||||||
// h *= r
|
|
||||||
d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
|
|
||||||
d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
|
|
||||||
d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
|
|
||||||
d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
|
|
||||||
d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
|
|
||||||
|
|
||||||
// h %= p
|
|
||||||
h0 = uint32(d0) & 0x3ffffff
|
|
||||||
h1 = uint32(d1) & 0x3ffffff
|
|
||||||
h2 = uint32(d2) & 0x3ffffff
|
|
||||||
h3 = uint32(d3) & 0x3ffffff
|
|
||||||
h4 = uint32(d4) & 0x3ffffff
|
|
||||||
|
|
||||||
h0 += uint32(d4>>26) * 5
|
|
||||||
h1 += h0 >> 26
|
|
||||||
h0 = h0 & 0x3ffffff
|
|
||||||
}
|
|
||||||
|
|
||||||
// h %= p reduction
|
// h %= p reduction
|
||||||
h2 += h1 >> 26
|
h2 += h1 >> 26
|
||||||
@ -123,13 +156,13 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
|||||||
|
|
||||||
// s: the s part of the key
|
// s: the s part of the key
|
||||||
// tag = (h + s) % (2^128)
|
// tag = (h + s) % (2^128)
|
||||||
t := uint64(h0) + uint64(binary.LittleEndian.Uint32(key[16:]))
|
t := uint64(h0) + uint64(s[0])
|
||||||
h0 = uint32(t)
|
h0 = uint32(t)
|
||||||
t = uint64(h1) + uint64(binary.LittleEndian.Uint32(key[20:])) + (t >> 32)
|
t = uint64(h1) + uint64(s[1]) + (t >> 32)
|
||||||
h1 = uint32(t)
|
h1 = uint32(t)
|
||||||
t = uint64(h2) + uint64(binary.LittleEndian.Uint32(key[24:])) + (t >> 32)
|
t = uint64(h2) + uint64(s[2]) + (t >> 32)
|
||||||
h2 = uint32(t)
|
h2 = uint32(t)
|
||||||
t = uint64(h3) + uint64(binary.LittleEndian.Uint32(key[28:])) + (t >> 32)
|
t = uint64(h3) + uint64(s[3]) + (t >> 32)
|
||||||
h3 = uint32(t)
|
h3 = uint32(t)
|
||||||
|
|
||||||
binary.LittleEndian.PutUint32(out[0:], h0)
|
binary.LittleEndian.PutUint32(out[0:], h0)
|
4
vendor/golang.org/x/crypto/poly1305/sum_noasm.go
generated
vendored
4
vendor/golang.org/x/crypto/poly1305/sum_noasm.go
generated
vendored
@ -10,5 +10,7 @@ package poly1305
|
|||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
// key allows an attacker to forge messages at will.
|
// key allows an attacker to forge messages at will.
|
||||||
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||||
sumGeneric(out, msg, key)
|
h := newMAC(key)
|
||||||
|
h.Write(msg)
|
||||||
|
h.Sum(out)
|
||||||
}
|
}
|
||||||
|
17
vendor/golang.org/x/crypto/poly1305/sum_s390x.go
generated
vendored
17
vendor/golang.org/x/crypto/poly1305/sum_s390x.go
generated
vendored
@ -6,16 +6,9 @@
|
|||||||
|
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
// hasVectorFacility reports whether the machine supports
|
import (
|
||||||
// the vector facility (vx).
|
"golang.org/x/sys/cpu"
|
||||||
func hasVectorFacility() bool
|
)
|
||||||
|
|
||||||
// hasVMSLFacility reports whether the machine supports
|
|
||||||
// Vector Multiply Sum Logical (VMSL).
|
|
||||||
func hasVMSLFacility() bool
|
|
||||||
|
|
||||||
var hasVX = hasVectorFacility()
|
|
||||||
var hasVMSL = hasVMSLFacility()
|
|
||||||
|
|
||||||
// poly1305vx is an assembly implementation of Poly1305 that uses vector
|
// poly1305vx is an assembly implementation of Poly1305 that uses vector
|
||||||
// instructions. It must only be called if the vector facility (vx) is
|
// instructions. It must only be called if the vector facility (vx) is
|
||||||
@ -33,12 +26,12 @@ func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
|||||||
// 16-byte result into out. Authenticating two different messages with the same
|
// 16-byte result into out. Authenticating two different messages with the same
|
||||||
// key allows an attacker to forge messages at will.
|
// key allows an attacker to forge messages at will.
|
||||||
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||||
if hasVX {
|
if cpu.S390X.HasVX {
|
||||||
var mPtr *byte
|
var mPtr *byte
|
||||||
if len(m) > 0 {
|
if len(m) > 0 {
|
||||||
mPtr = &m[0]
|
mPtr = &m[0]
|
||||||
}
|
}
|
||||||
if hasVMSL && len(m) > 256 {
|
if cpu.S390X.HasVXE && len(m) > 256 {
|
||||||
poly1305vmsl(out, mPtr, uint64(len(m)), key)
|
poly1305vmsl(out, mPtr, uint64(len(m)), key)
|
||||||
} else {
|
} else {
|
||||||
poly1305vx(out, mPtr, uint64(len(m)), key)
|
poly1305vx(out, mPtr, uint64(len(m)), key)
|
||||||
|
22
vendor/golang.org/x/crypto/poly1305/sum_s390x.s
generated
vendored
22
vendor/golang.org/x/crypto/poly1305/sum_s390x.s
generated
vendored
@ -376,25 +376,3 @@ b1:
|
|||||||
|
|
||||||
MOVD $0, R3
|
MOVD $0, R3
|
||||||
BR multiply
|
BR multiply
|
||||||
|
|
||||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
|
||||||
MOVD $x-24(SP), R1
|
|
||||||
XC $24, 0(R1), 0(R1) // clear the storage
|
|
||||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
|
||||||
WORD $0xB2B01000 // STFLE 0(R1)
|
|
||||||
XOR R0, R0 // reset the value of R0
|
|
||||||
MOVBZ z-8(SP), R1
|
|
||||||
AND $0x40, R1
|
|
||||||
BEQ novector
|
|
||||||
|
|
||||||
vectorinstalled:
|
|
||||||
// check if the vector instruction has been enabled
|
|
||||||
VLEIB $0, $0xF, V16
|
|
||||||
VLGVB $0, V16, R1
|
|
||||||
CMPBNE R1, $0xF, novector
|
|
||||||
MOVB $1, ret+0(FP) // have vx
|
|
||||||
RET
|
|
||||||
|
|
||||||
novector:
|
|
||||||
MOVB $0, ret+0(FP) // no vx
|
|
||||||
RET
|
|
||||||
|
22
vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s
generated
vendored
22
vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s
generated
vendored
@ -907,25 +907,3 @@ square:
|
|||||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||||
BR next
|
BR next
|
||||||
|
|
||||||
TEXT ·hasVMSLFacility(SB), NOSPLIT, $24-1
|
|
||||||
MOVD $x-24(SP), R1
|
|
||||||
XC $24, 0(R1), 0(R1) // clear the storage
|
|
||||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
|
||||||
WORD $0xB2B01000 // STFLE 0(R1)
|
|
||||||
XOR R0, R0 // reset the value of R0
|
|
||||||
MOVBZ z-8(SP), R1
|
|
||||||
AND $0x01, R1
|
|
||||||
BEQ novmsl
|
|
||||||
|
|
||||||
vectorinstalled:
|
|
||||||
// check if the vector instruction has been enabled
|
|
||||||
VLEIB $0, $0xF, V16
|
|
||||||
VLGVB $0, V16, R1
|
|
||||||
CMPBNE R1, $0xF, novmsl
|
|
||||||
MOVB $1, ret+0(FP) // have vx
|
|
||||||
RET
|
|
||||||
|
|
||||||
novmsl:
|
|
||||||
MOVB $0, ret+0(FP) // no vx
|
|
||||||
RET
|
|
||||||
|
6
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
6
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
generated
vendored
@ -64,13 +64,15 @@ func Restore(fd int, state *State) error {
|
|||||||
return windows.SetConsoleMode(windows.Handle(fd), state.mode)
|
return windows.SetConsoleMode(windows.Handle(fd), state.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the dimensions of the given terminal.
|
// GetSize returns the visible dimensions of the given terminal.
|
||||||
|
//
|
||||||
|
// These dimensions don't include any scrollback buffer height.
|
||||||
func GetSize(fd int) (width, height int, err error) {
|
func GetSize(fd int) (width, height int, err error) {
|
||||||
var info windows.ConsoleScreenBufferInfo
|
var info windows.ConsoleScreenBufferInfo
|
||||||
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
|
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
return int(info.Size.X), int(info.Size.Y), nil
|
return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadPassword reads a line of input from a terminal without local echo. This
|
// ReadPassword reads a line of input from a terminal without local echo. This
|
||||||
|
30
vendor/golang.org/x/sys/cpu/byteorder.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/cpu/byteorder.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2019 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 cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hostByteOrder returns binary.LittleEndian on little-endian machines and
|
||||||
|
// binary.BigEndian on big-endian machines.
|
||||||
|
func hostByteOrder() binary.ByteOrder {
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "386", "amd64", "amd64p32",
|
||||||
|
"arm", "arm64",
|
||||||
|
"mipsle", "mips64le", "mips64p32le",
|
||||||
|
"ppc64le",
|
||||||
|
"riscv", "riscv64":
|
||||||
|
return binary.LittleEndian
|
||||||
|
case "armbe", "arm64be",
|
||||||
|
"mips", "mips64", "mips64p32",
|
||||||
|
"ppc", "ppc64",
|
||||||
|
"s390", "s390x",
|
||||||
|
"sparc", "sparc64":
|
||||||
|
return binary.BigEndian
|
||||||
|
}
|
||||||
|
panic("unknown architecture")
|
||||||
|
}
|
89
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
Normal file
89
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 2018 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 cpu implements processor feature detection for
|
||||||
|
// various CPU architectures.
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||||
|
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||||
|
|
||||||
|
// X86 contains the supported CPU features of the
|
||||||
|
// current X86/AMD64 platform. If the current platform
|
||||||
|
// is not X86/AMD64 then all feature flags are false.
|
||||||
|
//
|
||||||
|
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||||
|
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||||
|
// registers in addition to the CPUID feature bit being set.
|
||||||
|
var X86 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasAES bool // AES hardware implementation (AES NI)
|
||||||
|
HasADX bool // Multi-precision add-carry instruction extensions
|
||||||
|
HasAVX bool // Advanced vector extension
|
||||||
|
HasAVX2 bool // Advanced vector extension 2
|
||||||
|
HasBMI1 bool // Bit manipulation instruction set 1
|
||||||
|
HasBMI2 bool // Bit manipulation instruction set 2
|
||||||
|
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||||
|
HasFMA bool // Fused-multiply-add instructions
|
||||||
|
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||||
|
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||||
|
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||||
|
HasRDRAND bool // RDRAND instruction (on-chip random number generator)
|
||||||
|
HasRDSEED bool // RDSEED instruction (on-chip random number generator)
|
||||||
|
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||||
|
HasSSE3 bool // Streaming SIMD extension 3
|
||||||
|
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||||
|
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||||
|
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM64 contains the supported CPU features of the
|
||||||
|
// current ARMv8(aarch64) platform. If the current platform
|
||||||
|
// is not arm64 then all feature flags are false.
|
||||||
|
var ARM64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasFP bool // Floating-point instruction set (always available)
|
||||||
|
HasASIMD bool // Advanced SIMD (always available)
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
HasATOMICS bool // Atomic memory operation instruction set
|
||||||
|
HasFPHP bool // Half precision floating-point instruction set
|
||||||
|
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||||
|
HasCPUID bool // CPUID identification scheme registers
|
||||||
|
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||||
|
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||||
|
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||||
|
HasLRCPC bool // Release Consistent processor consistent support
|
||||||
|
HasDCPOP bool // Persistent memory support
|
||||||
|
HasSHA3 bool // SHA3 hardware implementation
|
||||||
|
HasSM3 bool // SM3 hardware implementation
|
||||||
|
HasSM4 bool // SM4 hardware implementation
|
||||||
|
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||||
|
HasSHA512 bool // SHA512 hardware implementation
|
||||||
|
HasSVE bool // Scalable Vector Extensions
|
||||||
|
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||||
|
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||||
|
//
|
||||||
|
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||||
|
// since there are no optional categories. There are some exceptions that also
|
||||||
|
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||||
|
// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
|
||||||
|
// The struct is padded to avoid false sharing.
|
||||||
|
var PPC64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||||
|
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||||
|
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||||
|
IsPOWER9 bool // ISA v3.00 (POWER9)
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
9
vendor/golang.org/x/sys/cpu/cpu_arm.go
generated
vendored
Normal file
9
vendor/golang.org/x/sys/cpu/cpu_arm.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2018 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 cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func doinit() {}
|
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
Normal file
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// cpuid is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||||
|
|
||||||
|
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func xgetbv() (eax, edx uint32)
|
43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c
generated
vendored
Normal file
43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
#include <cpuid.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||||
|
int
|
||||||
|
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
|
||||||
|
uint32_t *eax, uint32_t *ebx,
|
||||||
|
uint32_t *ecx, uint32_t *edx)
|
||||||
|
{
|
||||||
|
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||||
|
// specified in the ECX register into registers EDX:EAX.
|
||||||
|
// Currently, the only supported value for XCR is 0.
|
||||||
|
//
|
||||||
|
// TODO: Replace with a better alternative:
|
||||||
|
//
|
||||||
|
// #include <xsaveintrin.h>
|
||||||
|
//
|
||||||
|
// #pragma GCC target("xsave")
|
||||||
|
//
|
||||||
|
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
|
||||||
|
// unsigned long long x = _xgetbv(0);
|
||||||
|
// *eax = x & 0xffffffff;
|
||||||
|
// *edx = (x >> 32) & 0xffffffff;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Note that _xgetbv is defined starting with GCC 8.
|
||||||
|
void
|
||||||
|
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
|
||||||
|
{
|
||||||
|
__asm(" xorl %%ecx, %%ecx\n"
|
||||||
|
" xgetbv"
|
||||||
|
: "=a"(*eax), "=d"(*edx));
|
||||||
|
}
|
26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go
generated
vendored
Normal file
26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
//extern gccgoGetCpuidCount
|
||||||
|
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
|
||||||
|
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
|
||||||
|
var a, b, c, d uint32
|
||||||
|
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
|
||||||
|
return a, b, c, d
|
||||||
|
}
|
||||||
|
|
||||||
|
//extern gccgoXgetbv
|
||||||
|
func gccgoXgetbv(eax, edx *uint32)
|
||||||
|
|
||||||
|
func xgetbv() (eax, edx uint32) {
|
||||||
|
var a, d uint32
|
||||||
|
gccgoXgetbv(&a, &d)
|
||||||
|
return a, d
|
||||||
|
}
|
55
vendor/golang.org/x/sys/cpu/cpu_linux.go
generated
vendored
Normal file
55
vendor/golang.org/x/sys/cpu/cpu_linux.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
//+build !amd64,!amd64p32,!386
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_AT_HWCAP = 16
|
||||||
|
_AT_HWCAP2 = 26
|
||||||
|
|
||||||
|
procAuxv = "/proc/self/auxv"
|
||||||
|
|
||||||
|
uintSize = int(32 << (^uint(0) >> 63))
|
||||||
|
)
|
||||||
|
|
||||||
|
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||||
|
// These are initialized in cpu_$GOARCH.go
|
||||||
|
// and should not be changed after they are initialized.
|
||||||
|
var hwCap uint
|
||||||
|
var hwCap2 uint
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
buf, err := ioutil.ReadFile(procAuxv)
|
||||||
|
if err != nil {
|
||||||
|
panic("read proc auxv failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
bo := hostByteOrder()
|
||||||
|
for len(buf) >= 2*(uintSize/8) {
|
||||||
|
var tag, val uint
|
||||||
|
switch uintSize {
|
||||||
|
case 32:
|
||||||
|
tag = uint(bo.Uint32(buf[0:]))
|
||||||
|
val = uint(bo.Uint32(buf[4:]))
|
||||||
|
buf = buf[8:]
|
||||||
|
case 64:
|
||||||
|
tag = uint(bo.Uint64(buf[0:]))
|
||||||
|
val = uint(bo.Uint64(buf[8:]))
|
||||||
|
buf = buf[16:]
|
||||||
|
}
|
||||||
|
switch tag {
|
||||||
|
case _AT_HWCAP:
|
||||||
|
hwCap = val
|
||||||
|
case _AT_HWCAP2:
|
||||||
|
hwCap2 = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doinit()
|
||||||
|
}
|
67
vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
generated
vendored
Normal file
67
vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2018 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 cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||||
|
const (
|
||||||
|
hwcap_FP = 1 << 0
|
||||||
|
hwcap_ASIMD = 1 << 1
|
||||||
|
hwcap_EVTSTRM = 1 << 2
|
||||||
|
hwcap_AES = 1 << 3
|
||||||
|
hwcap_PMULL = 1 << 4
|
||||||
|
hwcap_SHA1 = 1 << 5
|
||||||
|
hwcap_SHA2 = 1 << 6
|
||||||
|
hwcap_CRC32 = 1 << 7
|
||||||
|
hwcap_ATOMICS = 1 << 8
|
||||||
|
hwcap_FPHP = 1 << 9
|
||||||
|
hwcap_ASIMDHP = 1 << 10
|
||||||
|
hwcap_CPUID = 1 << 11
|
||||||
|
hwcap_ASIMDRDM = 1 << 12
|
||||||
|
hwcap_JSCVT = 1 << 13
|
||||||
|
hwcap_FCMA = 1 << 14
|
||||||
|
hwcap_LRCPC = 1 << 15
|
||||||
|
hwcap_DCPOP = 1 << 16
|
||||||
|
hwcap_SHA3 = 1 << 17
|
||||||
|
hwcap_SM3 = 1 << 18
|
||||||
|
hwcap_SM4 = 1 << 19
|
||||||
|
hwcap_ASIMDDP = 1 << 20
|
||||||
|
hwcap_SHA512 = 1 << 21
|
||||||
|
hwcap_SVE = 1 << 22
|
||||||
|
hwcap_ASIMDFHM = 1 << 23
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
// HWCAP feature bits
|
||||||
|
ARM64.HasFP = isSet(hwCap, hwcap_FP)
|
||||||
|
ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
|
||||||
|
ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
|
||||||
|
ARM64.HasAES = isSet(hwCap, hwcap_AES)
|
||||||
|
ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
|
||||||
|
ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
|
||||||
|
ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
|
||||||
|
ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
|
||||||
|
ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
|
||||||
|
ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
|
||||||
|
ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
|
||||||
|
ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
|
||||||
|
ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
|
||||||
|
ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
|
||||||
|
ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
|
||||||
|
ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
|
||||||
|
ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
|
||||||
|
ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
|
||||||
|
ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
|
||||||
|
ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
|
||||||
|
ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
|
||||||
|
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
|
||||||
|
ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
|
||||||
|
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
33
vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
generated
vendored
Normal file
33
vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 128
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
|
||||||
|
const (
|
||||||
|
// ISA Level
|
||||||
|
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
|
||||||
|
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
|
||||||
|
|
||||||
|
// CPU features
|
||||||
|
_PPC_FEATURE2_DARN = 0x00200000
|
||||||
|
_PPC_FEATURE2_SCV = 0x00100000
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
// HWCAP2 feature bits
|
||||||
|
PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
|
||||||
|
PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
|
||||||
|
PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
|
||||||
|
PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
11
vendor/golang.org/x/sys/cpu/cpu_mips64x.go
generated
vendored
Normal file
11
vendor/golang.org/x/sys/cpu/cpu_mips64x.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build mips64 mips64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func doinit() {}
|
11
vendor/golang.org/x/sys/cpu/cpu_mipsx.go
generated
vendored
Normal file
11
vendor/golang.org/x/sys/cpu/cpu_mipsx.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func doinit() {}
|
11
vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
generated
vendored
Normal file
11
vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2019 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.
|
||||||
|
|
||||||
|
// +build !linux,arm64
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
func doinit() {}
|
12
vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go
generated
vendored
Normal file
12
vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2019 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.
|
||||||
|
|
||||||
|
// +build !linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 128
|
||||||
|
|
||||||
|
func doinit() {}
|
9
vendor/golang.org/x/sys/cpu/cpu_s390x.go
generated
vendored
Normal file
9
vendor/golang.org/x/sys/cpu/cpu_s390x.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2018 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 cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 256
|
||||||
|
|
||||||
|
func doinit() {}
|
57
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
Normal file
57
vendor/golang.org/x/sys/cpu/cpu_x86.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
maxID, _, _, _ := cpuid(0, 0)
|
||||||
|
|
||||||
|
if maxID < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, ecx1, edx1 := cpuid(1, 0)
|
||||||
|
X86.HasSSE2 = isSet(26, edx1)
|
||||||
|
|
||||||
|
X86.HasSSE3 = isSet(0, ecx1)
|
||||||
|
X86.HasPCLMULQDQ = isSet(1, ecx1)
|
||||||
|
X86.HasSSSE3 = isSet(9, ecx1)
|
||||||
|
X86.HasFMA = isSet(12, ecx1)
|
||||||
|
X86.HasSSE41 = isSet(19, ecx1)
|
||||||
|
X86.HasSSE42 = isSet(20, ecx1)
|
||||||
|
X86.HasPOPCNT = isSet(23, ecx1)
|
||||||
|
X86.HasAES = isSet(25, ecx1)
|
||||||
|
X86.HasOSXSAVE = isSet(27, ecx1)
|
||||||
|
X86.HasRDRAND = isSet(30, ecx1)
|
||||||
|
|
||||||
|
osSupportsAVX := false
|
||||||
|
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||||
|
if X86.HasOSXSAVE {
|
||||||
|
eax, _ := xgetbv()
|
||||||
|
// Check if XMM and YMM registers have OS support.
|
||||||
|
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||||
|
}
|
||||||
|
|
||||||
|
X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
|
||||||
|
|
||||||
|
if maxID < 7 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, ebx7, _, _ := cpuid(7, 0)
|
||||||
|
X86.HasBMI1 = isSet(3, ebx7)
|
||||||
|
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
|
||||||
|
X86.HasBMI2 = isSet(8, ebx7)
|
||||||
|
X86.HasERMS = isSet(9, ebx7)
|
||||||
|
X86.HasRDSEED = isSet(18, ebx7)
|
||||||
|
X86.HasADX = isSet(19, ebx7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(bitpos uint, value uint32) bool {
|
||||||
|
return value&(1<<bitpos) != 0
|
||||||
|
}
|
27
vendor/golang.org/x/sys/cpu/cpu_x86.s
generated
vendored
Normal file
27
vendor/golang.org/x/sys/cpu/cpu_x86.s
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||||
|
TEXT ·cpuid(SB), NOSPLIT, $0-24
|
||||||
|
MOVL eaxArg+0(FP), AX
|
||||||
|
MOVL ecxArg+4(FP), CX
|
||||||
|
CPUID
|
||||||
|
MOVL AX, eax+8(FP)
|
||||||
|
MOVL BX, ebx+12(FP)
|
||||||
|
MOVL CX, ecx+16(FP)
|
||||||
|
MOVL DX, edx+20(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func xgetbv() (eax, edx uint32)
|
||||||
|
TEXT ·xgetbv(SB),NOSPLIT,$0-8
|
||||||
|
MOVL $0, CX
|
||||||
|
XGETBV
|
||||||
|
MOVL AX, eax+0(FP)
|
||||||
|
MOVL DX, edx+4(FP)
|
||||||
|
RET
|
@ -20,7 +20,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChatUpdateCommand string
|
type ChatUpdateCommand string
|
@ -20,7 +20,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CommandType string
|
type CommandType string
|
@ -19,7 +19,7 @@ package whatsappExt
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConnInfo struct {
|
type ConnInfo struct {
|
@ -19,7 +19,7 @@ package whatsappExt
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type JSONMessage []json.RawMessage
|
type JSONMessage []json.RawMessage
|
@ -20,7 +20,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MsgInfoCommand string
|
type MsgInfoCommand string
|
@ -20,7 +20,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PresenceType string
|
type PresenceType string
|
@ -19,7 +19,7 @@ package whatsappExt
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProtocolProps struct {
|
type ProtocolProps struct {
|
@ -19,7 +19,7 @@ package whatsappExt
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StreamType string
|
type StreamType string
|
@ -24,7 +24,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matterbridge/go-whatsapp"
|
"github.com/Rhymen/go-whatsapp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
27
vendor/modules.txt
vendored
27
vendor/modules.txt
vendored
@ -15,6 +15,14 @@ github.com/Philipp15b/go-steam/protocol/gamecoordinator
|
|||||||
github.com/Philipp15b/go-steam/protocol/protobuf
|
github.com/Philipp15b/go-steam/protocol/protobuf
|
||||||
github.com/Philipp15b/go-steam/rwu
|
github.com/Philipp15b/go-steam/rwu
|
||||||
github.com/Philipp15b/go-steam/socialcache
|
github.com/Philipp15b/go-steam/socialcache
|
||||||
|
# github.com/Rhymen/go-whatsapp v0.0.2-0.20190325075644-cc2581bbf24d
|
||||||
|
github.com/Rhymen/go-whatsapp
|
||||||
|
github.com/Rhymen/go-whatsapp/binary
|
||||||
|
github.com/Rhymen/go-whatsapp/binary/proto
|
||||||
|
github.com/Rhymen/go-whatsapp/crypto/cbc
|
||||||
|
github.com/Rhymen/go-whatsapp/crypto/curve25519
|
||||||
|
github.com/Rhymen/go-whatsapp/crypto/hkdf
|
||||||
|
github.com/Rhymen/go-whatsapp/binary/token
|
||||||
# github.com/bwmarrin/discordgo v0.19.0
|
# github.com/bwmarrin/discordgo v0.19.0
|
||||||
github.com/bwmarrin/discordgo
|
github.com/bwmarrin/discordgo
|
||||||
# github.com/d5/tengo v1.20.0
|
# github.com/d5/tengo v1.20.0
|
||||||
@ -40,7 +48,7 @@ github.com/dgrijalva/jwt-go
|
|||||||
github.com/fsnotify/fsnotify
|
github.com/fsnotify/fsnotify
|
||||||
# github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible
|
# github.com/go-telegram-bot-api/telegram-bot-api v4.6.5-0.20181225215658-ec221ba9ea45+incompatible
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api
|
github.com/go-telegram-bot-api/telegram-bot-api
|
||||||
# github.com/golang/protobuf v1.2.0
|
# github.com/golang/protobuf v1.3.0
|
||||||
github.com/golang/protobuf/proto
|
github.com/golang/protobuf/proto
|
||||||
github.com/golang/protobuf/protoc-gen-go/descriptor
|
github.com/golang/protobuf/protoc-gen-go/descriptor
|
||||||
# github.com/google/gops v0.3.5
|
# github.com/google/gops v0.3.5
|
||||||
@ -89,14 +97,6 @@ github.com/magiconair/properties
|
|||||||
github.com/matterbridge/Rocket.Chat.Go.SDK/models
|
github.com/matterbridge/Rocket.Chat.Go.SDK/models
|
||||||
github.com/matterbridge/Rocket.Chat.Go.SDK/realtime
|
github.com/matterbridge/Rocket.Chat.Go.SDK/realtime
|
||||||
github.com/matterbridge/Rocket.Chat.Go.SDK/rest
|
github.com/matterbridge/Rocket.Chat.Go.SDK/rest
|
||||||
# github.com/matterbridge/go-whatsapp v0.0.1-0.20190301204034-f2f1b29d441b
|
|
||||||
github.com/matterbridge/go-whatsapp
|
|
||||||
github.com/matterbridge/go-whatsapp/binary
|
|
||||||
github.com/matterbridge/go-whatsapp/binary/proto
|
|
||||||
github.com/matterbridge/go-whatsapp/crypto/cbc
|
|
||||||
github.com/matterbridge/go-whatsapp/crypto/curve25519
|
|
||||||
github.com/matterbridge/go-whatsapp/crypto/hkdf
|
|
||||||
github.com/matterbridge/go-whatsapp/binary/token
|
|
||||||
# github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
|
# github.com/matterbridge/go-xmpp v0.0.0-20180529212104-cd19799fba91
|
||||||
github.com/matterbridge/go-xmpp
|
github.com/matterbridge/go-xmpp
|
||||||
# github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea
|
# github.com/matterbridge/gomatrix v0.0.0-20190102230110-6f9631ca6dea
|
||||||
@ -105,8 +105,6 @@ github.com/matterbridge/gomatrix
|
|||||||
github.com/matterbridge/gozulipbot
|
github.com/matterbridge/gozulipbot
|
||||||
# github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
|
# github.com/matterbridge/logrus-prefixed-formatter v0.0.0-20180806162718-01618749af61
|
||||||
github.com/matterbridge/logrus-prefixed-formatter
|
github.com/matterbridge/logrus-prefixed-formatter
|
||||||
# github.com/matterbridge/mautrix-whatsapp v0.0.0-20190301210046-3539cf52ed6e
|
|
||||||
github.com/matterbridge/mautrix-whatsapp/whatsapp-ext
|
|
||||||
# github.com/mattermost/mattermost-server v5.5.0+incompatible
|
# github.com/mattermost/mattermost-server v5.5.0+incompatible
|
||||||
github.com/mattermost/mattermost-server/model
|
github.com/mattermost/mattermost-server/model
|
||||||
github.com/mattermost/mattermost-server/mlog
|
github.com/mattermost/mattermost-server/mlog
|
||||||
@ -143,7 +141,7 @@ github.com/pborman/uuid
|
|||||||
github.com/pelletier/go-toml
|
github.com/pelletier/go-toml
|
||||||
# github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320
|
# github.com/peterhellberg/emojilib v0.0.0-20190124112554-c18758d55320
|
||||||
github.com/peterhellberg/emojilib
|
github.com/peterhellberg/emojilib
|
||||||
# github.com/pkg/errors v0.8.0
|
# github.com/pkg/errors v0.8.1
|
||||||
github.com/pkg/errors
|
github.com/pkg/errors
|
||||||
# github.com/pmezard/go-difflib v1.0.0
|
# github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/pmezard/go-difflib/difflib
|
github.com/pmezard/go-difflib/difflib
|
||||||
@ -208,7 +206,7 @@ go.uber.org/zap/internal/bufferpool
|
|||||||
go.uber.org/zap/buffer
|
go.uber.org/zap/buffer
|
||||||
go.uber.org/zap/internal/color
|
go.uber.org/zap/internal/color
|
||||||
go.uber.org/zap/internal/exit
|
go.uber.org/zap/internal/exit
|
||||||
# golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f
|
# golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||||
golang.org/x/crypto/ssh/terminal
|
golang.org/x/crypto/ssh/terminal
|
||||||
golang.org/x/crypto/acme/autocert
|
golang.org/x/crypto/acme/autocert
|
||||||
golang.org/x/crypto/nacl/secretbox
|
golang.org/x/crypto/nacl/secretbox
|
||||||
@ -234,6 +232,7 @@ golang.org/x/net/websocket
|
|||||||
# golang.org/x/sys v0.0.0-20190222171317-cd391775e71e
|
# golang.org/x/sys v0.0.0-20190222171317-cd391775e71e
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
|
golang.org/x/sys/cpu
|
||||||
# golang.org/x/text v0.3.0
|
# golang.org/x/text v0.3.0
|
||||||
golang.org/x/text/encoding
|
golang.org/x/text/encoding
|
||||||
golang.org/x/text/encoding/japanese
|
golang.org/x/text/encoding/japanese
|
||||||
@ -249,3 +248,5 @@ golang.org/x/text/encoding/internal
|
|||||||
gopkg.in/natefinch/lumberjack.v2
|
gopkg.in/natefinch/lumberjack.v2
|
||||||
# gopkg.in/yaml.v2 v2.2.2
|
# gopkg.in/yaml.v2 v2.2.2
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
|
# maunium.net/go/mautrix-whatsapp v0.0.0-20190406194125-7e1028726f0f
|
||||||
|
maunium.net/go/mautrix-whatsapp/whatsapp-ext
|
||||||
|
Loading…
Reference in New Issue
Block a user