diff --git a/contrib/fb303/TClientInfo.cpp b/contrib/fb303/TClientInfo.cpp
new file mode 100644
index 0000000..d093017
--- /dev/null
+++ b/contrib/fb303/TClientInfo.cpp
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <server/TClientInfo.h>
+
+namespace apache { namespace thrift { namespace server {
+
+using namespace apache::thrift;
+using namespace apache::thrift::transport;
+
+TClientInfoConnection::TClientInfoConnection() {
+  call_[kNameLen - 1] = '\0';    // insure NUL terminator is there
+  eraseAddr();
+  eraseCall();
+}
+
+void TClientInfoConnection::recordAddr(const sockaddr* addr) {
+  eraseAddr();
+  initTime();
+  ncalls_ = 0;
+  if (addr != NULL) {
+    if (addr->sa_family == AF_INET) {
+      memcpy((void*)&addr_.ipv4, (const void *)addr, sizeof(sockaddr_in));
+    }
+    else if (addr->sa_family == AF_INET6) {
+      memcpy((void*)&addr_.ipv6, (const void *)addr, sizeof(sockaddr_in6));
+    }
+  }
+}
+
+void TClientInfoConnection::eraseAddr() {
+  addr_.ipv4.sin_family = AF_UNSPEC;
+}
+
+const char* TClientInfoConnection::getAddr(char* buf, int len) const {
+  switch (addr_.ipv4.sin_family) {
+  case AF_INET:
+    return inet_ntop(AF_INET, &addr_.ipv4.sin_addr, buf, len);
+  case AF_INET6:
+    return inet_ntop(AF_INET6, &addr_.ipv6.sin6_addr, buf, len);
+  default:
+    return NULL;
+  }
+}
+
+void TClientInfoConnection::recordCall(const char* name) {
+  strncpy(call_, name, kNameLen - 1);   // NUL terminator set in constructor
+  ncalls_++;
+}
+
+void TClientInfoConnection::eraseCall() {
+  call_[0] = '\0';
+}
+
+const char* TClientInfoConnection::getCall() const {
+  if (call_[0] == '\0') {
+      return NULL;
+  }
+  return call_;
+}
+
+void TClientInfoConnection::getTime(timespec* time) const {
+  *time = time_;
+}
+
+uint64_t TClientInfoConnection::getNCalls() const {
+  return ncalls_;
+}
+
+void TClientInfoConnection::initTime() {
+  clock_gettime(CLOCK_REALTIME, &time_);
+}
+
+
+TClientInfoConnection* TClientInfo::getConnection(int fd, bool grow) {
+  if (fd < 0 || (!grow && fd >= info_.size())) {
+    return NULL;
+  }
+  return &info_[fd];
+}
+
+size_t TClientInfo::size() const {
+    return info_.size();
+}
+
+void* TClientInfoServerHandler::createContext(boost::shared_ptr<TProtocol> input,
+                                              boost::shared_ptr<TProtocol> output) {
+  (void)input;
+  (void)output;
+  return (void*) new Connect(&clientInfo_);
+}
+
+void TClientInfoServerHandler::deleteContext(void* connectionContext,
+                                             boost::shared_ptr<TProtocol> input,
+                                             boost::shared_ptr<TProtocol> output) {
+  Connect* call = static_cast<Connect*>(connectionContext);
+  if (call->callInfo_) {
+    call->callInfo_->eraseCall();
+  }
+  delete call;
+}
+
+void TClientInfoServerHandler::processContext(void* connectionContext,
+                                              shared_ptr<TTransport> transport) {
+  Connect* call = static_cast<Connect*>(connectionContext);
+  if (call->callInfo_ == NULL) {
+    if (typeid(*(transport.get())) == typeid(TSocket)) {
+      TSocket* tsocket = static_cast<TSocket*>(transport.get());
+      int fd = tsocket->getSocketFD();
+      if (fd < 0) {
+        return;
+      }
+      call->callInfo_ = call->clientInfo_->getConnection(fd, true);
+      assert(call->callInfo_ != NULL);
+      socklen_t len;
+        call->callInfo_->recordAddr(tsocket->getCachedAddress(&len));
+    }
+  }
+}
+
+void TClientInfoServerHandler::getStatsStrings(vector<string>& result) {
+  result.clear();
+  timespec now;
+  clock_gettime(CLOCK_REALTIME, &now);
+
+  for (int i = 0; i < clientInfo_.size(); ++i) {
+    TClientInfoConnection* info = clientInfo_.getConnection(i, false);
+    const char* callStr = info->getCall();
+    if (callStr == NULL) {
+      continue;
+    }
+
+    char addrBuf[INET6_ADDRSTRLEN];
+    const char* addrStr = info->getAddr(addrBuf, sizeof addrBuf);
+    if (addrStr == NULL) {
+      // cerr << "no addr!" << endl;
+      continue;
+    }
+
+    timespec start;
+    double secs = 0.0;
+    info->getTime(&start);
+    secs = (double)(now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec)*0.000000001;
+
+    char buf[256];
+    snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs,
+             (unsigned long long)info->getNCalls());
+               
+    result.push_back(buf);
+  }
+}
+
+void* TClientInfoCallHandler::getContext(const char* fn_name, void* serverContext) {
+  if (serverContext) {
+    TClientInfoConnection* callInfo =  static_cast<TClientInfoServerHandler::Connect*>(serverContext)->callInfo_;
+    if (callInfo != NULL) {
+      callInfo->recordCall(fn_name);
+    }
+  }
+  return NULL;
+}
+
+} } } // namespace apache::thrift::server
