github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/third/kmgRadius/kmgRadius.go (about)

     1  package kmgRadius
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/bronze1man/kmg/kmgLog"
     7  )
     8  
     9  type AcctRequest struct {
    10  	SessionId   string //连接id
    11  	Username    string
    12  	SessionTime uint32 //连接时间
    13  	InputBytes  uint64 //流入字节
    14  	OutputBytes uint64 //流出字节
    15  	NasPort     uint32
    16  }
    17  
    18  type Handler struct {
    19  	// 有的协议需要明文密码来做各种hash的事情
    20  	// exist返回false可以踢掉客户端
    21  	// 同步调用
    22  	Auth func(username string) (password string, exist bool)
    23  	// 计费开始,来了一条新连接
    24  	// 根据协议规定 此处返回给客户端的包,不能发送任何有效信息(比如踢掉客户端,请采用其他办法踢掉客户端)
    25  	// 异步调用
    26  	AcctStart func(acctReq AcctRequest)
    27  	// 计费数据更新
    28  	// 根据协议规定 此处返回给客户端的包,不能发送任何有效信息(比如踢掉客户端,请采用其他办法踢掉客户端)
    29  	// 异步调用
    30  	AcctUpdate func(acctReq AcctRequest)
    31  	// 计费结束
    32  	// 根据协议规定 此处返回给客户端的包,不能发送任何有效信息(比如踢掉客户端,请采用其他办法踢掉客户端)
    33  	// 异步调用
    34  	AcctStop func(acctReq AcctRequest)
    35  }
    36  
    37  //异步运行服务器,
    38  // TODO 返回Closer以便可以关闭服务器,所有无法运行的错误panic出来,其他错误丢到kmgLog error里面.
    39  // 如果不需要Closer可以直接忽略
    40  func RunServer(address string, secret []byte, handler Handler) func() error {
    41  	s := server{
    42  		mschapMap: map[string]mschapStatus{},
    43  		handler:   handler,
    44  	}
    45  	return RunServerWithPacketHandler(address, secret, s.PacketHandler)
    46  }
    47  
    48  type PacketHandler func(request *Packet) *Packet
    49  
    50  //异步运行服务器,返回Closer以便可以关闭服务器,所有无法运行的错误panic出来,其他错误丢到kmgLog error里面.
    51  func RunServerWithPacketHandler(address string, secret []byte, handler PacketHandler) func() error {
    52  	connChan := make(chan *net.UDPConn)
    53  	go func() {
    54  		var conn *net.UDPConn
    55  		addr, err := net.ResolveUDPAddr("udp", address)
    56  		if err != nil {
    57  			panic(err)
    58  		}
    59  		conn, err = net.ListenUDP("udp", addr)
    60  		if err != nil {
    61  			panic(err)
    62  		}
    63  		connChan <- conn
    64  		for {
    65  			b := make([]byte, 4096)
    66  			n, senderAddress, err := conn.ReadFrom(b)
    67  			if err != nil {
    68  				panic(err)
    69  			}
    70  			go func(p []byte, senderAddress net.Addr) {
    71  				pac, err := DecodeRequestPacket(secret, p)
    72  				if err != nil {
    73  					kmgLog.Log("error", "radius.Decode", err.Error())
    74  					return
    75  				}
    76  
    77  				npac := handler(pac)
    78  				if npac == nil {
    79  					// 特殊情况,返回nil,表示抛弃这个包.
    80  					return
    81  				}
    82  				err = npac.Send(conn, senderAddress)
    83  				if err != nil {
    84  					kmgLog.Log("error", "radius.Send", err.Error())
    85  					return
    86  				}
    87  			}(b[:n], senderAddress)
    88  		}
    89  		return
    90  	}()
    91  	conn := <-connChan
    92  	close(connChan)
    93  	return conn.Close
    94  }