code: func (nat *NAT) NewMapping(protocol string, port int) (Mapping, error) {
  	if nat == nil {
  		return nil, fmt.Errorf("no nat available")
  	}
  
  	switch protocol {
  	case "tcp", "udp":
  	default:
  		return nil, fmt.Errorf("invalid protocol: %s", protocol)
  	}
  
  	m := &mapping{
  		intport: port,
  		nat:     nat,
  		proto:   protocol,
  	}
  
  	m.proc = goprocess.WithTeardown(func() error {
  		nat.rmMapping(m)
  		nat.natmu.Lock()
  		defer nat.natmu.Unlock()
  		nat.nat.DeletePortMapping(m.Protocol(), m.InternalPort())
  		return nil
  	})
  
  	nat.addMapping(m)
  
  	m.proc.AddChild(periodic.Every(MappingDuration/3, func(worker goprocess.Process) {
  		nat.establishMapping(m)
  	}))
  
  	// do it once synchronously, so first mapping is done right away, and before exiting,
  	// allowing users -- in the optimistic case -- to use results right after.
  	nat.establishMapping(m)
  	return m, nil
  }
docs: // NewMapping attemps to construct a mapping on protocol and internal port
  // It will also periodically renew the mapping until the returned Mapping
  // -- or its parent NAT -- is Closed.
  //
  // May not succeed, and mappings may change over time;
  // NAT devices may not respect our port requests, and even lie.
  // Clients should not store the mapped results, but rather always
  // poll our object for the latest mappings.