@@ -12,6 +12,7 @@ import (
1212	"strconv" 
1313	"strings" 
1414	"sync" 
15+ 	"syscall" 
1516	"time" 
1617	"unicode" 
1718
@@ -377,6 +378,17 @@ const (
377378	comprBufferSize       =  64  *  1024  // 64 Kb 
378379)
379380
381+ /* 
382+ Checks if this error indicates that a chosen source port/address cannot be bound. 
383+ 
384+ This is caused by one of the following: 
385+   - The source address is already used by another socket, 
386+   - The source address is reserved and the process does not have sufficient privileges to use it. 
387+ */ 
388+ func  isAddrUnavailableForUseErr (err  error ) bool  {
389+ 	return  errors .Is (err , syscall .EADDRINUSE ) ||  errors .Is (err , syscall .EPERM )
390+ }
391+ 
380392// OpenShardConn opens connection mapped to a specific shard on Scylla node. 
381393func  OpenShardConn (ctx  context.Context , addr  string , si  ShardInfo , cfg  ConnConfig ) (* Conn , error ) {
382394	it  :=  ShardPortIterator (si )
@@ -385,12 +397,16 @@ func OpenShardConn(ctx context.Context, addr string, si ShardInfo, cfg ConnConfi
385397		conn , err  :=  OpenLocalPortConn (ctx , addr , it (), cfg )
386398		if  err  !=  nil  {
387399			cfg .Logger .Infof ("%s dial error: %s (try %d/%d)" , addr , err , i , maxTries )
388- 			continue 
400+ 			if  isAddrUnavailableForUseErr (err ) {
401+ 				continue 
402+ 			}
403+ 
404+ 			return  nil , fmt .Errorf ("failed to open connection to shard: %w" , err )
389405		}
390406		return  conn , nil 
391407	}
392408
393- 	return  nil , fmt .Errorf ("failed to open connection on shard %d: all local ports are busy " , si .Shard )
409+ 	return  nil , fmt .Errorf ("failed to open connection on shard %d: all local ports are unavailable for use " , si .Shard )
394410}
395411
396412// OpenLocalPortConn opens connection on a given local port. 
0 commit comments