Browse Source

Merge pull request #2143 from slingamn/emailsending.1

fix #2142
irctest_stable
Shivaram Lingamneni 1 month ago
parent
commit
74fa04c5ea
No account linked to committer's email address
4 changed files with 38 additions and 7 deletions
  1. 4
    0
      default.yaml
  2. 23
    1
      irc/email/email.go
  3. 7
    6
      irc/smtp/smtp.go
  4. 4
    0
      traditional.yaml

+ 4
- 0
default.yaml View File

409
             sender: "admin@my.network"
409
             sender: "admin@my.network"
410
             require-tls: true
410
             require-tls: true
411
             helo-domain: "my.network" # defaults to server name if unset
411
             helo-domain: "my.network" # defaults to server name if unset
412
+            # set to `tcp4` to force sending over IPv4, `tcp6` to force IPv6:
413
+            # protocol: "tcp4"
414
+            # set to force a specific source/local IPv4 or IPv6 address:
415
+            # local-address: "1.2.3.4"
412
             # options to enable DKIM signing of outgoing emails (recommended, but
416
             # options to enable DKIM signing of outgoing emails (recommended, but
413
             # requires creating a DNS entry for the public key):
417
             # requires creating a DNS entry for the public key):
414
             # dkim:
418
             # dkim:

+ 23
- 1
irc/email/email.go View File

75
 	Sender                 string
75
 	Sender                 string
76
 	HeloDomain             string `yaml:"helo-domain"`
76
 	HeloDomain             string `yaml:"helo-domain"`
77
 	RequireTLS             bool   `yaml:"require-tls"`
77
 	RequireTLS             bool   `yaml:"require-tls"`
78
+	Protocol               string `yaml:"protocol"`
79
+	LocalAddress           string `yaml:"local-address"`
80
+	localAddress           net.Addr
78
 	VerifyMessageSubject   string `yaml:"verify-message-subject"`
81
 	VerifyMessageSubject   string `yaml:"verify-message-subject"`
79
 	DKIM                   DKIMConfig
82
 	DKIM                   DKIMConfig
80
 	MTAReal                MTAConfig       `yaml:"mta"`
83
 	MTAReal                MTAConfig       `yaml:"mta"`
159
 		}
162
 		}
160
 	}
163
 	}
161
 
164
 
165
+	config.Protocol = strings.ToLower(config.Protocol)
166
+	if config.Protocol == "" {
167
+		config.Protocol = "tcp"
168
+	}
169
+	if !(config.Protocol == "tcp" || config.Protocol == "tcp4" || config.Protocol == "tcp6") {
170
+		return fmt.Errorf("Invalid protocol for email sending: `%s`", config.Protocol)
171
+	}
172
+
173
+	if config.LocalAddress != "" {
174
+		ipAddr := net.ParseIP(config.LocalAddress)
175
+		if ipAddr == nil {
176
+			return fmt.Errorf("Could not parse local-address for email sending: `%s`", config.LocalAddress)
177
+		}
178
+		config.localAddress = &net.TCPAddr{
179
+			IP:   ipAddr,
180
+			Port: 0,
181
+		}
182
+	}
183
+
162
 	if config.MTAConfig.Server != "" {
184
 	if config.MTAConfig.Server != "" {
163
 		// smarthost, nothing more to validate
185
 		// smarthost, nothing more to validate
164
 		return nil
186
 		return nil
241
 
263
 
242
 	return smtp.SendMail(
264
 	return smtp.SendMail(
243
 		addr, auth, config.HeloDomain, config.Sender, []string{recipient}, msg,
265
 		addr, auth, config.HeloDomain, config.Sender, []string{recipient}, msg,
244
-		config.RequireTLS, implicitTLS, config.Timeout,
266
+		config.RequireTLS, implicitTLS, config.Protocol, config.localAddress, config.Timeout,
245
 	)
267
 	)
246
 }
268
 }

+ 7
- 6
irc/smtp/smtp.go View File

55
 
55
 
56
 // Dial returns a new Client connected to an SMTP server at addr.
56
 // Dial returns a new Client connected to an SMTP server at addr.
57
 // The addr must include a port, as in "mail.example.com:smtp".
57
 // The addr must include a port, as in "mail.example.com:smtp".
58
-func Dial(addr string, timeout time.Duration, implicitTLS bool) (*Client, error) {
58
+func Dial(protocol, addr string, localAddress net.Addr, timeout time.Duration, implicitTLS bool) (*Client, error) {
59
 	var conn net.Conn
59
 	var conn net.Conn
60
 	var err error
60
 	var err error
61
 	dialer := net.Dialer{
61
 	dialer := net.Dialer{
62
-		Timeout: timeout,
62
+		Timeout:   timeout,
63
+		LocalAddr: localAddress,
63
 	}
64
 	}
64
 	start := time.Now()
65
 	start := time.Now()
65
 	if !implicitTLS {
66
 	if !implicitTLS {
66
-		conn, err = dialer.Dial("tcp", addr)
67
+		conn, err = dialer.Dial(protocol, addr)
67
 	} else {
68
 	} else {
68
-		conn, err = tls.DialWithDialer(&dialer, "tcp", addr, nil)
69
+		conn, err = tls.DialWithDialer(&dialer, protocol, addr, nil)
69
 	}
70
 	}
70
 	if err != nil {
71
 	if err != nil {
71
 		return nil, err
72
 		return nil, err
341
 // functionality. Higher-level packages exist outside of the standard
342
 // functionality. Higher-level packages exist outside of the standard
342
 // library.
343
 // library.
343
 // XXX: modified in Ergo to add `requireTLS`, `heloDomain`, and `timeout` arguments
344
 // XXX: modified in Ergo to add `requireTLS`, `heloDomain`, and `timeout` arguments
344
-func SendMail(addr string, a Auth, heloDomain string, from string, to []string, msg []byte, requireTLS, implicitTLS bool, timeout time.Duration) error {
345
+func SendMail(addr string, a Auth, heloDomain string, from string, to []string, msg []byte, requireTLS, implicitTLS bool, protocol string, localAddress net.Addr, timeout time.Duration) error {
345
 	if err := validateLine(from); err != nil {
346
 	if err := validateLine(from); err != nil {
346
 		return err
347
 		return err
347
 	}
348
 	}
350
 			return err
351
 			return err
351
 		}
352
 		}
352
 	}
353
 	}
353
-	c, err := Dial(addr, timeout, implicitTLS)
354
+	c, err := Dial(protocol, addr, localAddress, timeout, implicitTLS)
354
 	if err != nil {
355
 	if err != nil {
355
 		return err
356
 		return err
356
 	}
357
 	}

+ 4
- 0
traditional.yaml View File

381
             sender: "admin@my.network"
381
             sender: "admin@my.network"
382
             require-tls: true
382
             require-tls: true
383
             helo-domain: "my.network" # defaults to server name if unset
383
             helo-domain: "my.network" # defaults to server name if unset
384
+            # set to `tcp4` to force sending over IPv4, `tcp6` to force IPv6:
385
+            # protocol: "tcp4"
386
+            # set to force a specific source/local IPv4 or IPv6 address:
387
+            # local-address: "1.2.3.4"
384
             # options to enable DKIM signing of outgoing emails (recommended, but
388
             # options to enable DKIM signing of outgoing emails (recommended, but
385
             # requires creating a DNS entry for the public key):
389
             # requires creating a DNS entry for the public key):
386
             # dkim:
390
             # dkim:

Loading…
Cancel
Save