-func (h *Handshake) Client(conn *net.UDPConn, data []byte) *Peer {
- switch len(data) {
- case 80: // ENC(H(DSAPub), R+1, El(SDHPub)) + ENC(K, R, RS + SS) + IDtag
- if h.key != nil {
- log.Println("Invalid handshake stage from", h.addr)
- return nil
+func (h *Handshake) Client(data []byte) *Peer {
+ // ENC(H(DSAPub), R+1, El(SDHPub)) + ENC(K, R, RS + SS) + IDtag
+ if h.rServer == nil && h.key == nil &&
+ ((!h.Conf.EncLess && len(data) >= 80) ||
+ (h.Conf.EncLess && len(data) == 2*(EncLessEnlargeSize+h.Conf.MTU))) {
+ // Decrypt remote public key
+ sDHRepr := new([32]byte)
+ var tmp []byte
+ var err error
+ if h.Conf.EncLess {
+ tmp, err = EncLessDecode(
+ h.dsaPubH,
+ h.rNonceNext(1),
+ data[:len(data)/2],
+ )
+ if err != nil {
+ log.Println("Unable to decode packet from", h.addr, err)
+ return nil
+ }
+ copy(sDHRepr[:], tmp[:32])
+ } else {
+ salsa20.XORKeyStream(
+ sDHRepr[:],
+ data[:32],
+ h.rNonceNext(1),
+ h.dsaPubH,
+ )