| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | package p2p | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | 	errMagicTokenMismatch = iota | 
					
						
							|  |  |  | 	errRead | 
					
						
							|  |  |  | 	errWrite | 
					
						
							|  |  |  | 	errMisc | 
					
						
							|  |  |  | 	errInvalidMsgCode | 
					
						
							|  |  |  | 	errInvalidMsg | 
					
						
							|  |  |  | 	errP2PVersionMismatch | 
					
						
							|  |  |  | 	errPubkeyMissing | 
					
						
							|  |  |  | 	errPubkeyInvalid | 
					
						
							|  |  |  | 	errPubkeyForbidden | 
					
						
							|  |  |  | 	errProtocolBreach | 
					
						
							|  |  |  | 	errPingTimeout | 
					
						
							|  |  |  | 	errInvalidNetworkId | 
					
						
							|  |  |  | 	errInvalidProtocolVersion | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | var errorToString = map[int]string{ | 
					
						
							|  |  |  | 	errMagicTokenMismatch:     "Magic token mismatch", | 
					
						
							|  |  |  | 	errRead:                   "Read error", | 
					
						
							|  |  |  | 	errWrite:                  "Write error", | 
					
						
							|  |  |  | 	errMisc:                   "Misc error", | 
					
						
							|  |  |  | 	errInvalidMsgCode:         "Invalid message code", | 
					
						
							|  |  |  | 	errInvalidMsg:             "Invalid message", | 
					
						
							|  |  |  | 	errP2PVersionMismatch:     "P2P Version Mismatch", | 
					
						
							|  |  |  | 	errPubkeyMissing:          "Public key missing", | 
					
						
							|  |  |  | 	errPubkeyInvalid:          "Public key invalid", | 
					
						
							|  |  |  | 	errPubkeyForbidden:        "Public key forbidden", | 
					
						
							|  |  |  | 	errProtocolBreach:         "Protocol Breach", | 
					
						
							|  |  |  | 	errPingTimeout:            "Ping timeout", | 
					
						
							|  |  |  | 	errInvalidNetworkId:       "Invalid network id", | 
					
						
							|  |  |  | 	errInvalidProtocolVersion: "Invalid protocol version", | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | type peerError struct { | 
					
						
							|  |  |  | 	Code    int | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | 	message string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | func newPeerError(code int, format string, v ...interface{}) *peerError { | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | 	desc, ok := errorToString[code] | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		panic("invalid error code") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | 	err := &peerError{code, desc} | 
					
						
							|  |  |  | 	if format != "" { | 
					
						
							|  |  |  | 		err.message += ": " + fmt.Sprintf(format, v...) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | func (self *peerError) Error() string { | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | 	return self.message | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | type DiscReason byte | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	DiscRequested           DiscReason = 0x00 | 
					
						
							|  |  |  | 	DiscNetworkError                   = 0x01 | 
					
						
							|  |  |  | 	DiscProtocolError                  = 0x02 | 
					
						
							|  |  |  | 	DiscUselessPeer                    = 0x03 | 
					
						
							|  |  |  | 	DiscTooManyPeers                   = 0x04 | 
					
						
							|  |  |  | 	DiscAlreadyConnected               = 0x05 | 
					
						
							|  |  |  | 	DiscIncompatibleVersion            = 0x06 | 
					
						
							|  |  |  | 	DiscInvalidIdentity                = 0x07 | 
					
						
							|  |  |  | 	DiscQuitting                       = 0x08 | 
					
						
							|  |  |  | 	DiscUnexpectedIdentity             = 0x09 | 
					
						
							|  |  |  | 	DiscSelf                           = 0x0a | 
					
						
							|  |  |  | 	DiscReadTimeout                    = 0x0b | 
					
						
							|  |  |  | 	DiscSubprotocolError               = 0x10 | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var discReasonToString = [DiscSubprotocolError + 1]string{ | 
					
						
							|  |  |  | 	DiscRequested:           "Disconnect requested", | 
					
						
							|  |  |  | 	DiscNetworkError:        "Network error", | 
					
						
							|  |  |  | 	DiscProtocolError:       "Breach of protocol", | 
					
						
							|  |  |  | 	DiscUselessPeer:         "Useless peer", | 
					
						
							|  |  |  | 	DiscTooManyPeers:        "Too many peers", | 
					
						
							|  |  |  | 	DiscAlreadyConnected:    "Already connected", | 
					
						
							|  |  |  | 	DiscIncompatibleVersion: "Incompatible P2P protocol version", | 
					
						
							|  |  |  | 	DiscInvalidIdentity:     "Invalid node identity", | 
					
						
							|  |  |  | 	DiscQuitting:            "Client quitting", | 
					
						
							|  |  |  | 	DiscUnexpectedIdentity:  "Unexpected identity", | 
					
						
							|  |  |  | 	DiscSelf:                "Connected to self", | 
					
						
							|  |  |  | 	DiscReadTimeout:         "Read timeout", | 
					
						
							|  |  |  | 	DiscSubprotocolError:    "Subprotocol error", | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d DiscReason) String() string { | 
					
						
							|  |  |  | 	if len(discReasonToString) < int(d) { | 
					
						
							|  |  |  | 		return fmt.Sprintf("Unknown Reason(%d)", d) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return discReasonToString[d] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 11:58:39 +01:00
										 |  |  | type discRequestedError DiscReason | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (err discRequestedError) Error() string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("disconnect requested: %v", DiscReason(err)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | func discReasonForError(err error) DiscReason { | 
					
						
							| 
									
										
										
										
											2014-12-12 11:58:39 +01:00
										 |  |  | 	if reason, ok := err.(discRequestedError); ok { | 
					
						
							|  |  |  | 		return DiscReason(reason) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-21 21:48:49 +01:00
										 |  |  | 	peerError, ok := err.(*peerError) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return DiscSubprotocolError | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	switch peerError.Code { | 
					
						
							|  |  |  | 	case errP2PVersionMismatch: | 
					
						
							|  |  |  | 		return DiscIncompatibleVersion | 
					
						
							|  |  |  | 	case errPubkeyMissing, errPubkeyInvalid: | 
					
						
							|  |  |  | 		return DiscInvalidIdentity | 
					
						
							|  |  |  | 	case errPubkeyForbidden: | 
					
						
							|  |  |  | 		return DiscUselessPeer | 
					
						
							|  |  |  | 	case errInvalidMsgCode, errMagicTokenMismatch, errProtocolBreach: | 
					
						
							|  |  |  | 		return DiscProtocolError | 
					
						
							|  |  |  | 	case errPingTimeout: | 
					
						
							|  |  |  | 		return DiscReadTimeout | 
					
						
							|  |  |  | 	case errRead, errWrite, errMisc: | 
					
						
							|  |  |  | 		return DiscNetworkError | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return DiscSubprotocolError | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-23 16:57:54 +01:00
										 |  |  | } |