Skip to content

Commit

Permalink
Make rawQuery timeout handling more thread-safe
Browse files Browse the repository at this point in the history
Previous an `elapsed` duration was saved on the `Client` object and was updated multiple times on each call to `rawQuery`. This could lead to a race condition when calling `whois.Whois(...)` in parallel, where one thread halfway through the function has a non-zero elapsed duration and another thread entering the function sets it to 0. This removes the `elapsed` field on the `Client` object and uses a local variable instead, which avoids the aforementioned issue.
  • Loading branch information
ugexe authored May 12, 2024
1 parent 9dd719a commit 027c73e
Showing 1 changed file with 4 additions and 8 deletions.
12 changes: 4 additions & 8 deletions whois.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ var DefaultClient = NewClient()
type Client struct {
dialer proxy.Dialer
timeout time.Duration
elapsed time.Duration
disableStats bool
disableReferral bool
}
Expand Down Expand Up @@ -175,7 +174,6 @@ func (c *Client) Whois(domain string, servers ...string) (result string, err err

// rawQuery do raw query to the server
func (c *Client) rawQuery(domain, server, port string) (string, error) {
c.elapsed = 0
start := time.Now()

if server == "whois.arin.net" {
Expand All @@ -202,24 +200,22 @@ func (c *Client) rawQuery(domain, server, port string) (string, error) {
}

defer conn.Close()
c.elapsed = time.Since(start)
elapsed := time.Since(start)

_ = conn.SetWriteDeadline(time.Now().Add(c.timeout - c.elapsed))
_ = conn.SetWriteDeadline(time.Now().Add(c.timeout - elapsed))
_, err = conn.Write([]byte(domain + "\r\n"))
if err != nil {
return "", fmt.Errorf("whois: send to whois server failed: %w", err)
}

c.elapsed = time.Since(start)
elapsed = time.Since(start)

_ = conn.SetReadDeadline(time.Now().Add(c.timeout - c.elapsed))
_ = conn.SetReadDeadline(time.Now().Add(c.timeout - elapsed))
buffer, err := io.ReadAll(conn)
if err != nil {
return "", fmt.Errorf("whois: read from whois server failed: %w", err)
}

c.elapsed = time.Since(start)

return string(buffer), nil
}

Expand Down

0 comments on commit 027c73e

Please sign in to comment.