func (inv *Inventory) UnmarshalNbt(tag *nbt.Compound) (err os.Error) { itemList, ok := tag.Lookup("Items").(*nbt.List) if !ok { return os.NewError("bad inventory - not a list") } for _, slotTagITag := range itemList.Value { slotTag, ok := slotTagITag.(*nbt.Compound) if !ok { return os.NewError("inventory slot not a compound") } var slotIdTag *nbt.Byte if slotIdTag, ok = slotTag.Lookup("Slot").(*nbt.Byte); !ok { return os.NewError("Slot ID not a byte") } slotId := types.SlotId(slotIdTag.Value) if err = inv.SlotUnmarshalNbt(slotTag, slotId); err != nil { return } } return nil }
func passwordfromfile(hostname string, port int, dbname string, username string) (string, os.Error) { var sport string var lhostname string if dbname == "" { return "", nil } if username == "" { return "", nil } if hostname == "" { lhostname = "localhost" } else { lhostname = hostname } if port == 0 { sport = "5432" } else { sport = fmt.Sprintf("%d", port) } pgfile := getpgpassfilename() fileinfo, err := os.Stat(pgfile) if err != nil { err := os.NewError(fmt.Sprintf("WARNING: password file \"%s\" is not a plain file\n", pgfile)) return "", err } if (fileinfo.Mode & 077) != 0 { err := os.NewError(fmt.Sprintf("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less", pgfile)) return "", err } fp, err := os.Open(pgfile) if err != nil { err := os.NewError(fmt.Sprintf("Problem opening pgpass file \"%s\"", pgfile)) return "", err } br := bufio.NewReader(fp) for { line, ok := br.ReadString('\n') if ok == os.EOF { return "", nil } // Now, split the line into pieces // hostname:port:database:username:password // and * matches anything pieces := strings.Split(line, ":") phost := pieces[0] pport := pieces[1] pdb := pieces[2] puser := pieces[3] ppass := pieces[4] if (phost == lhostname || phost == "*") && (pport == "*" || pport == sport) && (pdb == "*" || pdb == dbname) && (puser == "*" || puser == username) { return ppass, nil } } return "", nil }
func decodeSecureCookie(value string) (user string, session string, err os.Error) { parts := strings.Split(value, "|", 3) if len(parts) != 3 { err = os.NewError("Malformed cookie value") return } val := parts[0] timestamp := parts[1] sig := parts[2] // Check signature if getCookieSig([]byte(val), timestamp) != sig { return "", "", os.NewError("Signature error, cookie is invalid") } // Check time stamp ts, _ := strconv.Atoi64(timestamp) if ts+maxAge < time.UTC().Seconds() { return "", "", os.NewError("Cookie is outdated") } buf := bytes.NewBufferString(val) encoder := base64.NewDecoder(base64.StdEncoding, buf) res, _ := ioutil.ReadAll(encoder) str := string(res) lst := strings.Split(str, "!", -1) if len(lst) != 2 { return "", "", os.NewError("Missing !") } return lst[0], lst[1], nil }
func LoadBlockDefs(reader io.Reader) (blocks BlockTypeList, err os.Error) { blocksStr := make(map[string]blockDef) decoder := json.NewDecoder(reader) err = decoder.Decode(&blocksStr) // Find the max block ID so we allocate the correct amount of memory. Also // range check the IDs. maxId := 0 for idStr := range blocksStr { var id int id, err = strconv.Atoi(idStr) if err != nil { return } if id < BlockIdMin || id > BlockIdMax { err = os.NewError(fmt.Sprintf( "Encountered block type with ID %d which is outside the range"+ "%d <= N <= %d", id, BlockIdMin, BlockIdMax)) return } if id > maxId { maxId = id } } // Convert map string keys to ints. blocks = make(BlockTypeList, maxId+1) for idStr, blockDef := range blocksStr { var id int id, _ = strconv.Atoi(idStr) if blocks[id].defined { err = os.NewError(fmt.Sprintf( "Block ID %d defined more than once.", id)) } var block *BlockType block, err = blockDef.LoadBlockType() if err != nil { return } block.id = BlockId(id) block.defined = true blocks[id] = *block } // Put VoidAspect in any undefined blocks rather than leave it nil, and also // set id on each block type. for id := range blocks { block := &blocks[id] block.id = BlockId(id) if !block.defined { void := makeVoidAspect() block.Aspect = void void.setAttrs(&block.BlockAttrs) } } return }
func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, err os.Error) { // Grab the request header. req = server.getRequest() err = codec.ReadRequestHeader(req) if err != nil { req = nil if err == os.EOF || err == io.ErrUnexpectedEOF { return } err = os.NewError("rpc: server cannot decode request: " + err.String()) return } serviceMethod := strings.Split(req.ServiceMethod, ".") if len(serviceMethod) != 2 { err = os.NewError("rpc: service/method request ill-formed: " + req.ServiceMethod) return } // Look up the request. server.mu.Lock() service = server.serviceMap[serviceMethod[0]] server.mu.Unlock() if service == nil { err = os.NewError("rpc: can't find service " + req.ServiceMethod) return } mtype = service.method[serviceMethod[1]] if mtype == nil { err = os.NewError("rpc: can't find method " + req.ServiceMethod) } return }
// Expand expands a shortened url to long url. // It returns the orgin url and nil if success, or empty string // and an os.Error when failed. func (req *Googl) Expand(url string) (string, os.Error) { res, err := req.get(url) if err != nil { return "", err } var temp map[string]string if err = json.Unmarshal([]byte(res), &temp); err != nil { return "", os.Error(err) } if _, ok := temp["code"]; ok { return "", os.NewError(temp["message"]) } if status, _ := temp["status"]; "OK" != status { return "", os.NewError(status) } url, ok := temp["longUrl"] if !ok { return "", os.NewError("Invalid response") } return url, nil }
func writeToContainer(data [][]byte, val reflect.Value) os.Error { switch v := val; v.Kind() { case reflect.Ptr: return writeToContainer(data, reflect.Indirect(v)) case reflect.Interface: return writeToContainer(data, v.Elem()) case reflect.Map: if v.Type().Key().Kind() != reflect.String { return os.NewError("Invalid map type") } elemtype := v.Type().Elem() for i := 0; i < len(data)/2; i++ { mk := reflect.ValueOf(string(data[i*2])) mv := reflect.New(elemtype).Elem() writeTo(data[i*2+1], mv) v.SetMapIndex(mk, mv) } case reflect.Struct: for i := 0; i < len(data)/2; i++ { name := string(data[i*2]) field := v.FieldByName(name) if !field.IsValid() { continue } writeTo(data[i*2+1], field) } default: return os.NewError("Invalid container type") } return nil }
func (m *Master) MapChunkToFile(args *sfs.MapChunkToFileArgs, ret *sfs.MapChunkToFileReturn) os.Error { file, ok := QueryFile(args.Name) if !ok { log.Printf("master: MapChunkToFile: File %s does not exist\n", args.Name) return os.NewError("File does not exist! Herp derp") } log.Printf("master: MapChunkToFile: ChunkID: %d Offset %d nservers: %d\n", args.Chunk.ChunkID, args.Offset, len(args.Chunk.Servers)) var newChunk chunk newChunk.chunkID = args.Chunk.ChunkID newChunk.servers = new(vector.Vector) for i := 0; i < len(args.Chunk.Servers); i++ { newChunk.servers.Push(addrToServerMap[args.Chunk.Servers[i].String()]) } _, err := file.MapChunk(args.Offset, &newChunk) if err != nil { return os.NewError("Could not add chunk! Ruh roh") } return nil }
func (self *LinkHandler) SetLinkState(flag link.Flags) (err os.Error) { var qry *netlink.Message if hdr, ok := self.cache.Header.(*link.Header); ok { // While rtnetlink(7) says changes should always be IFF_QUERY, it has some // behaviours that are undocumented - like limiting actions on SETLINK's to // specific FLAGs. hdr = link.NewHeader(hdr.InterfaceFamily(), hdr.InterfaceType(), hdr.InterfaceIndex(), flag&link.IFF_UP, link.IFF_UP) msg := rtnetlink.Message{Header: hdr} qry, err = netlink.NewMessage(rtnetlink.RTM_SETLINK, netlink.NLM_F_ACK|netlink.NLM_F_REQUEST, msg, 4) } else { err = os.NewError("Cant set link flags (invalid cache)") } if err != nil { return } mch, err := self.h.Query(*qry, 1, 4) if err == nil { for m := range mch { switch m.Header.MessageType() { case netlink.NLMSG_ERROR: emsg := &netlink.Error{} err = emsg.UnmarshalNetlink(m.Body, 4) if err == nil && emsg.Code() != 0 { err = emsg } default: err = os.NewError("Unexpected netlink message") log.Printf("NetlinkError: %v", err) } } close(mch) } return }
// pkgConfig runs pkg-config and extracts --libs and --cflags information // for packages. func pkgConfig(packages []string) (cflags, ldflags []string, err os.Error) { for _, name := range packages { if len(name) == 0 || name[0] == '-' { return nil, nil, os.NewError(fmt.Sprintf("invalid name: %q", name)) } } args := append([]string{"pkg-config", "--cflags"}, packages...) stdout, stderr, ok := run(nil, args) if !ok { os.Stderr.Write(stderr) return nil, nil, os.NewError("pkg-config failed") } cflags, err = splitQuoted(string(stdout)) if err != nil { return } args = append([]string{"pkg-config", "--libs"}, packages...) stdout, stderr, ok = run(nil, args) if !ok { os.Stderr.Write(stderr) return nil, nil, os.NewError("pkg-config failed") } ldflags, err = splitQuoted(string(stdout)) return }
// Write Bind Response PDU func (pdu *PDUBindResp) write(w *bufio.Writer) (err os.Error) { // Write Header err = pdu.Header.write(w) if err != nil { err = os.NewError("Bind Response: Error writing Header") return } // Create byte array the size of the PDU p := make([]byte, pdu.Header.CmdLength-pdu.OptionalLen-16) pos := 0 // Copy system id if len(pdu.SystemId) > 0 { copy(p[pos:len(pdu.SystemId)], []byte(pdu.SystemId)) pos += len(pdu.SystemId) } pos++ // Null terminator // Write to buffer _, err = w.Write(p) if err != nil { err = os.NewError("Bind Response: Error writing to buffer") return } // Flush write buffer err = w.Flush() if err != nil { err = os.NewError("Bind Response: Error flushing write buffer") } // Optional params err = pdu.writeOptional(w) if err != nil { err = os.NewError("Bind Response: Error writing optional params") } return }
// readDoc reads a single document from the connection. func (c *connection) readDoc(alloc bool) ([]byte, os.Error) { if c.responseLen < 4 { return nil, c.fatal(os.NewError("mongo: incomplete document in message")) } b, err := c.br.Peek(4) if err != nil { return nil, c.fatal(err) } n := int(wire.Uint32(b)) if c.responseLen < n { return nil, c.fatal(os.NewError("mongo: incomplete document in message")) } var p []byte if n > len(c.buf) || alloc { p = make([]byte, n) } else { p = c.buf[:n] } _, err = io.ReadFull(c.br, p) if err != nil { return nil, c.fatal(err) } c.responseLen -= n c.responseCount -= 1 if c.responseCount == 0 { c.cursor = nil if c.responseLen != 0 { return nil, c.fatal(os.NewError("mongo: unexpected data in message.")) } } return p, nil }
func (me *WorkerDaemon) getMirror(rpcConn, revConn net.Conn, reserveCount int) (*Mirror, os.Error) { if reserveCount <= 0 { return nil, os.NewError("must ask positive jobcount") } me.mirrorMapMutex.Lock() defer me.mirrorMapMutex.Unlock() used := 0 for _, v := range me.mirrorMap { used += v.maxJobCount } remaining := me.maxJobCount - used if remaining <= 0 { return nil, os.NewError("no processes available") } if remaining < reserveCount { reserveCount = remaining } mirror := NewMirror(me, rpcConn, revConn) mirror.maxJobCount = reserveCount key := fmt.Sprintf("%v", rpcConn.RemoteAddr()) me.mirrorMap[key] = mirror mirror.key = key return mirror, nil }
func ExecuteOperation(input interface{}, op Operation) (output interface{}, err os.Error) { switch op.Kind { case NoOp: return input, nil case StringOp: if input == nil { input = NewSimpleText("") } text, ok := input.(Text) if !ok { err = os.NewError("Type mismatch: Not a string") return } err = executeString(text, op.Operations) output = text case ArrayOp: // TODO case ObjectOp: obj, ok := input.(Object) if !ok { err = os.NewError("Type mismatch: Not an object") return } err = executeObject(obj, op.Operations) output = obj default: err = os.NewError("Operation not allowed in this place") } return }
func (c *attrCmd) RunCommand(up *Uploader, args []string) os.Error { if len(args) != 3 { return os.NewError("Attr takes 3 args: <permanode> <attr> <value>") } permanode, attr, value := args[0], args[1], args[2] var err os.Error pn := blobref.Parse(permanode) if pn == nil { return fmt.Errorf("Error parsing blobref %q", permanode) } m := schema.NewSetAttributeClaim(pn, attr, value) if c.add { if c.del { return os.NewError("Add and del options are exclusive") } m = schema.NewAddAttributeClaim(pn, attr, value) } else { // TODO: del, which can make <value> be optional if c.del { return os.NewError("del not yet implemented") } } put, err := up.UploadAndSignMap(m) handleResult(m["claimType"].(string), put, err) return nil }
func enc(val reflect.Value, typ reflect.Type, buffer *bytes.Buffer, req bool) (encoded bool, err os.Error) { switch typ.(type) { case *reflect.PtrType: // log.Println("pointer") pt := typ.(*reflect.PtrType).Elem() pv := reflect.Indirect(val) // log.Println("Type is: ", pt.Name()) if pv == nil { if !req { return false, nil } else { return false, os.NewError("Required field is nil") } } return enc(pv, pt, buffer, req) case *reflect.BoolType: if val.(*reflect.BoolValue).Get() { buffer.WriteString("true") } else { buffer.WriteString("false") } case *reflect.IntType: buffer.WriteString(strconv.Itoa64(val.(*reflect.IntValue).Get())) case *reflect.UintType: buffer.WriteString(strconv.Uitoa64(val.(*reflect.UintValue).Get())) case *reflect.StringType: buffer.WriteString("\"") // TODO: encode buffer.WriteString(val.(*reflect.StringValue).Get()) buffer.WriteString("\"") case *reflect.FloatType: buffer.WriteString(strconv.Ftoa64(val.(*reflect.FloatValue).Get(), 'e', -1)) case *reflect.StructType: enc_struct(val.(*reflect.StructValue), typ.(*reflect.StructType), buffer) case *reflect.SliceType: st := typ.(*reflect.SliceType).Elem() sv := val.(*reflect.SliceValue) if sv.IsNil() { if req { return false, os.NewError("Required field is nil") } else { return false, nil } } buffer.WriteString("[") for i := 0; i < sv.Len(); i++ { if i > 0 { buffer.WriteString(",") } _, err := enc(sv.Elem(i), st, buffer, true) if err != nil { return false, err } } buffer.WriteString("]") default: return false, os.NewError("Unsupported type") } return true, nil }
func (p *Protocol) DecodeIPv4() os.Error { ip := new(IPv4Fix) err := binary.Read(p.reader, binary.BigEndian, ip) if err != nil { return os.NewError("read ip header - " + err.String()) } ver := ip.VerHL >> 4 if ver != 4 { return os.NewError("not ip v4") } var options []byte const MinLen = 20 offset := uint16((ip.VerHL & 0x0F) * 4) if offset < MinLen || ip.Length < offset { return os.NewError("bad ip v4 length") } if offset > MinLen { options = make([]byte, offset-MinLen) _, err := io.ReadFull(p.reader, options) if err != nil { return os.NewError("read ip options - " + err.String()) } } p.TransType = uint(ip.Protocol) p.Length = uint(ip.Length - offset) p.Net = &IPv4{ip, options} return nil }
func Import(uid, nick, user, host, ip, hops, ts, name string) os.Error { userMutex.Lock() defer userMutex.Unlock() if _, ok := userMap[uid]; ok { return os.NewError("UID collision") } lownick := parser.ToLower(nick) if _, ok := userNicks[lownick]; ok { return os.NewError("NICK collision") } its, _ := strconv.Atoi64(ts) u := &User{ mutex: new(sync.RWMutex), ts: its, id: uid, user: user, nick: nick, name: name, utyp: RegisteredAsUser, } userMap[uid] = u userNicks[lownick] = uid return nil }
// Project like Expand above. // But this will return with short URL's analytics as a // map[string]interface{} type. func (req *Googl) Project(url, proj string) (map[string]interface{}, os.Error) { proj = strings.ToUpper(proj) if "FULL" != proj && "ANALYTICS_CLICKS" != proj && "ANALYTICS_TOP_STRINGS" != proj { return nil, os.EINVAL } res, err := req.get(url, map[string]string{"projection": proj}) if err != nil { return nil, err } var temp map[string]interface{} if err = json.Unmarshal([]byte(res), &temp); err != nil { return nil, os.Error(err) } if _, ok := temp["code"]; ok { msg, _ := temp["message"].(string) return nil, os.NewError(msg) } if status, _ := temp["status"]; "OK" != status { msg, _ := status.(string) return nil, os.NewError(msg) } return temp, nil }
func createShader(name string, shaderType int) (gl.Shader, os.Error) { data, err := fileRead(name) if err != nil { return 0, err } if len(data) == 0 { return 0, os.NewError("No shader code.") } var shader gl.Shader switch shaderType { case VertexShaderType: shader = gl.CreateShader(gl.VERTEX_SHADER) case FragmentShaderType: shader = gl.CreateShader(gl.FRAGMENT_SHADER) default: return 0, os.NewError("Unknown ShaderType.") } shader.Source(data) shader.Compile() // Similar to print_log in the C code example infoLog := shader.GetInfoLog() if len(infoLog) != 0 { shader.Delete() return 0, err } errNum := gl.GetError() if errNum != 0 { return 0, os.NewError(fmt.Sprintf("Error code: %d", errNum)) } return shader, nil }
func readBulkData(conn *bufio.Reader, len int64) ([]byte, os.Error) { buff := make([]byte, len) _, e := io.ReadFull(conn, buff) if e != nil { return nil, NewErrorWithCause(SYSTEM_ERR, "Error while attempting read of bulkdata", e) } // fmt.Println ("Read ", n, " bytes. data: ", buff); crb, e1 := conn.ReadByte() if e1 != nil { return nil, os.NewError("Error while attempting read of bulkdata terminal CR:" + e1.String()) } if crb != CR_BYTE { return nil, os.NewError("<BUG> bulkdata terminal was not CR as expected") } lfb, e2 := conn.ReadByte() if e2 != nil { return nil, os.NewError("Error while attempting read of bulkdata terminal LF:" + e2.String()) } if lfb != LF_BYTE { return nil, os.NewError("<BUG> bulkdata terminal was not LF as expected.") } return buff, nil }
// For a given query, which is either a single identifier or a qualified // identifier, Lookup returns a LookupResult, and a list of alternative // spellings, if any. If the query syntax is wrong, an error is reported. func (x *Index) Lookup(query string) (match *LookupResult, alt *AltWords, err os.Error) { ss := strings.Split(query, ".", -1) // check query syntax for _, s := range ss { if !isIdentifier(s) { err = os.NewError("all query parts must be identifiers") return } } switch len(ss) { case 1: match, alt = x.LookupWord(ss[0]) case 2: pakname := ss[0] match, alt = x.LookupWord(ss[1]) if match != nil { // found a match - filter by package name decls := match.Decls.filter(pakname) others := match.Others.filter(pakname) match = &LookupResult{decls, others} } default: err = os.NewError("query is not a (qualified) identifier") } return }
func getFuseConn(local *os.File) (f *os.File, err os.Error) { var data [4]byte control := make([]byte, 4*256) // n, oobn, recvflags, from, errno - todo: error checking. _, oobn, _, _, errno := syscall.Recvmsg( local.Fd(), data[:], control[:], 0) if errno != 0 { return } message := *(*syscall.Cmsghdr)(unsafe.Pointer(&control[0])) fd := *(*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(&control[0])) + syscall.SizeofCmsghdr)) if message.Type != 1 { err = os.NewError(fmt.Sprintf("getFuseConn: recvmsg returned wrong control type: %d", message.Type)) return } if oobn <= syscall.SizeofCmsghdr { err = os.NewError(fmt.Sprintf("getFuseConn: too short control message. Length: %d", oobn)) return } if fd < 0 { err = os.NewError(fmt.Sprintf("getFuseConn: fd < 0: %d", fd)) return } f = os.NewFile(int(fd), "<fuseConnection>") return }
func (item *Item) UnmarshalNbt(tag *nbt.Compound) (err os.Error) { if err = item.PointObject.UnmarshalNbt(tag); err != nil { return } itemInfo, ok := tag.Lookup("Item").(*nbt.Compound) if !ok { return os.NewError("bad item data") } // Grab the basic item data id, idOk := itemInfo.Lookup("id").(*nbt.Short) count, countOk := itemInfo.Lookup("Count").(*nbt.Byte) data, dataOk := itemInfo.Lookup("Damage").(*nbt.Short) if !idOk || !countOk || !dataOk { return os.NewError("bad item data") } item.Slot = Slot{ ItemTypeId: ItemTypeId(id.Value), Count: ItemCount(count.Value), Data: ItemData(data.Value), } return nil }
// parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80). func parsePlan9Addr(s string) (ip IP, iport int, err os.Error) { var ( addr IP p, i int ok bool ) addr = IPv4zero // address contains port only i = byteIndex(s, '!') if i >= 0 { addr = ParseIP(s[:i]) if addr == nil { err = os.NewError("net: parsing IP failed") goto Error } } p, _, ok = dtoi(s[i+1:], 0) if !ok { err = os.NewError("net: parsing port failed") goto Error } if p < 0 || p > 0xFFFF { err = &AddrError{"invalid port", string(p)} goto Error } return addr, p, nil Error: return nil, 0, err }
func (p *StdoutProcessor) ParseOneStatusMessage() (*StatusMessage, os.Error) { if HasNewLineCR(p.readAhead) { chunk, rest := ExtractFirstToken(p.readAhead) p.readAhead = rest return NewStatusMessage(chunk), nil } else { // Need to read more data from in. But first check savedError. if p.savedError != nil { return nil, p.savedError } n, e := (*(p.in)).Read(p.data) if n > 0 { p.readAhead = p.readAhead + string(p.data[0:n]) } if HasNewLineCR(p.readAhead) { p.savedError = e chunk, rest := ExtractFirstToken(p.readAhead) p.readAhead = rest return NewStatusMessage(chunk), nil } if e != nil { return nil, e } return nil, os.NewError("No more data") } return nil, os.NewError("should not get here") }
// Create the reader. func NewSmlReader(reader io.Reader) *SmlReader { // Init the reader. sr := &SmlReader{ reader: bufio.NewReader(reader), index: -1, } node, ctrl := sr.readNode() switch ctrl { case ctrlClose: sr.root = node sr.error = nil case ctrlEOF: msg := fmt.Sprintf("eof too early at index %v", sr.index) sr.error = os.NewError(msg) case ctrlInvalid: msg := fmt.Sprintf("invalid rune at index %v", sr.index) sr.error = os.NewError(msg) } return sr }
func init() { ERR_MUST_SPECIFY_ID = os.NewError("Must Specify Id") ERR_INVALID_ID = os.NewError("Invalid Id") ERR_INVALID_EMAIL_ADDRESS = os.NewError("Invalid Email Address") ERR_REQUIRED_FIELD = os.NewError("Required Field") ERR_INVALID_FORMAT = os.NewError("Invalid Format") }
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, os.Error) { preMasterSecret := make([]byte, 48) _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) if err != nil { return nil, err } if len(ckx.ciphertext) < 2 { return nil, os.NewError("bad ClientKeyExchange") } ciphertext := ckx.ciphertext if version != versionSSL30 { ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) if ciphertextLen != len(ckx.ciphertext)-2 { return nil, os.NewError("bad ClientKeyExchange") } ciphertext = ckx.ciphertext[2:] } err = rsa.DecryptPKCS1v15SessionKey(config.rand(), config.Certificates[0].PrivateKey, ciphertext, preMasterSecret) if err != nil { return nil, err } // We don't check the version number in the premaster secret. For one, // by checking it, we would leak information about the validity of the // encrypted pre-master secret. Secondly, it provides only a small // benefit against a downgrade attack and some implementations send the // wrong version anyway. See the discussion at the end of section // 7.4.7.1 of RFC 4346. return preMasterSecret, nil }
// NewPool returns a new Pool that will create new connections on demand // using connectParams, up to a maximum of maxConns outstanding connections. // An error is returned if an initial connection cannot be created. // Connections that have been idle for idleTimeout seconds will be automatically // closed. func NewPool(connectParams string, maxConns, idleTimeout int) (p *Pool, err os.Error) { if maxConns < 1 { return nil, os.NewError("maxConns must be >= 1") } if idleTimeout < 5 { return nil, os.NewError("idleTimeout must be >= 5") } // Create initial connection to verify connectParams will work. c, err := Connect(connectParams) if err != nil { return } p = &Pool{ &pool{ params: connectParams, conns: list.New(), max: maxConns, n: 1, cond: sync.NewCond(new(sync.Mutex)), timeout: int64(idleTimeout), }, } p.conns.PushFront(poolConn{c, time.Seconds()}) go timeoutCloser(p.pool) runtime.SetFinalizer(p, (*Pool).close) return }