name_pipe_windows.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. //go:build windows
  2. // +build windows
  3. package namedpipe
  4. import (
  5. "bufio"
  6. "fmt"
  7. log "github.com/sirupsen/logrus"
  8. "net"
  9. "sync/atomic"
  10. )
  11. const pipeNameDaemonAndSubPattern = `\\.\pipe\`
  12. const ONEAGENT = "cw-oneagent"
  13. const NETFLOW = "cw-netflow"
  14. const SERVERAGENT = "cw-serveragent"
  15. type NamedPipe4W struct {
  16. *namedPipe
  17. pipePath string
  18. listener *npipe.PipeListener
  19. conn net.Conn
  20. }
  21. /*
  22. ListenNpipe
  23. @Description: 创建命名管道文件,返回命名管道对象
  24. @param agent_type: from
  25. @param to_type: to
  26. @param isMaster: 是否为daemon创建的
  27. @param single: 是否为单文件模式
  28. @param rootPath: 命名管道文件夹路径
  29. @return *NamedPipe4U: 命名管道对象
  30. @return error: 错误信息
  31. */
  32. func ListenNpipe(agent_type, to_type string, isMaster, single bool, rootPath string) (*NamedPipe4W, error) {
  33. np, err := newNamePipe(agent_type, to_type, isMaster, single, rootPath)
  34. if err != nil {
  35. return nil, err
  36. }
  37. np4w := &NamedPipe4W{namedPipe: np}
  38. if err := np4w.initPipe(); err != nil {
  39. return nil, err
  40. }
  41. return np4w, nil
  42. }
  43. func (np *NamedPipe4W) getPipePath() (daemon2subPipe, sub2DaemonPipe string, err error) {
  44. daemon2subPipe = fmt.Sprintf("%s%s2%s", pipeNameDaemonAndSubPattern, np.fromType, np.toType)
  45. sub2DaemonPipe = fmt.Sprintf("%s%s2%s", pipeNameDaemonAndSubPattern, np.toType, np.fromType)
  46. return daemon2subPipe, sub2DaemonPipe, nil
  47. }
  48. func (np *NamedPipe4W) initPipe() error {
  49. daemon2subPipe, sub2DaemonPipe, err := np.getPipePath()
  50. if err != nil {
  51. return err
  52. }
  53. if np.isDaemon {
  54. // daemon进程进行建连
  55. ln, err := npipe.Listen(daemon2subPipe)
  56. if err != nil {
  57. return err
  58. }
  59. np.listener = ln
  60. // 过程可能会阻塞
  61. conn, err := ln.Accept()
  62. if err != nil {
  63. return err
  64. }
  65. np.conn = conn
  66. np.recvPipe = bufio.NewReader(conn)
  67. np.sendPipe = bufio.NewWriter(conn)
  68. } else {
  69. conn, err := npipe.Dial(sub2DaemonPipe)
  70. if err != nil {
  71. return err
  72. }
  73. np.conn = conn
  74. np.sendPipe = bufio.NewWriter(conn)
  75. np.recvPipe = bufio.NewReader(conn)
  76. }
  77. return nil
  78. }
  79. // only called when io.EOF occurs
  80. func (np *NamedPipe4W) FreeUp4EOF() {
  81. if !atomic.CompareAndSwapUint32(&np.quitFlag, 0, 1) {
  82. log.WithField("module", "namedPipe_Win").Warnf("named pipe(%s) already free", np.pipePath)
  83. return
  84. }
  85. log.WithField("module", "namedPipe_Win").Infof("named pipe(%s) free begin", np.pipePath)
  86. np.wg.Wait()
  87. conn := np.conn
  88. np.conn = nil
  89. if conn != nil {
  90. if err := conn.Close(); err != nil {
  91. log.WithField("module", "namedPipe_Win").Errorf("close named pipe(%s) conn error: %v", np.pipePath, err)
  92. }
  93. }
  94. listener := np.listener
  95. np.listener = nil
  96. if listener != nil {
  97. if err := listener.Close(); err != nil {
  98. log.WithField("module", "namedPipe_Win").Errorf("close named pipe(%s) listener error: %v", np.pipePath, err)
  99. }
  100. }
  101. np.sendPipe = nil
  102. np.recvPipe = nil
  103. log.WithField("module", "namedPipe_Win").Infof("named pipe free(%s) end", np.pipePath)
  104. }