123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package service
- import (
- "context"
- "dhcp/api/request"
- "dhcp/code"
- "dhcp/internal/backend"
- "dhcp/internal/handler/proxy"
- "dhcp/internal/ip"
- "dhcp/internal/server"
- "dhcp/result"
- "fmt"
- "github.com/go-logr/logr"
- "github.com/insomniacslk/dhcp/dhcpv4/server4"
- "net"
- "net/netip"
- )
- var DHCPServiceMap = map[string]*DHCPService{}
- var DHCPServiceInfoMap = map[string]request.DHCPService{}
- type DhcpConfig struct {
- Mode string `yaml:"mode"` // 模式
- BindAddr string `yaml:"bind_addr"` // 绑定地址
- BindInterface string `yaml:"bind_interface"` // 绑定接口
- IpForPacket string `yaml:"ip_for_packet"` // 包的ip
- SyslogIP string `yaml:"syslog_ip"` // syslog ip
- TftpIP string `yaml:"tftp_ip"` // tftp ip
- HttpIpxeBinaryURL string `yaml:"http_ipxe_binary_url"` // http ipxe二进制url
- }
- func StartDHCPService(ctx context.Context, log logr.Logger, req request.DHCPService) result.Result {
- dhcp := DhcpConfig{
- Mode: req.Mode,
- BindAddr: "0.0.0.0:67",
- BindInterface: req.BindInterface,
- IpForPacket: ip.DetectPublicIPv4(""),
- SyslogIP: ip.DetectPublicIPv4(""),
- TftpIP: ip.DetectPublicIPv4(":69"),
- }
- var dhcpService = &DHCPService{}
- dhcpService.StartDHCP(ctx, dhcp, log)
- DHCPServiceMap[req.BindInterface] = dhcpService
- req.Status = true
- DHCPServiceInfoMap[req.BindInterface] = req
- return result.Result{
- Status: true,
- Code: code.SUCCESS,
- Msg: "启动成功",
- }
- }
- func StopDHCPService(ctx context.Context, log logr.Logger, req request.DHCPService) result.Result {
- if dhcpService, ok := DHCPServiceMap[req.BindInterface]; ok {
- err := dhcpService.server.Close()
- if err != nil {
- return result.Result{
- Status: false,
- Code: code.SystemException,
- Msg: "关闭失败",
- }
- }
- delete(DHCPServiceMap, req.BindInterface)
- DHCPServiceInfo := DHCPServiceInfoMap[req.BindInterface]
- DHCPServiceInfo.Status = false
- DHCPServiceInfo.Info = "自主关闭"
- DHCPServiceInfoMap[req.BindInterface] = DHCPServiceInfo
- }
- return result.Result{
- Status: true,
- Code: code.SUCCESS,
- Msg: "关闭成功",
- }
- }
- func DeleteDHCPService(ctx context.Context, log logr.Logger, req request.DHCPService) result.Result {
- if dhcpService, ok := DHCPServiceMap[req.BindInterface]; ok {
- _ = dhcpService.server.Close()
- delete(DHCPServiceMap, req.BindInterface)
- delete(DHCPServiceInfoMap, req.BindInterface)
- } else {
- return result.Result{
- Status: false,
- Code: code.SystemException,
- Msg: "删除失败",
- }
- }
- return result.Result{
- Status: true,
- Code: code.SUCCESS,
- Msg: "删除成功",
- }
- }
- type DHCPService struct {
- server *server.DHCP
- }
- func (dhcp *DHCPService) StartDHCP(ctx context.Context, d DhcpConfig, log logr.Logger) {
- dh, err := dhcpHandler(ctx, &d, log)
- if err != nil {
- log.Error(err, "failed to create dhcpServer listener")
- panic(fmt.Errorf("failed to create dhcpServer listener: %w", err))
- }
- log.Info("starting dhcpServer server", "bind_addr", d.BindAddr)
- go func(ctx context.Context) {
- bindAddr, err := netip.ParseAddrPort(d.BindAddr)
- if err != nil {
- panic(fmt.Errorf("invalid tftp address for dhcpServer server: %w", err))
- }
- conn, err := server4.NewIPv4UDPConn(d.BindInterface, net.UDPAddrFromAddrPort(bindAddr))
- if err != nil {
- log.Info("failed to create dhcpServer listener", "error", err)
- panic(err)
- }
- defer conn.Close()
- dhcp.server = &server.DHCP{Logger: log, Conn: conn, Handlers: []server.Handler{dh}}
- err = dhcp.server.Serve(ctx)
- if err != nil {
- delete(DHCPServiceMap, d.BindInterface)
- DHCPServiceInfo := DHCPServiceInfoMap[d.BindInterface]
- DHCPServiceInfo.Status = false
- DHCPServiceInfo.Info = err.Error()
- DHCPServiceInfoMap[d.BindInterface] = DHCPServiceInfo
- }
- }(ctx)
- }
- func (dhcp *DHCPService) StopDHCP(ctx context.Context) {
- dhcp.server.Close()
- }
- func dhcpHandler(ctx context.Context, c *DhcpConfig, log logr.Logger) (server.Handler, error) {
- // 1. create the handler
- // 2. create the macAndIPXE
- // 3. add the macAndIPXE to the handler
- pktIP, err := netip.ParseAddr(c.IpForPacket)
- if err != nil {
- return nil, fmt.Errorf("invalid bind address: %w", err)
- }
- br := backend.NewBackend()
- dh := &proxy.Handler{
- Backend: br,
- IPAddr: pktIP,
- Log: log,
- }
- return dh, nil
- }
|